/* ============================================================
   SPACE WIZE ENTERPRISE — umbrella
   Night-band tokens inherited from the Space Wize web design site.
   The tree is the signature. Everything else stays quiet.
   ============================================================ */
:root{
  /* night band */
  --void:      #06070F;
  --deep:      #0C1026;
  --midnight:  #171B3A;
  --dusk:      #241844;

  /* accents */
  --cherry:    #E36FA0;
  --magenta:   #E8579F;
  --teal:      #4FD8CF;
  --sakura:    #FBD3E0;
  --lilac:     #CFC4E0;

  /* from the Space Wize Enterprise logo — sliced sun and RGB split */
  --coral:     #E8556A;
  --amber:     #F5A65B;
  --cyan:      #4FC3F7;

  /* ink */
  --ink:       #F4EEF6;
  --ink-soft:  #BDB2CC;
  --ink-faint: #8E85A3;
  --line:      rgba(244,238,246,.16);

  /* system */
  --shell:     1240px;
  /* the six-card grid needs more room than the reading column; the bar
     is not allowed to grow with it */
  --shell-wide:1420px;
  --r-lg:      22px;
  --r-md:      14px;
  --r-pill:    999px;
  --ease:      cubic-bezier(.16,1,.3,1);

  --display:   'Cormorant', Georgia, serif;
  --brand:     'Instrument Serif', Georgia, serif;
  --body:      'Inter', system-ui, -apple-system, sans-serif;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;
  background:var(--void);
  color:var(--ink);
  font-family:var(--body);
  font-size:16px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
img,svg,canvas{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
h1,h2,h3{margin:0;font-weight:400;line-height:1.05;letter-spacing:-.015em}

:focus-visible{
  outline:2.5px solid var(--teal);
  outline-offset:3px;
  border-radius:6px;
}

.skip{
  position:absolute;left:12px;top:-70px;z-index:200;
  background:var(--ink);color:var(--void);
  padding:12px 18px;border-radius:var(--r-pill);
  font-size:.85rem;font-weight:500;
  transition:top .2s var(--ease);
}
.skip:focus{top:12px}

.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;
}

/* ============================================================
   glass
   ============================================================ */
.glass{
  position:relative;
  background:rgba(255,255,255,.045);
  backdrop-filter:blur(14px) saturate(1.3);
  -webkit-backdrop-filter:blur(14px) saturate(1.3);
  border:1px solid var(--line);
  box-shadow:inset 0 1px 1px rgba(255,255,255,.14),
             0 18px 50px -26px rgba(0,0,0,.9);
}

/* ============================================================
   chrome — nav
   ============================================================ */
.topbar{
  position:fixed;inset:16px 16px auto 16px;z-index:40;
  display:flex;justify-content:center;
  pointer-events:none;
}
.topbar-inner{
  pointer-events:auto;
  width:100%;max-width:var(--shell);
  display:flex;align-items:center;justify-content:space-between;
  gap:20px;
  padding:10px 12px 10px 20px;
  border-radius:var(--r-md);
}
.wordmark{
  font-family:var(--brand);
  font-size:1.32rem;letter-spacing:.005em;
  white-space:nowrap;
  text-shadow:-1px 0 0 rgba(232,85,106,.42), 1px 0 0 rgba(79,195,247,.34);
}
.wordmark em{font-style:italic;color:var(--sakura)}

.topnav{display:flex;align-items:center;gap:6px}
.topnav a{
  padding:9px 15px;border-radius:var(--r-pill);
  font-size:.82rem;font-weight:500;
  color:var(--ink-soft);
  transition:color .2s var(--ease), background-color .2s var(--ease);
}
.topnav a:hover{color:var(--ink);background:rgba(255,255,255,.07)}
.topnav a[aria-current="page"]{color:var(--ink);background:rgba(255,255,255,.09)}

/* ============================================================
   home — locked stage
   ============================================================ */
/* Default is the scrollable static list: what you get with no JS and
   no WebGL. The scene upgrades the page to a locked viewport once it
   has actually started. */
.stage{
  position:relative;
  min-height:100vh;
  overflow:hidden;
  background:
    radial-gradient(120% 80% at 50% 22%, var(--dusk) 0%, transparent 62%),
    radial-gradient(95% 75% at 50% 104%, var(--dusk) 0%, transparent 72%),
    var(--void);
}
body[data-scene="on"]{overflow:hidden}
body[data-scene="on"] .stage{position:fixed;inset:0;min-height:0}
#scene{position:absolute;inset:0;width:100%;height:100%;z-index:1;touch-action:none;cursor:grab}
#scene[data-grabbing="true"]{cursor:grabbing}
#scene[data-over="true"]{cursor:pointer}

/* vignette keeps the type legible over the canvas */
body[data-scene="on"] .stage::after{
  content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  background:
    /* a local scrim under the headline, rather than dimming the whole
       scene to make one corner readable */
    radial-gradient(46% 42% at 6% 88%, rgba(6,7,15,.86) 0%, transparent 72%),
    radial-gradient(92% 78% at 50% 42%, transparent 48%, rgba(6,7,15,.30) 100%),
    linear-gradient(to bottom, rgba(6,7,15,.45) 0%, transparent 26%, transparent 70%, rgba(6,7,15,.5) 100%);
}

/* Stage furniture only exists once the canvas is running — but only
   `display` is gated on that. Putting layout properties behind the
   body attribute raises their specificity above the media queries,
   and the responsive rules silently stop applying. */
.stage-copy,.hint{display:none}
body[data-scene="on"] .stage-copy{display:flex}
body[data-scene="on"] .hint{display:flex}

.stage-copy{
  position:absolute;left:0;right:0;bottom:0;z-index:20;
  padding:0 clamp(18px,4vw,48px) clamp(22px,4vh,40px);
  align-items:flex-end;justify-content:space-between;
  gap:32px;
  pointer-events:none;
  /* the whole stage is drag-to-rotate, so a stray drag across the
     headline should not leave a highlight behind */
  -webkit-user-select:none;user-select:none;
  transition:opacity .3s var(--ease);
}
.stage-copy > *{pointer-events:auto}

.eyebrow{
  font-size:.68rem;font-weight:600;text-transform:uppercase;
  letter-spacing:.2em;color:var(--cherry);
  margin:0 0 14px;
}
.stage-copy h1{
  font-family:var(--display);
  font-size:clamp(2.1rem,4.6vw,3.6rem);
  font-weight:400;
  letter-spacing:-.02em;
  /* the logo's channel split, dialled down to where it reads as
     texture rather than as a broken screen */
  text-shadow:
    -1.4px 0 0 rgba(232,85,106,.5),
     1.4px 0 0 rgba(79,195,247,.4),
     0 0 40px rgba(227,111,160,.18);
  max-width:15ch;
}
.lede{
  margin:14px 0 0;
  color:var(--ink-soft);
  font-size:.95rem;
  max-width:46ch;
}

.stage-meta{
  text-align:right;
  font-size:.76rem;color:var(--ink-faint);
  line-height:1.7;white-space:nowrap;
}
.status{display:flex;align-items:center;justify-content:flex-end;gap:8px;margin:0}
.dot{
  width:7px;height:7px;border-radius:50%;
  background:var(--cherry);
  box-shadow:0 0 10px 2px rgba(227,111,160,.6);
  animation:pulse 1.6s var(--ease) infinite;
}
@keyframes pulse{
  0%,100%{opacity:1;transform:scale(1)}
  50%{opacity:.45;transform:scale(1.45)}
}

/* drag affordance */
.hint{
  -webkit-user-select:none;user-select:none;
  position:absolute;left:50%;bottom:clamp(30px,5vh,48px);
  transform:translateX(-50%);
  z-index:20;
  align-items:center;gap:9px;
  padding:9px 16px;border-radius:var(--r-pill);
  font-size:.76rem;color:var(--ink-soft);
  white-space:nowrap;
  transition:opacity .5s var(--ease);
}
.hint[data-hidden="true"]{opacity:0;pointer-events:none}
.hint .touch{display:none}
@media (hover:none){
  .hint .hover{display:none}
  .hint .touch{display:inline}
}

/* ============================================================
   blossom panel
   ============================================================ */
/* The card hangs off the open blossom on a cord, and swings when the
   tree is turned. Position and swing angle come from the scene. */
.tag{display:none}
body[data-scene="on"] .tag{display:flex}
/* A flat overlay pinned to the branch: the scene projects the anchor
   to screen space and writes transform/opacity, so neither is set
   here. transform-origin sits at the pin so the card swings from the
   cord rather than about its own middle. */
.tag{
  position:absolute;top:0;left:0;z-index:25;
  width:min(300px,82vw);
  flex-direction:column;align-items:center;
  transform-origin:50% 0;
  pointer-events:none;
  opacity:0;visibility:hidden;
  will-change:transform;
}

.tag-pin{
  width:9px;height:9px;border-radius:50%;
  border:1.5px solid var(--cyan);
  background:rgba(79,195,247,.2);
  box-shadow:0 0 10px 2px rgba(79,195,247,.5);
}
.tag-cord{
  width:1px;height:46px;
  background:linear-gradient(180deg, rgba(79,195,247,.15), var(--cyan));
  box-shadow:0 0 6px rgba(79,195,247,.55);
}

/* Out of the 3D layer, backdrop-filter works again — so the card gets
   its frosted glass back, over a fill dark enough to stay legible
   against the moon. */
.panel{
  /* the whole card forwards to the button's destination */
  cursor:pointer;
  position:relative;width:100%;
  padding:18px 20px;
  border-radius:var(--r-lg);
  pointer-events:auto;
  background:linear-gradient(158deg,
    rgba(36,24,68,.74) 0%,
    rgba(12,16,38,.8) 100%);
  backdrop-filter:blur(16px) saturate(1.3);
  -webkit-backdrop-filter:blur(16px) saturate(1.3);
  border:1px solid rgba(244,238,246,.2);
  box-shadow:inset 0 1px 1px rgba(255,255,255,.16),
             0 26px 60px -22px rgba(0,0,0,.95);
}
/* the punched hole the cord runs into */
.panel::after{
  content:"";position:absolute;top:9px;left:50%;
  width:16px;height:5px;margin-left:-8px;
  border-radius:999px;
  background:rgba(6,7,15,.75);
  box-shadow:inset 0 1px 1px rgba(0,0,0,.6), 0 0 0 1px rgba(79,195,247,.28);
}
.panel-status{
  display:inline-flex;align-items:center;gap:7px;
  font-size:.63rem;font-weight:600;text-transform:uppercase;
  letter-spacing:.16em;color:var(--ink-faint);
  margin-bottom:11px;
}
.panel-status .pip{
  width:6px;height:6px;border-radius:50%;
  background:var(--ink-faint);
}
.panel[data-live="true"] .panel-status{color:var(--cherry)}
.panel[data-live="true"] .pip{
  background:var(--cherry);
  box-shadow:0 0 8px 1px rgba(227,111,160,.7);
}
.panel h2{
  font-family:var(--display);
  font-size:1.5rem;font-weight:500;
  letter-spacing:-.02em;line-height:1.1;
}
.panel p{
  margin:11px 0 0;
  font-size:.88rem;color:#D3CADF;
  line-height:1.62;
}
.panel .btn{margin-top:17px}

.btn{
  display:inline-flex;align-items:center;gap:9px;
  min-height:44px;padding:11px 20px;
  border-radius:var(--r-pill);
  border:1px solid var(--line);
  background:transparent;color:var(--ink);
  font-family:var(--body);font-size:.83rem;font-weight:500;
  cursor:pointer;
  transition:background-color .22s var(--ease), border-color .22s var(--ease), color .22s var(--ease);
}
.btn:hover{background:rgba(255,255,255,.07)}
/* a second action next to a first one: same shape, less weight, and
   still over the 44px touch target once its own padding is counted */
.btn-sm{min-height:38px;padding:9px 16px;font-size:.76rem;color:var(--ink-soft)}
.btn-sm:hover{color:var(--ink)}
.panel-alt{margin-top:9px}
/* .btn sets display, and a class beats the browser's own
   [hidden]{display:none} — so hiding one needs saying explicitly */
.btn[hidden]{display:none}
.btn-live{border-color:rgba(227,111,160,.5)}
.btn-live:hover{background:var(--cherry);border-color:var(--cherry);color:var(--void)}
.btn[aria-disabled="true"]{opacity:.45;cursor:not-allowed}
.btn[aria-disabled="true"]:hover{background:transparent}
.btn .arrow{transition:transform .22s var(--ease)}
.btn:hover .arrow{transform:translateX(3px)}

/* ============================================================
   keyboard access to the branches
   ============================================================ */
.branch-keys{
  position:absolute;left:-9999px;top:0;z-index:50;
}
/* the :focus-within rule below would otherwise beat [hidden] */
.branch-keys[hidden]{display:none}
.branch-keys:focus-within{
  left:clamp(18px,4vw,48px);top:96px;
  display:flex;flex-direction:column;gap:6px;
  padding:14px;border-radius:var(--r-lg);
  background:rgba(12,16,38,.94);
  border:1px solid var(--line);
}
.branch-keys button,.branch-keys a{
  display:flex;align-items:center;
  min-height:44px;padding:9px 16px;
  border-radius:var(--r-pill);border:1px solid transparent;
  background:transparent;color:var(--ink-soft);
  font-family:var(--body);font-size:.83rem;text-align:left;
  cursor:pointer;
}
.branch-keys button:hover,.branch-keys a:hover{color:var(--ink);background:rgba(255,255,255,.07)}

/* ============================================================
   no-webgl fallback + /sites listing
   ============================================================ */
.fallback{
  position:relative;z-index:20;
  max-width:var(--shell-wide);margin:0 auto;
  padding:clamp(110px,16vh,150px) clamp(18px,4vw,48px) 70px;
}
.tree-list{
  list-style:none;margin:0 auto;padding:0;
  display:grid;gap:14px;
  /* Three across, centred, without hard-coding the count: the cap and
     the minimum are set so a fourth column cannot meet the minimum and
     a third comfortably can. Still falls to two and then one on its
     own as the window narrows — no breakpoints to keep in step.

     330/1160 rather than 268/1020 because at 372px per card the two
     longest lines wrap to three rather than four, which is what makes
     every card in the grid come out the same height. */
  max-width:1312px;
  grid-template-columns:repeat(auto-fit,minmax(330px,1fr));
}
.tree-list li{margin:0}
.branch-card{
  display:block;height:100%;
  padding:24px 26px;border-radius:var(--r-lg);
  transition:transform .3s var(--ease), border-color .3s var(--ease);
}
a.branch-card:hover{transform:translateY(-4px);border-color:rgba(227,111,160,.45)}
.branch-card h3{
  font-family:var(--display);font-size:clamp(1.55rem,1.9vw,1.7rem);font-weight:500;
  margin-bottom:11px;
}
.branch-card p{margin:0;color:var(--ink-soft);font-size:clamp(.9rem,1.1vw,1rem)}
.branch-card .tag{
  display:inline-flex;align-items:center;gap:7px;
  font-size:.70rem;font-weight:600;text-transform:uppercase;
  letter-spacing:.16em;color:var(--ink-faint);
  margin-bottom:14px;
}
.branch-card[data-live="true"] .tag{color:var(--cherry)}
.branch-card .pip{width:6px;height:6px;border-radius:50%;background:currentColor}

/* ============================================================
   inner pages
   ============================================================ */
.page{
  min-height:100vh;
  background:
    radial-gradient(100% 60% at 50% -10%, var(--dusk) 0%, transparent 60%),
    var(--void);
}
.shell{max-width:860px;margin:0 auto;padding:0 clamp(18px,4vw,48px)}
.wide{max-width:var(--shell-wide)}
.page-head{padding:clamp(120px,18vh,190px) 0 clamp(40px,7vh,68px)}
.page-head h1{
  font-family:var(--display);
  font-size:clamp(2.6rem,7vw,4.6rem);
  font-weight:400;letter-spacing:-.025em;
}
.page-head .lede{max-width:56ch}
.prose{padding-bottom:clamp(70px,12vh,120px)}
.prose p{margin:0 0 22px;color:var(--ink-soft);max-width:64ch}
.prose h2{
  font-family:var(--display);font-size:1.9rem;font-weight:500;
  margin:44px 0 16px;
}

.foot{
  border-top:1px solid var(--line);
  margin-top:clamp(50px,9vh,90px);
  padding:34px 0 46px;
  font-size:.78rem;color:var(--ink-faint);
  display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;
}
.foot a:hover{color:var(--ink)}
.foot-brand{display:flex;flex-direction:column;gap:4px}
.foot-copy{font-size:.72rem;color:var(--ink-faint);opacity:.75}

/* the tree view's only persistent chrome is .stage-meta, corner
   bottom-right — a credit anywhere else in that view is invisible,
   sitting behind the canvas */
.stage-copy-line{
  margin-top:10px;padding-top:10px;
  border-top:1px solid var(--line);
  font-size:.68rem;color:var(--ink-faint);opacity:.7;
}
/* the address sits with the location it belongs to, above the credit */
.stage-contact{margin-top:2px;font-size:.74rem}
.stage-contact a{color:var(--ink-faint)}
.stage-contact a:hover{color:var(--ink)}
.fallback-contact{margin-top:40px;font-size:.85rem;color:var(--ink-faint)}

/* the no-JS/no-WebGL fallback is real, scrolling document flow */
.fallback-copy{
  margin-top:44px;padding-top:22px;
  border-top:1px solid var(--line);
  font-size:.72rem;color:var(--ink-faint);opacity:.75;
}

/* ============================================================
   responsive
   ============================================================ */
@media (max-width:900px){
  .stage-copy{flex-direction:column;align-items:flex-start;gap:18px}
  .stage-meta{text-align:left}
  .status{justify-content:flex-start}
  /* the canopy fills the frame at this width, so the tag gets smaller
     and the headline steps aside while one is open */
  .tag-cord{height:34px}
  body[data-panel="open"] .stage-copy,
  body[data-panel="open"] .hint{opacity:0;pointer-events:none}
}
@media (max-width:620px){
  .topbar{inset:10px 10px auto 10px}
  .topbar-inner{padding:8px 8px 8px 16px}
  .wordmark{font-size:1.15rem}
  .topnav a{padding:9px 12px;font-size:.78rem}
  .stage-copy{padding-bottom:26px}
  .stage-copy h1{font-size:clamp(1.8rem,7.6vw,2.4rem)}
  .lede{font-size:.88rem}
  .hint{bottom:auto;top:76px;font-size:.72rem}
}

/* ============================================================
   reduced motion
   ============================================================ */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
}

/* ---- stage, timing and the second action ---- */
.panel-when{
  margin:9px 0 0;
  font-size:.76rem;
  color:var(--cherry);
  letter-spacing:.01em;
}
.card-when{
  margin:12px 0 0;
  font-size:.88rem;color:var(--cherry);
}
.card-acts{
  display:flex;flex-wrap:wrap;align-items:center;
  gap:8px 16px;margin-top:18px;
}
.card-notify{
  font-size:.9rem;font-weight:500;color:var(--ink);
  border-bottom:1px solid var(--cherry);
  padding-bottom:2px;
  transition:color .2s var(--ease)}
.card-notify:hover{color:var(--cherry)}
/* ============================================================
   arriving from the branch
   The circle that grew over the web-design site lands here still
   covering the page, holds for a beat, then shrinks away to nothing
   and uncovers the tree.

   This is an animation rather than a transition on purpose: a
   transition has to be triggered after the element is already
   painted, which on a page that is still loading is a race. An
   animation just runs.

   Sized in vmax so it is correct on the very first painted frame —
   measuring it in script would show a flash of the scene first.
   ============================================================ */
.page-arrive{ display:none }
/* hidden while script runs; restored if the scene never starts */
html[data-js="1"] #fallback{ display:none }

/* ============================================================
   the screens under the tree
   A stack: the tree is level 0, About is one viewport below it, Sites
   one below that. Everything is placed off its own depth against the
   current level, so each screen slides the same distance and the tree
   leaves the way it would if you really had scrolled past it. None of
   it is a scroll region — the stage above has no overflow to scroll —
   so the only routes down are the ones script opens deliberately.
   Hidden by visibility rather than display, so a closed screen stays
   out of the tab order but can still transition out.
   ============================================================ */
.under{
  --depth:1;
  position:fixed;inset:0;z-index:30;
  visibility:hidden;
  transform:translateY(calc((var(--depth) - var(--level, 0)) * 100%));
  /* the delay is what keeps a screen on show while it slides away */
  transition:transform 900ms var(--ease), visibility 0s linear 900ms;
  overflow-y:auto;
  /* a flick inside the panel must not turn into a page-level scroll */
  overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch;
  background:
    radial-gradient(120% 80% at 50% 0%, var(--dusk) 0%, transparent 62%),
    var(--void);
}
#underSites{ --depth:2 }

body[data-level="1"] #under,
body[data-level="2"] #underSites{
  visibility:visible;
  transition:transform 900ms var(--ease), visibility 0s linear 0s;
}

body[data-scene="on"] .stage{
  transition:transform 900ms var(--ease);
  transform:translateY(calc(var(--level, 0) * -100%));
}

.under-inner{
  max-width:860px;margin:0 auto;
  padding:clamp(96px,14vh,150px) clamp(18px,4vw,48px) clamp(60px,10vh,110px);
}
/* the six cards need the room the Sites page itself gives them */
.under[data-wide] .under-inner{ max-width:var(--shell-wide) }

/* the borrowed page's own h1, stepped down a rank on arrival */
.under-title{
  font-family:var(--display);
  font-size:clamp(2.4rem,6vw,3.4rem);font-weight:400;
  margin:0 0 30px;color:var(--ink);
}
.under-back{
  display:inline-flex;align-items:center;gap:9px;
  margin-top:10px;padding:11px 18px;
  border:1px solid var(--line);border-radius:999px;
  background:transparent;color:var(--ink-soft);
  font:inherit;font-size:.82rem;cursor:pointer;
  transition:background 200ms var(--ease), color 200ms var(--ease);
}
.under-back:hover{background:rgba(255,255,255,.07);color:var(--ink)}

@media (prefers-reduced-motion: reduce){
  .under, body[data-scene="on"] .stage{ transition:none }
  body[data-level="1"] #under,
  body[data-level="2"] #underSites{ transition:none }
}

/* ============================================================
   the loading veil
   Sits over the whole stage from the very first paint, gated by the
   same html[data-js] flag as the fallback above — a no-JS visitor
   never sees it, and the WebGL bail-out (which clears that flag)
   removes it the same way it restores the static list. Just under
   the arrive-cover's z-index: both are solid var(--void), so if they
   ever overlap there is no visible seam either way round.
   ============================================================ */
#loadVeil{
  display:none;
  position:fixed;inset:0;z-index:199;
  background:var(--void);
  opacity:1;
  transition:opacity 550ms var(--ease);
}
html[data-js="1"] #loadVeil{ display:block }
#loadVeil[data-go="true"]{ opacity:0;pointer-events:none }

/* Positioned in script as a percentage of the viewport, matched to
   the real moon's projected screen position rather than guessed —
   see scene.js. The image itself is a data URL taken straight off the
   same canvas the WebGL sprite's texture is drawn from — not a CSS
   approximation of it — so the handoff has no visible jump. */
#loadMoon{
  position:absolute;
  width:16vmax;height:16vmax;
  transform:translate(-50%,-50%);
  opacity:0;
  transition:opacity 400ms var(--ease);
  background-size:contain;
  background-repeat:no-repeat;
  background-position:center;
  filter:brightness(1.35) saturate(1.15);
}
#loadMoon[data-shown="true"]{ opacity:1 }

@media (prefers-reduced-motion: reduce){
  #loadVeil{ transition:none }
  #loadMoon{ transition:none }
}

html[data-arrive="1"] .page-arrive{
  display:block;
  position:fixed;z-index:200;
  left:50%;top:50%;
  width:300vmax;height:300vmax;
  margin-left:-150vmax;margin-top:-150vmax;
  border-radius:50%;
  background:var(--void);
  pointer-events:none;
  transform:scale(1);
}
html[data-arrive="1"] .page-arrive[data-go="true"]{
  animation:arriveShrink 1150ms cubic-bezier(.45,0,.25,1) forwards;
}
@keyframes arriveShrink{
  0%   { transform:scale(1);    opacity:1 }
  /* fades over the last stretch so it does not end as a hard dot
     sitting in the middle of the tree */
  72%  { transform:scale(.24);  opacity:1 }
  100% { transform:scale(0);    opacity:0 }
}
@media (prefers-reduced-motion: reduce){
  html[data-arrive="1"] .page-arrive{ animation:none;display:none }
}

/* ============================================================
   the notify form
   Ours, posting to the Google Form behind it — so the surface can
   match the rest of the site instead of dropping the visitor onto a
   white page in someone else's typeface.
   ============================================================ */
.notify-form,
.notify-done{
  margin-top:40px;
  padding:clamp(24px,4vw,38px);
  border-radius:var(--r-lg);
  max-width:520px;
}
.field{ margin-bottom:22px }
.field label{
  display:block;margin-bottom:8px;
  font-size:.76rem;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-soft);
}
.field .opt{
  margin-left:8px;
  font-weight:400;letter-spacing:.04em;text-transform:none;
  color:var(--ink-faint);
}
.field input,
.field select{
  width:100%;
  padding:13px 15px;
  border-radius:var(--r-md);
  border:1px solid var(--line);
  background:rgba(6,7,15,.4);
  color:var(--ink);
  font-family:var(--body);
  font-size:.95rem;
  transition:border-color .2s var(--ease), background-color .2s var(--ease);
}
.field input::placeholder{ color:var(--ink-faint) }
.field input:hover,
.field select:hover{ border-color:rgba(244,238,246,.3) }
.field input:focus-visible,
.field select:focus-visible{
  outline:none;
  border-color:var(--cherry);
  background:rgba(6,7,15,.62);
}
/* the native arrow is drawn in the OS's own colours, which reads as a
   piece of another site sitting inside this one */
.field select{
  appearance:none;-webkit-appearance:none;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' fill='none' stroke='%23BDB2CC' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 5l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right 15px center;
  padding-right:42px;
}
.field select option{ background:var(--deep);color:var(--ink) }

.notify-form .btn{ margin-top:4px }
.notify-form .btn[disabled]{ opacity:.55;pointer-events:none }
.notify-note{
  margin:18px 0 0;
  font-size:.76rem;color:var(--ink-faint);
  line-height:1.6;
}
.notify-done h2{
  font-family:var(--display);
  font-size:1.9rem;margin-bottom:10px;
}
.notify-done h2:focus-visible{ outline:none }
.notify-done p{ color:var(--ink-soft);margin:0 0 22px }

/* the yes/no opt-in — a pair of pills rather than the OS radio, which
   is drawn in the system's own colours and reads as foreign here */
.field.choice{ border:0;padding:0;margin:0 0 22px;min-width:0 }
.field.choice legend{
  padding:0;margin-bottom:10px;
  font-size:.76rem;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-soft);
}
.choice-row{ display:flex;gap:10px;flex-wrap:wrap }
.choice-opt{ position:relative;flex:1 1 0;min-width:110px }
.choice-opt input{
  position:absolute;opacity:0;width:100%;height:100%;
  margin:0;cursor:pointer;
}
.choice-opt span{
  display:block;text-align:center;
  padding:12px 16px;
  border-radius:var(--r-md);
  border:1px solid var(--line);
  background:rgba(6,7,15,.4);
  color:var(--ink-soft);
  font-size:.92rem;
  transition:border-color .2s var(--ease), background-color .2s var(--ease),
             color .2s var(--ease);
}
.choice-opt input:hover + span{ border-color:rgba(244,238,246,.3);color:var(--ink) }
.choice-opt input:checked + span{
  border-color:var(--cherry);
  background:rgba(227,111,160,.14);
  color:var(--ink);
}
/* the input is invisible, so the ring has to be drawn on the pill */
.choice-opt input:focus-visible + span{
  outline:2.5px solid var(--teal);
  outline-offset:3px;
}

/* ============================================================
   404
   ============================================================ */
.lost{
  min-height:100vh;
  display:flex;flex-direction:column;justify-content:center;
  padding-top:clamp(96px,14vh,150px);
}

}

/* ============================================================
   404
   The tree's stage without the tree: moon, falling blossom, and the
   copy sitting in the middle of the empty space where it would be.
   ============================================================ */
.stage.lost{ position:fixed;inset:0;min-height:0;overflow:hidden }
.stage.lost #scene{ z-index:1 }
/* same scrim logic as the tree, centred rather than tucked in a corner */
.stage.lost::after{
  content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  background:
    /* centred on the copy, not below it — the scrim has to sit where
       the text actually is to do anything for it */
    radial-gradient(56% 40% at 50% 70%, rgba(6,7,15,.86) 0%, rgba(6,7,15,.5) 54%, transparent 80%),
    linear-gradient(to bottom, rgba(6,7,15,.45) 0%, transparent 24%, transparent 68%, rgba(6,7,15,.55) 100%);
}
.lost-copy{
  /* below the moon, not behind it */
  position:absolute;left:0;right:0;top:58%;
  z-index:20;
  padding:0 clamp(18px,5vw,48px);
  text-align:center;
  -webkit-user-select:none;user-select:none;
}
.lost-copy .eyebrow{
  letter-spacing:.32em;
  margin-bottom:16px;
}
.lost-copy h1{
  font-family:var(--display);
  font-size:clamp(2.2rem,5.4vw,3.8rem);
  font-weight:400;letter-spacing:-.02em;
  text-shadow:
    -1.4px 0 0 rgba(232,85,106,.5),
     1.4px 0 0 rgba(79,195,247,.4),
     0 0 40px rgba(227,111,160,.18);
}
.lost-copy .lede{ margin:16px auto 0;max-width:44ch }
.lost-acts{
  margin-top:30px;
  display:flex;align-items:center;justify-content:center;
  gap:12px 22px;flex-wrap:wrap;
}
.lost-alt{
  font-size:.8rem;color:var(--ink-faint);
  border-bottom:1px solid rgba(244,238,246,.22);
  padding-bottom:2px;
  transition:color .2s var(--ease), border-color .2s var(--ease);
}
.lost-alt:hover{ color:var(--ink);border-color:var(--ink) }
