/* Poster split, modernist tonal art, deep jewel palette (sapphire, cognac, oxblood, one brass accent). Ported from design/choose-refresh/final. */
@font-face{font-family:"Big Shoulders Display";src:url("/fonts/big-shoulders-display-800.woff2") format("woff2");font-weight:800;font-style:normal;font-display:optional} /* preloaded + optional: a late font never re-wraps the H1 and jumps the posters */
@font-face{font-family:"Atkinson Hyperlegible";src:url("/fonts/atkinson-hyperlegible-400.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Atkinson Hyperlegible";src:url("/fonts/atkinson-hyperlegible-700.woff2") format("woff2");font-weight:700;font-style:normal;font-display:swap}

:root{
  color-scheme:dark;
  --frame:#0F192C;          /* ink-navy rail: TABL navy, deepened */
  --cream:#F3E9D6;          /* warm cream type + art */
  --cream-soft:#CFC5B3;     /* intro copy, 10.3:1 on frame */
  --brass:#C8A461;          /* the one metallic accent: hairlines, arrow rings */
  --champagne:#DCC392;      /* brass at text weight: footer, focus, arrow fill; 10.3:1 on frame */
  --rule:#5E4E33;           /* header divider, brass in shadow */
  --display:"Big Shoulders Display","Barlow Condensed","Arial Narrow",sans-serif;
  --body:"Atkinson Hyperlegible","Avenir Next","Segoe UI",sans-serif;
  --ease:cubic-bezier(.22,1,.36,1);
  /* The stage (poster widening, discs, arrows) glides: it moves the moment the pointer arrives, never speeds up
     mid-way (a mid-move burst read as the disc snapping bigger), and eases to rest */
  --ease-stage:cubic-bezier(.33,1,.68,1);
  --stage-time:.6s; /* the widening and the discs share one curve and duration, so disc edges never wobble */
  --gutter:clamp(1rem,3vw,3rem);
}

*{box-sizing:border-box}
html{background:var(--frame)}
body{min-width:320px;min-height:100svh;margin:0;overflow-x:hidden;color:var(--cream);font-family:var(--body);background:var(--frame)}

.skip-link{position:fixed;z-index:20;top:.75rem;left:.75rem;padding:.75rem 1rem;border-radius:.5rem;color:var(--frame);background:var(--cream);font-weight:700;transform:translateY(-200%);transition:transform .2s ease}
.skip-link:focus{transform:none;outline:3px solid var(--champagne);outline-offset:2px}

.selector-shell{display:grid;grid-template-rows:auto minmax(15rem,1fr) auto;height:100svh;min-height:22rem} /* the floor makes very large default text scroll instead of collapsing the posters */

/* ---- Header band: logo, then the H1 and the pitch read as one line ---- */
.intro{
  display:grid;
  grid-template-columns:auto auto minmax(0,34rem);
  justify-content:start;
  align-items:center;
  gap:clamp(1rem,2.2vw,2.5rem);
  padding:max(1rem,env(safe-area-inset-top)) var(--gutter) 1rem;
  min-height:clamp(5.5rem,11svh,7.5rem);
}
/* The PNG's white plate multiplies onto cream, so the logo sits on a poster-cream label */
/* The logo keeps its classic white plate (not tinted to the cream type) */
.brand-plate{width:clamp(8rem,10.5vw,10.25rem);overflow:hidden;line-height:0;border-radius:.375rem;background:#fff}
.brand-plate img{display:block;width:100%;height:auto}
h1{margin:0;font:800 clamp(2.25rem,3.6vw,3.6rem)/.9 var(--display);letter-spacing:.005em;white-space:nowrap}
.intro__copy{margin:0;padding-left:clamp(1rem,1.8vw,2rem);border-left:2px solid var(--rule);color:var(--cream-soft);font-size:clamp(1rem,.72rem + .42vw,1.25rem);line-height:1.4;text-wrap:balance}

/* ---- Posters ---- */
/* Each poster's flex weight: 1 at rest, 1.28 hovered or focused, 0 once another is chosen. Stacked bands use them as
   flex-grow; side by side they only move the painted boundaries, never the layout (see "Side by side" below) */
@property --g1{syntax:"<number>";inherits:true;initial-value:1}
@property --g2{syntax:"<number>";inherits:true;initial-value:1}
@property --g3{syntax:"<number>";inherits:true;initial-value:1}
.choices{display:flex;min-height:0;transition:--g1 var(--stage-time) var(--ease-stage),--g2 var(--stage-time) var(--ease-stage),--g3 var(--stage-time) var(--ease-stage)}
.choices:has(>.choice--food:focus-visible){--g1:1.28}
.choices:has(>.choice--coffee:focus-visible){--g2:1.28}
.choices:has(>.choice--bowling:focus-visible){--g3:1.28}
.choice{
  --bg:#132451;             /* midnight sapphire; the three fields share one OKLCH ladder (field L .28-.30, disc +.07, ground -.07) */
  --flood:#1F3671;          /* exit bloom core = the poster's disc */
  --panel-speed:var(--champagne);
  --pad:clamp(1.25rem,2.5vw,3rem);
  --lit:#F2C877;
  --dim:#2C3656;            /* unlit festoon glass in the dark galley */
  --shade:#03081A;          /* the hover veil: each poster's own deepest tone, so dimming never greys the cream */
  position:relative;
  isolation:isolate;
  display:grid;
  flex:1 1 0;
  grid-template:auto minmax(0,1fr) / minmax(0,1fr);
  min-width:0;
  overflow:hidden;
  color:var(--cream);
  text-decoration:none;
  background:var(--bg);
  -webkit-tap-highlight-color:transparent;
}
.choice--coffee{--bg:#3E2614;--flood:#5C3A1F;--shade:#0E0704} /* cognac, hue ~57: 47° clear of the oxblood */
.choice--bowling{--bg:#521323;--flood:#6C2233;--lit:rgb(200 164 97 / .45);--dim:#4E1220;--shade:#160307} /* lane arrows light as brass inlays, not a marquee */
/* A 7% hairline keeps the dark sheets apart */
.choice+.choice{box-shadow:inset 1px 0 0 rgb(255 255 255 / .07)}

/* ---- Food truck tones: every fill in the van is a class bound to one of these. Neutral rubber and steel, brass stripe,
   TABL blue only on the door's logo tile ---- */
.choice--food{
  --panel-disc:#1F3671; --panel-disc-glow:#2B4688; /* the disc brightens toward the horizon (#ft-sky) */
  --panel-ground:#0A1532; --panel-horizon:var(--brass); --panel-lane:#16244A; --panel-contact:#050A1A;
  --truck-lit:#FAF4E8;          /* top edges catching the light */
  --truck-body:#EFE5D2;         /* body skin */
  --truck-shade:#E0D4BE;        /* planes turning away: roof gear, drip rail, lower flank, nose corner */
  --truck-shade-2:#D2C4AB;      /* seams, window reveal */
  --truck-shade-3:#B5A68C;      /* handles */
  --truck-livery:#112D6C;       /* lower band */
  --truck-livery-shade:#0B2152;
  --truck-livery-lit:#1A3A80;   /* wheel-arch lips, rub rail */
  --truck-stripe:var(--brass);
  --truck-trim-lit:#E6E8EB; --truck-trim:#C9CDD3; --truck-trim-shade:#A3A8B1; --truck-trim-deep:#7C828C; /* stainless + steel */
  --truck-glass:#0D1428; --truck-glass-lit:#2B3A5E;
  --truck-window:#121C38; --truck-window-deep:#060A17; --truck-pane:#24365E; --truck-pane-lit:#56699A;
  --truck-glow:#F6D08A; --truck-glow-2:#D99A45;
  --truck-awning:#A9AEB6; --truck-awning-shade:#7F858E; /* stainless hatch: the underside is in shade, its free edge catches the light */
  --truck-ink:#0D1428;          /* struts, mirror, tablet */
  --truck-tire:#15171C; --truck-tire-wall:#22252B; --truck-well:#07080B; --truck-chassis:#0B0D12;
  --truck-lamp:#FFF6E2; --truck-amber:#E9A23B; --truck-tail:#C0303F;
  --truck-screen:#D3DAE4; --truck-screen-lit:#EEF1F5; --truck-mark:#0A6BFE;
}
.p-ground{fill:var(--panel-ground)}.p-horizon{fill:var(--panel-horizon)}.p-lane{stroke:var(--panel-lane)}.p-contact{fill:var(--panel-contact)}.p-speed{fill:var(--panel-speed);fill-opacity:.5}
.t-lit{fill:var(--truck-lit)}.t-body{fill:var(--truck-body)}.t-shade{fill:var(--truck-shade)}.t-shade-2{fill:var(--truck-shade-2)}.t-shade-3{fill:var(--truck-shade-3)}
.t-livery{fill:var(--truck-livery)}.t-livery-shade{fill:var(--truck-livery-shade)}.t-livery-lit{fill:var(--truck-livery-lit)}.t-stripe{fill:var(--truck-stripe)}
.t-trim-lit{fill:var(--truck-trim-lit)}.t-trim{fill:var(--truck-trim)}.t-trim-shade{fill:var(--truck-trim-shade)}.t-trim-deep{fill:var(--truck-trim-deep)}
.t-glass{fill:var(--truck-glass)}.t-glass-lit{fill:var(--truck-glass-lit)}.t-window{fill:var(--truck-window)}.t-window-deep{fill:var(--truck-window-deep)}
.t-pane{fill:var(--truck-pane)}.t-pane-lit{fill:var(--truck-pane-lit)}.t-wire{stroke:var(--truck-pane-lit)}.t-glow{stop-color:var(--truck-glow)}.t-glow-2{stop-color:var(--truck-glow-2)}
.t-awning{fill:var(--truck-awning)}.t-awning-shade{fill:var(--truck-awning-shade)}.t-ink{fill:var(--truck-ink)}
.t-tire{fill:var(--truck-tire)}.t-tire-wall{fill:var(--truck-tire-wall)}.t-well{fill:var(--truck-well)}.t-chassis{fill:var(--truck-chassis)}
.t-lamp{fill:var(--truck-lamp)}.t-amber{fill:var(--truck-amber)}.t-tail{fill:var(--truck-tail)}.t-screen{fill:var(--truck-screen)}.t-screen-lit{fill:var(--truck-screen-lit)}.t-mark{fill:var(--truck-mark)}
.choice__body{display:contents}

/* Poster title, top-left */
.choice__label{
  grid-area:1/1;
  z-index:1;
  width:min-content;
  padding:clamp(1.25rem,4.5svh,3rem) var(--pad) 0;
  font:800 clamp(3.25rem,7.3vw,8.5rem)/.84 var(--display);
  letter-spacing:.01em;
  text-transform:uppercase;
}

/* The viewBox is cropped to the art (the disc overflows above), so short screens fit by height and wide ones
   grow until the subject (x 60-340 of 400) spans ~87% of the poster. Width comes from the resting column (100vw/3),
   so a hover's widening reveals more poster without rescaling the art or bobbing its ground line.
   Bottom-aligned: the ground under the road line is the same depth at every height (the arrow sits in it), and
   on tall screens the sun disc grows into the spare sky (see the aspect rules below), so no band goes dead. */
.choice__icon{
  grid-area:2/1;
  align-self:end;
  display:block;
  width:calc(124vw / 3);
  height:auto;
  max-height:100%;
  margin-inline:calc((100% - 124vw / 3) / 2);
  padding:1.5rem 0 clamp(4.25rem,10svh,6.5rem);
  overflow:visible;
  animation:rise .7s var(--ease) backwards; /* lets go once played: a held fill would own opacity and make the exit fade snap */
}
.choice--coffee .choice__icon{animation-delay:.07s}
.choice--bowling .choice__icon{animation-delay:.14s}

/* Two arrows drawn with text-shadow: the second waits left of the disc and slides in as the first leaves */
.choice__arrow{
  grid-area:2/1;
  z-index:1;
  align-self:end;
  justify-self:end;
  display:grid;
  --aw:clamp(3rem,3.8vw,3.75rem);
  width:var(--aw);
  aspect-ratio:1;
  margin:0 var(--pad) clamp(.9rem,2.6svh,1.75rem);
  place-items:center;
  overflow:hidden;
  border:2px solid var(--brass);
  border-radius:50%;
  color:transparent;
  text-shadow:0 0 var(--cream),-2em 0 var(--cream);
  font:700 clamp(1.3rem,1.7vw,1.7rem)/1 var(--body);
  transition:background-color .2s ease,text-shadow .45s var(--ease),scale 90ms ease-out;
}

/* Tall desktop screens (4:3, 5:4, 1440x1100): the subject is capped by the poster's width, so the sky grows instead.
   The disc is centered on the poster (cx 200); scale ~1.1 would exactly meet the poster edges, so it either clears
   them (3:2) or is cut clearly by them (4:3). The base size is a variable folded into the disc's one transform: as a
   separate `scale` property, Chrome dropped it while the hover transform animated and re-applied it at the end, so on
   these screens every disc snapped 4% bigger as its animation finished */

/* Art motion hooks */
.art-move,.art-steam,.art-speed,.art-wheel,.art-disc,.art-ball{transform-box:fill-box;transform-origin:center;transition:transform .5s var(--ease),opacity .3s ease}
.art-disc{
  --disc-base:1; --disc-hover:1; /* base: screen shape (centre-anchored); hover: grow / shrink, seated on its base */
  transform:translateY(calc(146px * var(--disc-base) * (1 - var(--disc-hover)))) scale(calc(var(--disc-base) * var(--disc-hover)));
  transition:transform var(--stage-time) var(--ease-stage); /* in step with the widening it rides on */
}
@media (min-width:721px) and (max-aspect-ratio:3/2){.art-disc{--disc-base:1.04}}
@media (min-width:721px) and (max-aspect-ratio:4/3){.art-disc{--disc-base:1.3}}
/* Each art hook animates only `transform`. Chrome drops a separate translate/rotate/scale property on SVG art while its
   transform transitions, then applies it when the transition ends, so the art snaps a beat after it settles */
.art-tip{transform-box:view-box;transform-origin:199.5px 263px;transition:transform .5s var(--ease)} /* the front pin's right base corner */
/* The crema's slosh is two opposite rotations on two nested groups: the outer turns fast, the inner cancels it slowly, so
   the sum swells and returns to zero. Both ease home together on leave, so a half-played slosh fades out, never snaps. */
.art-crema,.art-crema-settle{transform-box:fill-box;transform-origin:center;transition:transform .5s var(--ease)}
/* The cup's shadow on the saucer well: it spreads as the cup rises, and on leave fades faster than the cup lands */
.art-lift{opacity:0;transform:scale(.8);transform-box:fill-box;transform-origin:center;transition:opacity .25s var(--ease),transform .5s var(--ease)}
.art-speed{opacity:0}
/* Steam: each wisp sways and curls from its base while the coffee poster is hovered, focused or chosen. It pauses
   (never resets) when the pointer leaves, so it can't snap back; the three periods drift so the wisps never sync. */
/* Truck speed lines streak back from its rear bumper while it rolls: grow in, stretch left, fade out; staggered so they never
   pulse together. Paused (never reset) when the pointer leaves, and the whole group fades with .art-speed. */
/* Driving: the lane scrolls back at 120 units/s (one 54-unit dash period per .45s) and the wheels spin to match it
   (tyre r22 x .775 x .909 = 15.5 units, 97.4 units round: one turn per .81s, so the tyres roll without skidding).
   The spin runs on an inner group, under the one-shot 200deg roll-in turn. The body rides its suspension; all pause, never reset. */
.art-road{transition:stroke .4s ease;animation:road-scroll .45s linear infinite paused}
.art-spin{transform-box:fill-box;transform-origin:center}
.choice--food .art-spin{animation:wheel-spin .81s linear infinite paused}
.art-body{transform-box:fill-box;transform-origin:50% 100%;animation:body-ride 1.1s ease-in-out infinite paused}
.choice--food:focus-visible :is(.art-road,.art-spin,.art-body),body.is-leaving .choice--food.is-selected :is(.art-road,.art-spin,.art-body){animation-play-state:running}
@keyframes road-scroll{to{stroke-dashoffset:54}}
@keyframes wheel-spin{to{transform:rotate(360deg)}}
@keyframes body-ride{0%,100%{transform:none}30%{transform:translateY(-1.1px) rotate(-.18deg)}65%{transform:translateY(.4px) rotate(.08deg)}}
.art-streaks>path{transform-box:fill-box;transform-origin:100% 50%;animation:speed-streak 1.1s ease-out infinite paused}
.art-streaks>path:nth-child(2){animation-duration:.95s;animation-delay:-.35s}
.art-streaks>path:nth-child(3){animation-duration:1.25s;animation-delay:-.7s}
.choice--food:focus-visible .art-streaks>path,body.is-leaving .choice--food.is-selected .art-streaks>path{animation-play-state:running}
@keyframes speed-streak{0%{opacity:0;transform:scaleX(.55)}30%{opacity:1;transform:none}100%{opacity:0;transform:translateX(-4px) scaleX(1.35)}}
.art-steam>path{transform-box:fill-box;transform-origin:50% 100%;animation:steam-curl 2.8s ease-in-out infinite paused}
.art-steam>path+path{animation-duration:3.6s}
.art-steam>path:nth-child(3){animation-duration:3.1s}
.choice--coffee:focus-visible .art-steam>path,body.is-leaving .choice--coffee.is-selected .art-steam>path{animation-play-state:running}
@keyframes steam-curl{
  0%,100%{transform:none;opacity:1}
  30%{transform:translate(-2px,-9px) skewX(-14deg) scaleY(1.14);opacity:.72}
  65%{transform:translate(2.5px,-15px) skewX(12deg) scaleY(1.2);opacity:.45} /* a livelier sway than final/, same height, so the wisps stay clear of the title */
}
.art-glow{transition:opacity .4s ease}
/* Press feedback for touch (iOS needs a touch listener, set in script.js). Individual scale, never transform, and never on .choice:
   the exit flood is a fixed ::before, so .choice and its ancestors must stay transform-free */
@property --press{syntax:"<number>";inherits:false;initial-value:1}
.choice__icon,.choice__label{transition:scale 90ms ease-out}
.choice:active :is(.choice__icon,.choice__label,.choice__arrow){scale:.98}
/* Lights: lit by default (touch never hovers); pointer devices switch them on in a 35ms chase */
.art-lights{fill:var(--lit)}
.art-lights>*{transition:fill .18s ease calc(var(--i,0) * 35ms)}

/* Each poster's veil (hover dim + exit dim), above the title and arrow so the whole poster goes down together */
.choice::before{position:absolute;z-index:2;inset:0;background:var(--shade);opacity:0;content:"";pointer-events:none;transition:opacity .35s ease}

/* Keyboard focus: the poster steps forward with a cream ring set inside it */
.choice:focus-visible{outline:3px solid var(--champagne);outline-offset:-14px}
/* The art paints on its own layer, so the ring is repeated above it */
.choice:focus-visible::after{position:absolute;z-index:3;inset:11px;border:3px solid var(--champagne);content:"";pointer-events:none}
.choice:is(:focus-visible,:active) .choice__arrow{border-color:var(--champagne);background:var(--champagne);text-shadow:2em 0 var(--bg),0 0 var(--bg)}

/* Pointer hover (real pointers only, so a tap never leaves a stuck state) + focus animate the art */
@media (hover:hover){
  .choices:has(>.choice--food:hover){--g1:1.28}
  .choices:has(>.choice--coffee:hover){--g2:1.28}
  .choices:has(>.choice--bowling:hover){--g3:1.28}
  .choice:hover .choice__arrow{border-color:var(--champagne);background:var(--champagne);text-shadow:2em 0 var(--bg),0 0 var(--bg)}
  .art-lights{fill:var(--dim)}
  .choice:is(:hover,:focus-visible) .art-lights{fill:var(--lit)}
  .art-glow{opacity:.3} /* the galley is open at rest; hover turns the lights up */
  .choice:is(:hover,:focus-visible) .art-glow{opacity:1}
  /* House lights down: the other posters dim evenly (art, title, arrow) under their own deepest tone */
  body:not(.is-leaving) .choices:has(>.choice:is(:hover,:focus-visible))>.choice:not(:hover,:focus-visible)::before{opacity:.14}
  /* The disc is a sun seated on the horizon: hovered it rises bigger, the narrowed neighbours sink smaller, and the lift
     in its transform (146 x base x (1 - hover) units) keeps every base on the horizon, so none bob against the ground */
  .choice:is(:hover,:focus-visible) .art-disc{--disc-hover:1.06}
  body:not(.is-leaving) .choices:has(>.choice:is(:hover,:focus-visible))>.choice:not(:hover,:focus-visible) .art-disc{--disc-hover:.9}
  .choice:is(:hover,:focus-visible) .art-speed{opacity:1}
  .choice--food:is(:hover,:focus-visible) .art-move{transform:translateX(14px)}
  .choice--food:is(:hover,:focus-visible) .art-wheel{transform:rotate(200deg)}
  .choice--coffee:is(:hover,:focus-visible) .art-steam{transform:translateY(-16px);transition:transform .8s cubic-bezier(.3,.7,.2,1)} /* carried up with the cup, on its curve; -16 keeps the wisps' reach where final/ had it, clear of the title */
  .choice--coffee:hover .art-steam>path{animation-play-state:running}
  .choice--food:hover .art-streaks>path{animation-play-state:running}
  .choice--food:hover :is(.art-road,.art-spin,.art-body){animation-play-state:running}
  .choice--food:is(:hover,:focus-visible) .art-road{stroke:#2C3F72} /* the lane lifts so the moving road reads, still quiet */
  /* Coffee: the cup comes up off the saucer as if raised by its handle, leaving its shadow on the well; the liquid lags the tilt,
     swings back a hair and settles (clipped to the meniscus, #cf-well, so it never climbs the wall) */
  .choice--coffee:is(:hover,:focus-visible) .art-move{transform:translateY(-11px) rotate(-1.5deg);transition:transform .8s cubic-bezier(.3,.7,.2,1)}
  .choice--coffee:is(:hover,:focus-visible) .art-lift{opacity:1;transform:none;transition:opacity .5s ease .06s,transform .8s cubic-bezier(.3,.7,.2,1)}
  .choice--coffee:is(:hover,:focus-visible) .art-crema{transform:rotate(2deg);transition:transform .35s cubic-bezier(.25,.8,.4,1)}
  .choice--coffee:is(:hover,:focus-visible) .art-crema-settle{transform:rotate(-2deg);transition:transform .9s cubic-bezier(.45,0,.35,1.3) .12s}
  /* Bowling: the ball rolls into the head pin, which slides a unit, tips past its rest angle and settles against the ball, clear
     of the second pin. Held while hovered. The ball turns 5° per unit rolled; the trailing speed lines keep their distance */
  .choice--bowling:is(:hover,:focus-visible) .art-move{transform:translateX(21px);transition:transform .65s var(--ease)}
  .choice--bowling:is(:hover,:focus-visible) .art-ball{transform:rotate(105deg);transition:transform .65s var(--ease)}
  .choice--bowling:is(:hover,:focus-visible) .art-tip{transform:translate(1px,0) rotate(13.2deg);transition:transform .8s cubic-bezier(.34,1.4,.5,1) .07s}
  .choice--bowling:is(:hover,:focus-visible) .art-speed{transform:translateX(4px)}
}

/* Selection (script adds .is-leaving + .is-selected, navigates at 240ms):
   the chosen color covers the whole screen by 200ms, so the handoff is never partial.
   The flood is a fixed ::before, so .choice and its ancestors must never get a transform or filter. */
body.is-leaving .choices{transition-duration:.2s;transition-timing-function:cubic-bezier(.6,0,.4,1)}
body.is-leaving .choices:not(:has(>.choice--food.is-selected)){--g1:0}
body.is-leaving .choices:not(:has(>.choice--coffee.is-selected)){--g2:0}
body.is-leaving .choices:not(:has(>.choice--bowling.is-selected)){--g3:0}
body.is-leaving .choice:not(.is-selected) :is(.choice__icon,.choice__label,.choice__arrow){opacity:0;transition:opacity .12s ease}
/* The unchosen posters go black (not their own shade) under the flood as it fades in, so two hues never mix into a third
   (sapphire + oxblood = purple), and the veil covers their fading titles, so no ghosts */
body.is-leaving .choice:not(.is-selected)::before{background:#000;opacity:1;transition:opacity .12s ease}
body.is-leaving .choice.is-selected{z-index:5}
/* A bloom: the poster's disc light spreads from behind the subject, falling off to the field */
body.is-leaving .choice.is-selected::before{position:fixed;z-index:-1;inset:0;clip-path:none;background:radial-gradient(130% 90% at 50% 70%,var(--flood),var(--bg) 72%);opacity:1;content:"";transition:none;animation:flood .2s ease-out both}
/* Side-by-side exit poses (stacked bands play the finales below instead). Scoped away from stacked bands: a finale's
   keyframes start from the pose under them, so a static exit pose there made every finale jump on its first frame */
@media (min-width:721px) and (orientation:landscape),(min-width:1101px){
  body.is-leaving .choice--food.is-selected .art-move{transform:translateX(60px)} /* the van drives off */
  body.is-leaving .choice--coffee.is-selected .art-move{transform:translateY(-11px) rotate(-1.5deg)} /* the cup lifts with its steam */
  body.is-leaving .choice--coffee.is-selected .art-steam{transform:translateY(-16px)}
  body.is-leaving .choice--bowling.is-selected .art-move{transform:translateX(21px)} /* the ball strikes the head pin */
  body.is-leaving .choice--bowling.is-selected .art-ball{transform:rotate(105deg)} /* touch has no hover, so the ball spins here too */
  body.is-leaving .choice--bowling.is-selected .art-tip{transform:translate(1px,0) rotate(13.2deg);transition-delay:.07s} /* the pin waits for the ball, as on hover */
}

footer{padding:.7rem var(--gutter) max(.7rem,env(safe-area-inset-bottom));color:var(--champagne);font-size:.75rem;letter-spacing:.12em;text-align:center}

@keyframes rise{from{opacity:0;transform:translateY(14px)}}
@keyframes flood{from{opacity:0}}
/* Phone exit (stacked bands, below). Each art hook still animates only `transform` (plus opacity) */
@keyframes sun-burst{to{clip-path:circle(var(--sun-end) at var(--sun-x) var(--sun-y))}}
@keyframes fade-out{to{opacity:0}}
@keyframes drive{to{transform:translateX(var(--go))}}
@keyframes roll{to{transform:rotate(var(--turn))}}
@keyframes trail{0%{opacity:0}20%{opacity:1}to{opacity:1;transform:translateX(var(--go)) scaleX(4)}}
@keyframes cup-lift{to{transform:translateY(-58px) rotate(-5deg)}}
/* The wisps rise with the cup, hold a beat, then billow up out of the band, spreading as they thin away */
@keyframes steam-billow{32%{transform:translateY(-26px) scale(1.12,1.1);opacity:1;animation-timing-function:cubic-bezier(.2,.5,.4,1)}70%{opacity:.75}to{transform:translateY(-110px) scale(2,2.4);opacity:0}}
/* The van squats on its rear axle as it launches: the nose lifts, then eases back as it gathers speed */
@keyframes launch{35%{transform:rotate(-1.6deg)}to{transform:rotate(-.6deg)}}
/* The strike, keyed in ms of the .42s run (10ms = 2.38%), as a chain of contacts measured in both engines: the ball, let go
   at speed, meets the head pin at 18ms and carries it; the head pin, thrown steeply up and tumbling, clips the second at
   36ms, which is knocked into a flatter arc and tips the third low along the lane at 52ms. No pin moves before something
   touches it, and each leaves at a lower angle than the one before, so they fan apart. Each spins about its centre of mass */
@keyframes pin-1{0%,4.29%{transform:none}7.14%{transform:translate(12px,-6px) rotate(10deg)}10.71%{transform:translate(28px,-20px) rotate(24deg)}14.29%{transform:translate(42px,-40px) rotate(42deg)}19.05%{transform:translate(56px,-66px) rotate(66deg)}23.81%{transform:translate(66px,-92px) rotate(92deg)}28.57%{transform:translate(74px,-114px) rotate(118deg)}33.33%{transform:translate(80px,-132px) rotate(144deg)}42.86%{transform:translate(90px,-166px) rotate(196deg)}57.14%{transform:translate(102px,-204px) rotate(270deg)}71.43%{transform:translate(112px,-230px) rotate(330deg)}to{transform:translate(126px,-262px) rotate(430deg)}}
@keyframes pin-2{0%,8.57%{transform:none}12.14%{transform:translate(18px,-8px) rotate(10deg)}16.90%{transform:translate(42px,-24px) rotate(26deg)}22.62%{transform:translate(68px,-42px) rotate(46deg)}27.38%{transform:translate(88px,-56px) rotate(62deg)}33.33%{transform:translate(112px,-74px) rotate(82deg)}42.86%{transform:translate(144px,-96px) rotate(110deg)}57.14%{transform:translate(182px,-120px) rotate(150deg)}71.43%{transform:translate(212px,-136px) rotate(185deg)}to{transform:translate(256px,-152px) rotate(240deg)}}
@keyframes pin-3{0%,12.38%{transform:none}15.71%{transform:translate(16px,-3px) rotate(12deg)}20.48%{transform:translate(42px,-9px) rotate(32deg)}25.24%{transform:translate(66px,-15px) rotate(52deg)}32.38%{transform:translate(100px,-22px) rotate(80deg)}41.90%{transform:translate(140px,-28px) rotate(110deg)}56.19%{transform:translate(190px,-33px) rotate(145deg)}70.48%{transform:translate(234px,-35px) rotate(175deg)}to{transform:translate(310px,-36px) rotate(220deg)}}

/* ---- Phones + portrait tablets: three stacked bands (query pinned by tests) ---- */
@media (max-width:720px),(min-width:721px) and (max-width:1100px) and (orientation:portrait){
  /* Tap exit on phones and portrait tablets (script.js navigates at 480ms). The tapped band's sun bursts out of its band
     and floods the screen: a circle from the disc (--sun-*, measured by script.js) to the farthest corner, lit with the
     disc's colour falling off to the field. The page parts for it: bands above slide up and bands below slide down, each
     side as one block, over the page tinted to the chosen field (no navy gaps), the header lifts away a beat later, the
     title sweeps up. The subject plays one finale and fades by 400ms, so the handoff is a clean screen of the band's
     light. Layout holds still (the burst is measured from the disc), and only inner parts and the other bands move: the
     chosen .choice never takes a transform, or its fixed flood would be trapped in it. */
  body.is-leaving{background-color:var(--sun-bg);transition:background-color .2s ease}
  body.is-leaving .choices{background:var(--sun-bg)} /* the gaps open straight onto the chosen field, never a navy blend */
  body.is-leaving .choice{flex-grow:1}
  body.is-leaving .choice.is-selected{outline-color:transparent} /* a keyboard ring would stay drawn over the flood */
  body.is-leaving .choice.is-selected::after{content:none}
  body.is-leaving .choice.is-selected::before{
    background:radial-gradient(circle at var(--sun-x) var(--sun-y),var(--flood) var(--sun-r),var(--bg) calc(var(--sun-r) * 3));
    clip-path:circle(var(--sun-r0) at var(--sun-x) var(--sun-y));
    animation:sun-burst .44s cubic-bezier(.7,0,.2,1) forwards;
  }
  body.is-leaving .choice:not(.is-selected)::before{background:transparent}
  body.is-leaving .choice:not(.is-selected) :is(.choice__icon,.choice__label,.choice__arrow){opacity:1} /* they leave whole */
  body.is-leaving .choice:has(~.is-selected){translate:0 -100vh}
  body.is-leaving .is-selected~.choice{translate:0 100vh}
  body.is-leaving :is(.choice:has(~.is-selected),.is-selected~.choice){transition:translate .42s cubic-bezier(.4,0,.7,.5)}
  body.is-leaving .intro{translate:0 -1.5rem;opacity:0;transition:translate .3s cubic-bezier(.55,0,.8,.3) .04s,opacity .22s ease .04s}
  body.is-leaving .choice.is-selected .choice__label{translate:0 -.35em;opacity:0;transition:translate .26s cubic-bezier(.3,0,.2,1),opacity .16s linear}
  body.is-leaving .choice.is-selected .choice__arrow{translate:1.25rem 0;opacity:0;transition:translate .26s cubic-bezier(.3,0,.2,1),opacity .16s linear}
  /* The chosen art may leave its band upward from the first frame (still cut at its floor), so the finales play out over the
     parting page. Only the sun stays cut at the band's top edge (--cut, set by script.js in the disc's own units): its hidden
     top is left for the burst to cover, so it never pops, and no finale has to wait for the burst to clear it */
  body.is-leaving .choice.is-selected{overflow:visible}
  body.is-leaving .choice.is-selected .choice__icon{clip-path:inset(-100vh -100vw 0);animation:fade-out .12s linear .28s forwards}
  body.is-leaving .choice.is-selected .art-disc{clip-path:inset(var(--cut) 0 0)}
  /* Finales. Food: the van floors it off the right edge from a standstill (t², 440 units: its tail clears the edge by ~310ms),
     squatting on its rear axle, its wheels rolling the distance (r15.5 tyres), the speed lines stretching out behind it */
  body.is-leaving .choice--food.is-selected{--go:440px;--turn:1627deg}
  body.is-leaving .choice--food.is-selected :is(.art-move,.art-wheel,.art-speed){animation:drive .36s cubic-bezier(.333,0,.667,.333) forwards}
  body.is-leaving .choice--food.is-selected .art-wheel{animation-name:roll}
  body.is-leaving .choice--food.is-selected .art-speed{transform-origin:100% 50%;animation-name:trail}
  body.is-leaving .choice--food.is-selected .art-body{transform-origin:20% 100%;animation:launch .36s cubic-bezier(.3,0,.3,1) forwards}
  /* Coffee: the cup is raised well off the saucer and the steam billows up and thins away */
  body.is-leaving .choice--coffee.is-selected .art-move{animation:cup-lift .36s cubic-bezier(.25,.8,.3,1) forwards}
  body.is-leaving .choice--coffee.is-selected .art-steam{transform-origin:50% 100%;animation:steam-billow .4s cubic-bezier(.2,.6,.3,1) forwards}
  /* Bowling: a strike. The ball is let go at speed (from rest, no wind-up) and drives through, rolling its distance (290 units
     on r40.3); the pins scatter ahead of it in a chain (see pin-1) */
  body.is-leaving .choice--bowling.is-selected{--go:290px;--turn:412deg}
  body.is-leaving .choice--bowling.is-selected :is(.art-move,.art-ball,.art-speed){animation:drive .42s cubic-bezier(.5,.425,.65,1) forwards}
  body.is-leaving .choice--bowling.is-selected .art-ball{animation-name:roll}
  body.is-leaving .choice--bowling.is-selected .art-speed{transform-origin:100% 50%;animation-name:trail}
  body.is-leaving .choice--bowling.is-selected .art-tip{transform-origin:192px 214px;animation:pin-1 .42s linear forwards}
  body.is-leaving .choice--bowling.is-selected .art-pin2{animation:pin-2 .42s linear forwards}
  body.is-leaving .choice--bowling.is-selected .art-pin3{animation:pin-3 .42s linear forwards}
  .art-pin2,.art-pin3{transform-box:view-box;transform-origin:248px 214px}
  .art-pin3{transform-origin:304px 214px}
  .intro{grid-template-columns:1fr;justify-items:start;gap:.6rem;padding-bottom:1.1rem}
  .brand-plate{width:clamp(7.25rem,33vw,9.25rem)}
  h1{font-size:clamp(2.1rem,10.4vw,3.4rem);white-space:normal}
  .intro__copy{max-width:34rem;padding:0;border:0;font-size:clamp(.95rem,3.9vw,1.1rem)}
  .selector-shell{height:auto;min-height:100svh}
  .choices{flex-direction:column}
  /* flex-basis auto + a size-contained icon: a band never shrinks below its title and arrow (landscape phones scroll instead of clipping) */
  .choice{--label-size:clamp(2rem,min(12vw,11.5svh),4.5rem);flex:1 0 auto;grid-template:1fr auto auto 1fr / calc(var(--label-size) * 3.15 + var(--gutter)) minmax(0,1fr);min-height:clamp(8.5rem,22svh,15rem)}
  .choice--food{flex-grow:var(--g1)}.choice--coffee{flex-grow:var(--g2)}.choice--bowling{flex-grow:var(--g3)}
  .choice+.choice{box-shadow:inset 0 1px 0 rgb(255 255 255 / .07)}
  .choice__label{grid-area:2/1;padding:0 0 0 var(--gutter);font-size:var(--label-size)}
  .choice__arrow{grid-area:3/1;align-self:start;justify-self:start;width:clamp(2.5rem,11vw,2.9rem);margin:clamp(.5rem,2.5vw,.8rem) 0 0 var(--gutter);font-size:1.2rem}
  .choice__icon{grid-area:1/2/5/3;align-self:stretch;width:calc(118% + .5rem);height:100%;max-height:none;margin:0 0 0 -9%;padding:.9rem .25rem 0 0;contain:size;animation-name:rise-side} /* subject spans x 60-340, so the empty viewBox margins bleed */
  /* A tighter ring keeps clear of the title on a 16px gutter */
  .choice:focus-visible{outline-offset:-9px}
  .choice:focus-visible::after{inset:6px}
  .art-disc{--disc-base:1}
  footer{font-size:.7rem}
}
/* Phones on their side keep the stacked bands, with a margin so the title and arrow never touch the band edges */
@media (max-width:720px) and (orientation:landscape){.choice{grid-template-rows:minmax(.75rem,1fr) auto auto minmax(.75rem,1fr)}}
/* The cup leaves its shadow on the saucer on every exit (the side-by-side poses sit with the Selection rules).
   Reduced motion never adds .is-leaving */
body.is-leaving .choice--coffee.is-selected .art-lift{opacity:1;transform:none}
/* Small phones */
@media (max-width:720px) and (max-height:660px){
  .intro{gap:.4rem;padding-block:max(.75rem,env(safe-area-inset-top)) .8rem}
  .brand-plate{width:6.6rem}
  h1{font-size:2rem}
  .intro__copy{font-size:.875rem;line-height:1.4}
  .choice{min-height:7.5rem}
  .choice:focus-visible{outline-offset:-3px}
  .choice:focus-visible::after{inset:0}
}
@keyframes rise-side{from{opacity:0;transform:translateX(14px)}}

/* ---- Side by side: zero layout shift. The poster boxes stay equal thirds; the weights above only move two painted
   boundaries (--b1, --b2, % of the row). Each poster is clipped to its share [--l, --r] (paint and hit-testing alike, so a
   boundary never flickers), row-wide layers fill that share, and its title, art and arrow ride along by translate. Every frame
   matches the old flex-grow widening, but nothing is re-laid out, so hover sweeps score no CLS ---- */
@media (min-width:721px) and (orientation:landscape),(min-width:1101px){
  /* The row is the layers' containing block, and 1cqw is 1% of it */
  .choices{
    --sum:calc(var(--g1) + var(--g2) + var(--g3));
    --b1:calc(100 * var(--g1) / var(--sum));
    --b2:calc(100 * (var(--g1) + var(--g2)) / var(--sum));
    position:relative;
    container-type:inline-size;
    overflow:clip;
  }
  .choice{
    --l:0;--r:var(--b1);--c:0; /* share and resting column start, % of the row */
    --L:round(var(--l) * 1cqw, 1px);--R:round(var(--r) * 1cqw, 1px); /* share edges in whole px, as layout snapped them */
    --ring:11px;
    position:static;
    overflow:visible;
    background:none;
    /* Engines round clip edges differently (Chrome paints them outward, Firefox hit-tests them inward), so the left edge
       sits a hair in, past the box's 1/64px layout rounding (paint lands on the whole px), and the right edge a px out,
       under the right-hand poster that paints over it (the pointer never falls between two posters) */
    clip-path:inset(-100vh calc(var(--c) * 1cqw + 100cqw / 3 - var(--R) - 1px) -100vh calc(var(--L) - var(--c) * 1cqw + var(--hair, 0px)));
  }
  .choice--coffee{--l:var(--b1);--r:var(--b2);--c:calc(100 / 3)}
  .choice--bowling{--l:var(--b2);--r:100;--c:calc(200 / 3)}
  .choice+.choice{--hair:.03px;box-shadow:none}
  /* The field: the poster's color, with the hairline on its left edge. Clipped itself too, for the exit below */
  .choice__body::before{position:absolute;z-index:-2;inset:0;background:var(--bg);clip-path:inset(-100vh calc(100cqw - var(--R)) -100vh var(--L));content:""}
  .choice+.choice .choice__body::before{background:linear-gradient(90deg,rgb(255 255 255 / .07) calc(var(--L) + 1px),transparent 0),var(--bg)}
  /* The row-wide veil also takes the pointer where a widened share reaches past the poster's box */
  .choice::before{pointer-events:auto}
  /* The ring follows the share: top and bottom are borders, the sides a gradient; the outline stays for its width only */
  .choice:focus-visible{outline-color:transparent}
  .choice:focus-visible::after{
    inset:var(--ring) 0;
    border-inline:0;
    background:linear-gradient(90deg,transparent calc(var(--L) + var(--ring)),var(--champagne) 0 calc(var(--L) + var(--ring) + 3px),transparent 0 calc(var(--R) - var(--ring) - 3px),var(--champagne) 0) border-box;
    clip-path:inset(-100vh calc(100cqw - var(--R) + var(--ring)) -100vh calc(var(--L) + var(--ring)));
  }
  /* Title, art and arrow ride with their share at subpixel precision. Snapping them to whole px made them step while the
     discs scale smoothly, so disc edges jittered back and forth during the widening (read as twitching on retina) */
  .choice__label{translate:calc((var(--l) - var(--c)) * 1cqw)}
  .choice__arrow{translate:calc((var(--r) - var(--c) - 100 / 3) * 1cqw)}
  .choice__icon{
    scale:var(--press);
    translate:calc(((var(--l) + var(--r)) * .5 - var(--c) - 100 / 6) * 1cqw);
    transition:--press 90ms ease-out;
  }
  .choice:active .choice__icon{--press:.98;scale:var(--press)}
  /* Exit: a clip-path would also cut the fixed flood, so the chosen poster drops it and its art is cut on its own
     (the cut divided by the press scale, so releasing the press never opens a seam) */
  body.is-leaving .choice.is-selected{clip-path:none}
  body.is-leaving .choice.is-selected .choice__icon{clip-path:inset(-100vh calc(50% - (var(--R) - var(--L)) / 2 / var(--press)))}
}

/* Short landscape screens (laptops, phones on their side) */
@media (min-width:721px) and (max-height:700px){
  .intro{min-height:4.75rem;padding-block:.75rem}
  .choice__label{font-size:clamp(2.75rem,5.4vw,5rem)}
}
@media (min-width:721px) and (max-height:500px){
  .intro{min-height:0;padding-block:.55rem}
  .brand-plate{width:6.9rem}
  h1{font-size:2rem}
  .intro__copy{font-size:.85rem}
  .choice__label{padding-top:.9rem;font-size:clamp(2.25rem,4.8vw,3rem)}
  .choice__icon{padding:.5rem 0 3.25rem}
  .choice__arrow{--aw:2.6rem;margin-bottom:.45rem;font-size:1.15rem}
  footer{padding-block:.4rem}
  .choice{--ring:0px}
  .choice:focus-visible{outline-offset:-3px}
  .choice:focus-visible::after{inset:0}
}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-delay:0s!important;transition-duration:.01ms!important;transition-delay:0s!important}
  .choices{--g1:1!important;--g2:1!important;--g3:1!important}
  .choice .art-move,.choice .art-steam,.choice .art-wheel,.choice .art-tip,.choice .art-ball,.choice .art-speed,.choice .art-crema,.choice .art-crema-settle,.choice .art-lift{transform:none!important}
  .choice .art-disc{--disc-hover:1!important} /* keeps its screen-shape base size, never swells */
  .choice :is(.art-steam,.art-streaks)>path,.choice :is(.art-road,.art-spin,.art-body){animation:none!important} /* a looping animation at .01ms would flicker */
  .choice :is(.choice__icon,.choice__label,.choice__arrow){scale:none!important;--press:1!important}
  .choice :is(.art-speed,.art-lift){opacity:0!important}
}
