Drop turtle, honor ?template= URL param, add warp easter egg

- Removed the cosmos turtle (CSS rules + auto-load probe + JS hook).
  Reduced-motion turtle branch removed too.
- ?template=editorial|swiss|cosmos URL param now wins over the value
  in data/links.json (and the cached localStorage fallback). Wired in
  both the pre-paint boot script and main() so deep links work
  without flashing the wrong template.
- New hidden easter egg: type the letters w-a-r-p anywhere on the
  page (no input focused) and the page reloads on the next template
  in the cycle editorial -> swiss -> cosmos -> editorial. The URL is
  updated with the new ?template= param so the override survives
  refresh and is shareable. A small "↯ <name>" toast pops up after
  the reload via sessionStorage handoff, fades after ~2.5s, respects
  prefers-reduced-motion.
- README documents both the URL param and the warp keyword.
This commit is contained in:
Joel Brock
2026-05-16 09:35:45 -07:00
parent c16ee37096
commit ff0abee349
5 changed files with 102 additions and 63 deletions

View File

@@ -153,43 +153,6 @@
transition: transform 600ms cubic-bezier(0.22, 1, 0.36, 1);
}
/* galactic space turtle — floats in from the left, dips, then back out */
:root[data-template="cosmos"] .cosmos-turtle {
position: fixed;
top: clamp(48px, 9vh, 110px);
left: 0;
width: clamp(140px, 16vw, 240px);
height: auto;
z-index: 3;
pointer-events: none;
opacity: 0;
filter:
drop-shadow(0 0 22px rgba(122, 247, 255, 0.55))
drop-shadow(0 0 48px rgba(176, 122, 255, 0.45))
drop-shadow(0 0 80px rgba(255, 78, 205, 0.25));
animation:
cosmos-turtle-cycle 28s 2s linear infinite,
cosmos-turtle-bob 4s ease-in-out infinite;
will-change: transform, opacity;
}
@keyframes cosmos-turtle-cycle {
0% { transform: translate(-25vw, 0) rotate(-6deg); opacity: 0; }
6% { opacity: 1; }
45% { transform: translate(45vw, -4vh) rotate(4deg); opacity: 1; }
88% { transform: translate(112vw, 0) rotate(8deg); opacity: 1; }
93% { opacity: 0; }
100% { transform: translate(112vw, 0) rotate(8deg); opacity: 0; }
}
@keyframes cosmos-turtle-bob {
0%, 100% { filter:
drop-shadow(0 0 22px rgba(122, 247, 255, 0.55))
drop-shadow(0 0 48px rgba(176, 122, 255, 0.45))
drop-shadow(0 0 80px rgba(255, 78, 205, 0.25)); }
50% { filter:
drop-shadow(0 0 32px rgba(122, 247, 255, 0.75))
drop-shadow(0 0 64px rgba(176, 122, 255, 0.60))
drop-shadow(0 0 110px rgba(255, 78, 205, 0.40)); }
}
/* CSS-only static fallback nebula when WebGL is unavailable */
:root[data-template="cosmos"].cosmos-static body {
@@ -775,18 +738,13 @@
:root[data-template="cosmos"] .hero__asterism,
:root[data-template="cosmos"] .section__head::after,
:root[data-template="cosmos"] .card::before,
:root[data-template="cosmos"] .cosmos-comet,
:root[data-template="cosmos"] .cosmos-turtle {
:root[data-template="cosmos"] .cosmos-comet {
animation: none !important;
transition: none !important;
}
:root[data-template="cosmos"] .cosmos-bg,
:root[data-template="cosmos"] .cosmos-halo,
:root[data-template="cosmos"] .cosmos-comet { display: none; }
:root[data-template="cosmos"] .cosmos-turtle {
opacity: 1;
transform: translate(2vw, 0) rotate(-2deg);
}
:root[data-template="cosmos"] .hero__name,
:root[data-template="cosmos"] .hero__tagline,
:root[data-template="cosmos"] .hero__asterism { transform: none !important; }

View File

@@ -696,3 +696,33 @@ body::before {
}
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
/* warp toast — surfaces the active template after the easter egg fires */
.warp-toast {
position: fixed;
bottom: clamp(1.25rem, 3vw, 2.25rem);
left: 50%;
z-index: 1000;
display: inline-flex;
align-items: center;
gap: 0.6rem;
padding: 0.6rem 1.1rem;
background: var(--ink);
color: var(--paper);
font: 600 var(--fs-sm)/1 var(--mono);
text-transform: uppercase;
letter-spacing: 0.18em;
border-radius: 999px;
box-shadow: 0 12px 30px -16px rgba(0, 0, 0, 0.5);
opacity: 0;
transform: translate(-50%, 18px);
animation: warp-in 360ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
pointer-events: none;
}
.warp-toast__arrow { color: var(--accent); font-size: 1.1em; }
.warp-toast--out { animation: warp-out 600ms ease forwards; }
@keyframes warp-in { to { opacity: 1; transform: translate(-50%, 0); } }
@keyframes warp-out { to { opacity: 0; transform: translate(-50%, 18px); } }
@media (prefers-reduced-motion: reduce) {
.warp-toast { animation: none; opacity: 1; transform: translate(-50%, 0); }
}