/* Silver City Brewery — type and chrome.
   Daylight. The page is paper and ink, and the scene behind it is a real
   Pacific Northwest afternoon. Nothing here is a void. */

:root{
  --paper:#f4f1ea;         /* warm bone */
  --paper-2:#fdfbf8;
  --ink:#14181c;           /* deep charcoal, never pure black */
  --ink-dim:rgba(20,24,28,.70);
  --ink-faint:rgba(20,24,28,.44);
  --line:rgba(20,24,28,.14);
  --teal:#17808f;          /* the signature, darkened to hold on paper */
  --violet:#5a45b0;
  --amber:#9d5410;         /* the beer, as a text colour */
  --mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  --serif:"Bodoni Moda",Didot,"Times New Roman",serif;
  --shadow:0 1px 2px rgba(20,24,28,.05), 0 10px 30px rgba(20,24,28,.08);
  --shadow-lg:0 2px 4px rgba(20,24,28,.04), 0 24px 60px rgba(20,24,28,.10);
}

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}

/* [hidden] must beat any display we set below, or the fallback and the
   secret panel paint over the whole site. */
[hidden]{display:none!important}

html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

body{
  background:var(--paper);
  color:var(--ink);
  font-family:var(--serif);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow-x:hidden;
  -webkit-user-select:none;user-select:none;
  touch-action:pan-y;
}
.addr,.spec-note{-webkit-user-select:text;user-select:text}

/* ======================================================== LIQUID GLASS ====
   A slab of glass, not a frosted panel. Three things separate the two:
     · the backdrop is BENT at the rim by an SVG displacement map, so the edge
       lenses the photograph behind it instead of only blurring it
     · a specular that tracks the same pour field driving the liquid — one
       light source moving across every piece of glass on the page at once
     · thickness: a bright inner top edge, a dimmer bounce off the inner
       bottom, and a soft cast shadow so it floats rather than sits
   The displacement is a progressive enhancement (html.lens); without it the
   material degrades to a very good frosted card and nothing else changes. */
.glass{
  --r:16px;
  position:relative;
  border:none;
  border-radius:var(--r);
  background:linear-gradient(var(--ga,150deg),
    rgba(255,255,255,.30) 0%, rgba(255,255,255,.10) 38%,
    rgba(255,255,255,.06) 62%, rgba(255,255,255,.22) 100%);
  -webkit-backdrop-filter:blur(9px) saturate(190%) brightness(1.04);
  backdrop-filter:blur(9px) saturate(190%) brightness(1.04);
  box-shadow:
    0 10px 34px rgba(20,24,28,.13),
    0 2px 8px rgba(20,24,28,.07),
    inset 0 1px 1px rgba(255,255,255,.88),
    inset 0 -1px 2px rgba(255,255,255,.34);
  overflow:hidden;
  isolation:isolate;
}
/* the moving specular */
.glass::before{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:1;
  background:radial-gradient(130% 95% at var(--gx,50%) var(--gy,6%),
    rgba(255,255,255,.55), rgba(255,255,255,.14) 42%, rgba(255,255,255,0) 68%);
  transition:opacity .5s;
}
/* the refracting rim — a hairline that catches light all the way round */
.glass::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:2;
  padding:1.2px;
  background:linear-gradient(var(--ga,150deg),
    rgba(255,255,255,.95), rgba(255,255,255,.16) 34%,
    rgba(255,255,255,.07) 58%, rgba(255,255,255,.88));
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
  mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  mask-composite:exclude;
}
.glass>*{position:relative;z-index:3}

html.lens .glass{
  -webkit-backdrop-filter:blur(4px) url(#liquid-glass) saturate(195%) brightness(1.04);
  backdrop-filter:blur(4px) url(#liquid-glass) saturate(195%) brightness(1.04);
}
/* text has to survive being laid over a refracted photograph */
.glass .tap-name,.glass .abv{text-shadow:0 1px 6px rgba(244,241,234,.7)}

.glass-lift{transition:transform .5s cubic-bezier(.16,1,.3,1),box-shadow .5s}
.glass-lift:hover{
  box-shadow:0 18px 46px rgba(20,24,28,.17),0 3px 10px rgba(20,24,28,.08),
    inset 0 1px 1px rgba(255,255,255,.95),inset 0 -1px 2px rgba(255,255,255,.40);
}

@media (prefers-reduced-motion:reduce){
  .glass::before{transition:none}
}

/* ========================================================= THE HOME PAGE ===
   A photographic hero the whole page sits on. The still is always present as
   the poster and the reduced-motion fallback; the flythrough, once shot, cross-
   fades in over it and holds its final frame. */
.hero{position:fixed;inset:0;z-index:0;overflow:hidden;background:var(--ink)}
.hero-still,.hero-video{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:center 52%;
}
/* The still is deliberately NOT transform-animated. A scale/translate keyframe
   on a full-bleed fixed image promotes a compositing layer that renders BLANK
   in Chromium (same trap the plate hit — see README). The flythrough video is
   where the motion lives; the still just holds, reliably painted. */
.hero-still{transform:scale(1.04)}
.hero-video{opacity:0;transition:opacity 1s ease}
.hero.is-playing .hero-video{opacity:1}
.hero.is-landed .hero-video{opacity:1}   /* hold the final frame */

/* legibility for the light hero copy, lower-left, without flattening the photo */
.hero-scrim{
  position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(to top, rgba(10,12,14,.66) 0%, rgba(10,12,14,.20) 34%, rgba(10,12,14,0) 62%),
    radial-gradient(120% 90% at 12% 92%, rgba(10,12,14,.42), rgba(10,12,14,0) 60%);
}

.home-main{
  position:relative;z-index:10;min-height:100svh;
  display:flex;flex-direction:column;justify-content:flex-end;
  /* top pad guarantees the headline clears the fixed header even when a short
     viewport forces the copy to grow upward past the fold */
  padding:clamp(5.5rem,15vh,9rem) clamp(1.2rem,4vw,4rem) clamp(1.6rem,4vw,3rem);
}
.hero-copy{max-width:min(760px,92vw);color:#fdfbf8}
.hero-copy .label{color:rgba(253,251,248,.82);margin-bottom:1.1rem}
.hero-copy .display{
  color:#fdfbf8;text-shadow:0 2px 40px rgba(10,12,14,.5);
  font-size:clamp(3rem,7.5vw,6.6rem);line-height:.9;
}

/* On the dark photographic hero the nav must read light, and the header scrim
   goes dark instead of paper. (The beer page keeps its dark-on-bright-sky nav.) */
:is([data-page="home"],[data-dark]) .hud::before{
  background:linear-gradient(rgba(10,12,14,.55) 0%, rgba(10,12,14,.14) 58%, transparent);
}
/* Home's nav now rides the same frosted glass as its wordmark chip, so its
   links read ink like everywhere else. Only the barrel room ([data-dark],
   where the glass itself goes dark) still needs light links. */
[data-dark] .site-nav-link{color:rgba(253,251,248,.82)}
[data-dark] .site-nav-link:hover,
[data-dark] .site-nav-link.is-current{color:#fff}
[data-dark] .site-nav-link::after{background:#fff}
.hero-copy .display em{color:var(--amber);-webkit-text-fill-color:currentColor;
  filter:brightness(1.5) saturate(1.1)}
.hero-copy .lede{color:rgba(253,251,248,.9);max-width:46ch;margin:1.4rem 0 0;
  text-shadow:0 1px 18px rgba(10,12,14,.55)}

/* the three ways in — glass over the photograph, so they refract the hero */
.entries{
  display:grid;grid-template-columns:repeat(3,1fr);gap:1rem;margin-top:2.4rem;
}
@media (max-width:820px){.entries{grid-template-columns:1fr}}
.entry{
  --r:16px;
  display:flex;flex-direction:column;gap:.5rem;
  padding:1.15rem 1.25rem 1.05rem;text-decoration:none;color:#fdfbf8;
  min-height:132px;
}
.entry-kicker{color:rgba(253,251,248,.72);font-size:.55rem}
.entry-title{font-family:var(--serif);font-weight:700;font-size:1.5rem;line-height:1;margin-top:.15rem}
.entry-sub{color:rgba(253,251,248,.82);font-size:.86rem;line-height:1.45;flex:1}
.entry-go{color:#fff;font-size:.58rem;letter-spacing:.2em;transition:letter-spacing .4s}
.entry:hover .entry-go{letter-spacing:.32em}
/* the glass reads darker over a photo, so warm the fill for these */
.entry.glass{
  background:linear-gradient(var(--ga,150deg),
    rgba(255,255,255,.22) 0%, rgba(255,255,255,.07) 42%,
    rgba(255,255,255,.05) 62%, rgba(255,255,255,.16) 100%);
}

.home-disclosure{margin:1.8rem auto 0;color:rgba(253,251,248,.55);text-align:center;
  max-width:70ch;font-size:.5rem;line-height:1.9;letter-spacing:.13em}

/* ---- the photographic plate ---- */
#plate{position:fixed;inset:0;z-index:0;overflow:hidden;background:var(--paper)}
.plate-img{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:center 46%;
  opacity:0;transition:opacity 1.05s cubic-bezier(.4,0,.2,1);
}
.plate-img.is-on{opacity:1}
/* A slow drift, so the shot breathes instead of sitting there like wallpaper.
   2D transforms only, and on the images rather than the fixed container: a
   translate3d keyframe on #plate promoted it to a layer that composited
   blank — DOM state read perfectly correct while the pixels showed nothing. */
.plate-img{animation:plate-drift 54s ease-in-out infinite alternate}
@keyframes plate-drift{
  from{transform:scale(1.04) translate(-0.7%, 0.5%)}
  to{transform:scale(1.10) translate(0.7%, -0.6%)}
}
@media (prefers-reduced-motion:reduce){
  .plate-img{animation:none;transform:scale(1.04)}
}

/* the pour, as a full-bleed plate layer in the DOM path */
#pour{
  position:fixed;inset:0;width:100%;height:100%;z-index:0;
  object-fit:cover;object-position:center 46%;
  opacity:0;transition:opacity 1.05s cubic-bezier(.4,0,.2,1);pointer-events:none;
}
#pour.is-on{opacity:1}

/* the WebGPU plate, when the browser has one. It replaces the DOM layers
   entirely rather than sitting on top of them. */
#gpuplate{position:fixed;inset:0;width:100%;height:100%;display:block;z-index:1;opacity:0}
/* The pour is uploaded to the GPU from this <video> every frame, and a video
   Chromium is not painting stops producing frames — display:none and opacity:0
   both kill it (verified: identical pixels sampled 3.4s apart). So in GPU mode
   the video stays fully painted and simply sits UNDER the opaque GPU canvas,
   which covers it completely. The still layers do get hidden; only the video
   needs to keep decoding. */
html.gpu #plate{display:none}
html.gpu #gpuplate{opacity:1}
/* In GPU mode the pour is a texture, so the element itself must not be seen —
   but it must still be PAINTED, or the frames stop coming. A few pixels in the
   corner at 1% opacity keeps the decoder alive and is invisible in practice. */
html.gpu #pour{
  inset:auto auto 0 0;width:8px;height:6px;opacity:.01;z-index:4;transition:none;
}
/* The ceremony clips live by the same law. Each parks in its OWN slot along
   the bottom edge — one video occluding another stops the occluded one's
   decoder just as surely as display:none would. */
.cer{display:none}
html.gpu .cer{
  display:block;position:fixed;inset:auto auto 0 0;width:8px;height:6px;
  opacity:.01;z-index:4;pointer-events:none;transition:none;
}
html.gpu #cer-take{left:10px}   /* #pour owns 0–8px */
html.gpu #cer-place{left:20px}
html.gpu #cer-fill{left:30px}

/* the canvas is the dive, and nothing else — invisible until you go under */
#stage{
  position:fixed;inset:0;width:100%;height:100%;display:block;z-index:2;
  opacity:0;pointer-events:none;
}

/* washes the plate toward paper under the type-heavy sections */
#wash{position:fixed;inset:0;z-index:3;pointer-events:none;background:var(--paper);opacity:0}

/* the cold glass, DOM path only: a frosted veil where the GPU would render
   real condensation. Kept invisible AND hidden when clear so the backdrop
   blur never costs anything outside the crossing. */
#fog{
  position:fixed;inset:0;z-index:2;pointer-events:none;
  background:linear-gradient(rgba(244,241,234,.55), rgba(244,241,234,.38));
  -webkit-backdrop-filter:blur(16px) saturate(80%) brightness(1.06);
  backdrop-filter:blur(16px) saturate(80%) brightness(1.06);
  opacity:0;visibility:hidden;
}

#fallback{
  position:fixed;inset:0;z-index:50;display:grid;place-content:center;
  gap:1rem;padding:2rem;text-align:center;background:var(--paper);
}
#fallback h1{font-size:clamp(2rem,7vw,4rem);font-weight:900}

.mono{font-family:var(--mono);font-weight:500;letter-spacing:.17em;text-transform:uppercase;font-size:.66rem}

/* ------------------------------------------------------------------ hud */
.hud{
  position:fixed;top:0;left:0;right:0;z-index:20;
  display:grid;grid-template-columns:1fr auto 1fr;align-items:center;
  padding:clamp(1rem,2.4vw,1.9rem) clamp(1rem,3vw,2.4rem);
  pointer-events:none;
}
/* The scrim arrives only once content can scroll UNDER the nav — at rest the
   photograph owns the top of the frame. nav.js toggles html.scrolled. */
.hud::before{
  content:"";position:absolute;inset:0 0 -34%;z-index:-1;pointer-events:none;
  background:linear-gradient(rgba(244,241,234,.85), rgba(244,241,234,.4) 55%, transparent);
  opacity:0;transition:opacity .5s;
}
html.scrolled .hud::before{opacity:1}
.hud>.mark{justify-self:start}
.hud>.hud-right{justify-self:end}
.hud>*{pointer-events:auto}

/* the shared nav — a glass pill like the wordmark and the sound button, not
   loose text. Scrims lose to display type scrolling underneath (the .mark
   learned this first); an object wins outright. Mono caps inside, a hairline
   that lifts on the current page. */
.site-nav{
  --r:100px;
  justify-self:center;display:flex;gap:clamp(.5rem,1.6vw,1.4rem);
  align-items:center;padding:.3rem 1.15rem;
}
.site-nav-link{
  font-family:var(--mono);font-size:.62rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink-dim);text-decoration:none;padding:.5rem .2rem;position:relative;
  transition:color .35s;
}
.site-nav-link::after{
  content:"";position:absolute;left:.2rem;right:.2rem;bottom:.24rem;height:1.5px;
  background:var(--teal);transform:scaleX(0);transform-origin:left;
  transition:transform .4s cubic-bezier(.16,1,.3,1);
}
.site-nav-link:hover{color:var(--ink)}
.site-nav-link:hover::after,
.site-nav-link.is-current::after{transform:scaleX(1)}
.site-nav-link.is-current{color:var(--ink)}

@media (max-width:720px){
  /* on a phone the wordmark and nav share the top; drop the sub-line's weight
     and let the nav wrap under if it must, rather than crushing the row */
  .hud{grid-template-columns:auto 1fr;row-gap:.5rem}
  .site-nav{grid-column:1/-1;justify-self:center;flex-wrap:wrap;justify-content:center}
  .hud>.hud-right{grid-row:1;grid-column:2}
}
/* The wordmark is its own piece of glass rather than loose text over the
   photograph. A full-width scrim used to sit here and it still lost — display
   type scrolling underneath punched straight through it. Making the mark an
   object instead of a wash fixes the collision outright. */
.mark{
  --r:13px;
  text-decoration:none;color:inherit;display:block;line-height:1;
  padding:.62rem .95rem .58rem;
}
/* The wordmark is THEIR mark now — the script logo from their media kit
   (their IP, disclosed) — not our typographic stand-in. */
.mark-logo{display:block;height:clamp(30px,3.4vw,42px);width:auto}
.mark-line{
  display:block;font-family:var(--serif);font-weight:700;
  font-size:clamp(.95rem,1.7vw,1.25rem);letter-spacing:.13em;
  text-shadow:0 1px 14px rgba(244,241,234,.85);
}
.mark-sub{display:block;margin-top:.42rem;color:var(--ink-faint);font-size:.55rem}
[data-dark] .mark-sub{color:rgba(253,251,248,.6)}
.hud-right{display:flex;align-items:center;gap:1rem}
.greet{color:var(--teal);opacity:0;transition:opacity 1.2s ease;max-width:42vw;text-align:right;font-size:.57rem;line-height:1.5}
.greet.on{opacity:1}

.ghost{
  --r:100px;
  background:rgba(253,251,248,.42);
  -webkit-backdrop-filter:blur(10px) saturate(180%);backdrop-filter:blur(10px) saturate(180%);
  border:none;color:var(--ink-dim);
  padding:.6rem .95rem;border-radius:var(--r);cursor:pointer;
  font-family:var(--mono);font-size:.57rem;letter-spacing:.18em;text-transform:uppercase;
  display:inline-flex;align-items:center;gap:.55rem;position:relative;
  box-shadow:
    0 6px 20px rgba(20,24,28,.12),
    inset 0 1px 1px rgba(255,255,255,.9),
    inset 0 -1px 2px rgba(255,255,255,.35);
  transition:color .4s,background .4s,box-shadow .4s;
}
.ghost::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;padding:1.2px;
  background:linear-gradient(var(--ga,150deg),
    rgba(255,255,255,.95), rgba(255,255,255,.16) 40%, rgba(255,255,255,.85));
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
  mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  mask-composite:exclude;
}
.ghost:hover{color:var(--teal)}
.dot{width:5px;height:5px;border-radius:50%;background:var(--ink-faint);transition:background .4s,box-shadow .4s}
.ghost[aria-pressed="true"] .dot{background:var(--teal);box-shadow:0 0 0 3px rgba(23,128,143,.18)}

/* ---------------------------------------------------------------- layout */
main{position:relative;z-index:10}
.beat{min-height:100svh;display:flex;align-items:center;padding:14vh 0;scroll-margin-top:5.5rem}
.beat.tall{min-height:230svh;align-items:flex-start}
.beat.tall>.wrap{position:sticky;top:34vh}
.wrap{width:min(1180px,90vw);margin:0 auto}
.center{text-align:center}

.label{color:var(--ink-faint);margin-bottom:1.5rem}
.label .num{color:var(--teal);margin-right:.65rem;font-weight:500}

.display{
  font-weight:900;line-height:.86;letter-spacing:-.032em;
  font-size:clamp(3.6rem,15vw,12rem);
  text-shadow:0 2px 40px rgba(244,241,234,.55);
}
.display em{font-style:italic;font-weight:400;color:var(--amber)}
.display.sm{font-size:clamp(2.8rem,10vw,7rem)}

.section-title{
  font-weight:900;line-height:.94;letter-spacing:-.022em;
  font-size:clamp(2.2rem,6.4vw,5rem);margin-bottom:1.5rem;
}

.lede{
  font-size:clamp(1.05rem,1.65vw,1.34rem);line-height:1.60;
  max-width:44ch;margin:1.9rem auto 0;color:var(--ink-dim);
}
.center .lede{margin-inline:auto}
.lede strong{color:var(--ink);font-weight:700}
.lede em{color:var(--amber);font-style:italic}
.sub{max-width:54ch;color:var(--ink-dim);line-height:1.62;font-size:clamp(.98rem,1.3vw,1.08rem)}

.hint{margin-top:3rem;color:var(--ink-faint);animation:drift 4.7s ease-in-out infinite}
@keyframes drift{0%,100%{opacity:.45;transform:translateY(0)}50%{opacity:.9;transform:translateY(5px)}}

/* The headline lives on the sky, where dark ink reads perfectly. Only the body
   copy — which would otherwise fall across the pour — gets a frosted caption
   card, so it reads as a deliberate editorial device rather than as text
   fighting its background. */
[data-beat="arrival"] .lede,
[data-beat="crossing"] .lede{
  max-width:min(38rem, 90vw);
  padding:clamp(1.3rem,2.6vw,1.9rem) clamp(1.4rem,3vw,2.2rem);
  border-radius:4px;
  background:rgba(250,248,244,.72);
  -webkit-backdrop-filter:blur(20px) saturate(115%);
  backdrop-filter:blur(20px) saturate(115%);
  border:1px solid rgba(255,255,255,.60);
  box-shadow:var(--shadow-lg);
}
[data-beat="arrival"] .label,
[data-beat="arrival"] .display,
[data-beat="arrival"] .hint,
[data-beat="crossing"] .label,
[data-beat="crossing"] .display,
[data-beat="crossing"] .hint{
  text-shadow:0 1px 16px rgba(248,246,241,.80), 0 0 40px rgba(248,246,241,.55);
}

/* --------------------------------------------------------------- the taps */
/* The lineup, as the cans themselves. Eight across on a wide screen, four on a
   tablet, two on a phone — the can does the identifying, the type only confirms
   it. */
.taps{
  position:relative;
  display:grid;grid-template-columns:repeat(8,1fr);gap:.5rem;
  margin:2.8rem 0 2.2rem;align-items:stretch;grid-auto-rows:1fr;
}
/* The backdrop mirror the card shader samples (see glasscards.js). Opacity
   zero on purpose: the shader reads its pixels, the page must never show the
   duplicate. Do not display:none it — a canvas that is not painted may stop
   being readable, and inset:0 is what keeps its rect equal to the grid's. */
/* width/height 100% is load-bearing: a canvas is a replaced element, so
   inset:0 alone leaves it at its intrinsic bitmap size — twice the grid on a
   2× display — and every card then samples a half-scale slice of the wrong
   part of the scene. */
.taps-mirror{position:absolute;inset:0;width:100%;height:100%;opacity:0;pointer-events:none}
/* html.lgx = the WebGL card shader is live. The slab, the specular and the
   rim all come out of the fragment shader now — leaving the CSS material on
   would light an already-lit surface twice. Fallback keeps every rule above. */
html.lgx .tap.glass{
  background:none;
  -webkit-backdrop-filter:none;backdrop-filter:none;
  box-shadow:none;
}
html.lgx .tap.glass::before,html.lgx .tap.glass::after{display:none}
@media (max-width:1080px){.taps{grid-template-columns:repeat(4,1fr)}}
@media (max-width:560px){.taps{grid-template-columns:repeat(2,1fr);gap:.4rem}}
.tap{
  color:var(--ink-dim);
  padding:1rem .6rem .85rem;cursor:pointer;text-align:center;
  font-family:var(--mono);font-size:.58rem;letter-spacing:.1em;text-transform:uppercase;
  transition:color .45s,transform .5s cubic-bezier(.16,1,.3,1),box-shadow .5s;
}
.tap-swatch{
  position:absolute;left:0;bottom:0;height:3px;width:100%;z-index:3;
  background:var(--swatch,var(--amber));transform:scaleX(0);transform-origin:left;
  transition:transform .6s cubic-bezier(.16,1,.3,1);
  border-radius:0 0 var(--r) var(--r);
}
.tap[aria-selected="true"] .tap-swatch{transform:scaleX(1)}
.tap-can{display:block;height:96px;margin-bottom:.6rem}
.tap-can img{
  height:100%;width:100%;object-fit:contain;display:block;
  filter:drop-shadow(0 6px 12px rgba(20,24,28,.20));
  transition:transform .55s cubic-bezier(.16,1,.3,1);
}
.tap:hover .tap-can img{transform:translateY(-4px) scale(1.04)}
.tap[aria-selected="true"] .tap-can img{transform:translateY(-5px) scale(1.07)}
.tap-name{display:block;line-height:1.35}
@media (max-width:560px){.tap-can{height:78px}}
.tap:hover{color:var(--ink);transform:translateY(-3px)}
.tap[aria-selected="true"]{color:var(--ink)}
.tap .abv{display:block;margin-top:.36rem;color:var(--ink-faint);font-size:.55rem;letter-spacing:.1em}

.spec{
  display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);
  gap:clamp(1.5rem,4vw,3.5rem);align-items:start;
  border-top:1px solid var(--line);padding-top:2.2rem;
}
.spec-main{display:grid;grid-template-columns:auto minmax(0,1fr);
  grid-template-rows:auto auto;column-gap:1.6rem;align-items:start}
.spec-can{grid-row:1/3;width:clamp(84px,11vw,132px);line-height:0}
.spec-can img{
  width:100%;height:auto;display:block;
  filter:drop-shadow(0 10px 22px rgba(20,24,28,.22));
}
@media (max-width:560px){
  .spec-main{grid-template-columns:1fr;row-gap:1.1rem}
  .spec-can{grid-row:auto;width:96px}
}
.spec-main h3{font-size:clamp(1.9rem,4vw,3rem);font-weight:700;line-height:1;margin-bottom:.85rem}
.spec-note{color:var(--ink-dim);line-height:1.62;max-width:38ch}
.spec-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:1.4rem 1rem}
.spec-grid dt{color:var(--ink-faint);margin-bottom:.42rem;font-size:.55rem}
.spec-grid dd{font-size:1.08rem;color:var(--ink)}

/* the pint slides right on wide screens — keep the lineup out of its way */
@media (min-width:900px){
  [data-beat="choice"] .label,
  [data-beat="choice"] .section-title,
  [data-beat="choice"] .sub,
  [data-beat="choice"] .taps,
  [data-beat="choice"] .spec{max-width:60%}
}

/* ------------------------------------------------------------- the crossing */
.cross-a,.cross-b,.cross-c{transition:opacity .9s ease,transform .9s ease}
.cross-b{opacity:0;transform:translateY(14px)}
.cross-c{opacity:0}

/* -------------------------------------------------------------- the taproom */
.cards{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:1px;margin:3rem 0;
  background:var(--line);border:1px solid var(--line);
  border-radius:4px;overflow:hidden;box-shadow:var(--shadow-lg);
}
@media (max-width:860px){.cards{grid-template-columns:1fr}}
.card{background:var(--paper-2);padding:clamp(1.5rem,2.8vw,2.4rem)}
.card .mono{color:var(--ink-faint);margin-bottom:1.3rem}
.big{font-size:clamp(2rem,4vw,3.1rem);font-weight:700;line-height:1.05;display:flex;align-items:baseline;gap:.7rem}
.unit{font-family:var(--mono);font-size:.57rem;letter-spacing:.16em;color:var(--ink-faint);text-transform:uppercase}
.rules{list-style:none;display:grid;gap:.75rem}
.rules li{position:relative;padding-left:1.25rem;color:var(--ink-dim);font-size:1.04rem}
.rules li::before{content:"";position:absolute;left:0;top:.6em;width:6px;height:6px;border-radius:50%;background:var(--teal)}
.addr{line-height:1.6;font-size:1.06rem;color:var(--ink-dim);margin-bottom:1.3rem}
.link{color:var(--teal);text-decoration:none;border-bottom:1px solid rgba(23,128,143,.35);padding-bottom:.2rem}
.link:hover{border-color:var(--teal)}
.fire{font-style:italic;font-size:clamp(1.15rem,2.4vw,1.75rem);color:var(--ink-dim);max-width:30ch}

/* ---------------------------------------------------------------- plates */
.shot{margin:3rem 0;border-radius:5px;overflow:hidden;box-shadow:var(--shadow-lg);line-height:0}
.shot img{width:100%;height:auto;display:block}
.shot.wide{margin-top:3.5rem}
@media (max-width:760px){.shot{margin:2.2rem 0}}

.two-up{display:grid;grid-template-columns:1fr 1fr;gap:1.4rem;margin:3rem 0}
.two-up .shot{margin:0}
@media (max-width:760px){.two-up{grid-template-columns:1fr;gap:1rem;margin:2.2rem 0}}

.secret-shot{margin:0 0 1.6rem;border-radius:4px;overflow:hidden;line-height:0}
.secret-shot img{width:100%;height:auto;display:block}

.disclosure{
  margin-top:1.6rem;color:var(--ink-faint);opacity:.75;
  font-size:.5rem;line-height:1.9;letter-spacing:.13em;
  max-width:62ch;margin-inline:auto;
}

/* ------------------------------------------------------------- the counters */
.counters{display:flex;flex-wrap:wrap;justify-content:center;gap:clamp(2rem,7vw,6rem);margin-bottom:2.8rem}
.counter{display:grid;gap:.75rem;justify-items:center}
.cnum{
  font-size:clamp(2.6rem,8vw,6rem);font-weight:900;line-height:1;
  font-variant-numeric:tabular-nums;color:var(--ink);
}
.clabel{color:var(--ink-faint);font-size:.55rem}

/* --------------------------------------------------------------- the ending */
[data-beat="end"]{min-height:110svh}
.end-line{font-size:clamp(1.7rem,5vw,3.4rem);font-style:italic;line-height:1.26;color:var(--ink)}
.end-sub{margin-top:3.5rem;color:var(--ink-faint);font-size:.55rem}

/* ---------------------------------------------------------------- reveals */
.reveal{opacity:0;transform:translateY(18px);transition:opacity 1.1s cubic-bezier(.16,1,.3,1),transform 1.1s cubic-bezier(.16,1,.3,1)}
.reveal.on{opacity:1;transform:none}
.beat .wrap>*{transition-delay:calc(var(--d,0) * 90ms)}

/* ----------------------------------------------------------------- secret */
.secret{
  position:fixed;inset:0;z-index:60;display:grid;place-items:center;padding:2rem;
  background:rgba(244,241,234,.80);
  -webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);
  animation:fade .7s ease;
}
@keyframes fade{from{opacity:0}to{opacity:1}}
.secret-inner{
  width:min(520px,100%);border:1px solid var(--line);
  background:var(--paper-2);
  padding:clamp(1.9rem,4vw,2.9rem);display:grid;gap:1.15rem;border-radius:5px;
  box-shadow:var(--shadow-lg);
}
.secret-inner h3{font-size:clamp(1.7rem,4vw,2.4rem);font-weight:700}
.secret-inner p{color:var(--ink-dim);line-height:1.62}
.secret-inner .foot{color:var(--teal)}
.secret-inner .ghost{justify-self:start;margin-top:.4rem}
/* the panel's two actions share a row: the real thing first, then CLOSE */
.secret-actions{display:flex;gap:.6rem;align-items:center}
.secret-join{text-decoration:none;color:var(--ink)}
.secret-join:hover{color:var(--amber-deep,#8a5a19)}

.holdring{
  position:fixed;z-index:19;pointer-events:none;
  width:64px;height:64px;margin:-32px 0 0 -32px;border-radius:50%;
  border:1px solid var(--teal);opacity:0;transition:opacity .3s;
}

/* ------------------------------------------------------------------ footer */
/* Every link is the brewery's own page — the spec hands you to them (same
   call as TAPROOM/MERCH in the nav). And it speaks the site's material
   language: VISIT is a slab of the same glass as the taps, the links are
   frosted pills, and all of it is lit by the ONE LIGHT (--gx/--gy) that
   moves across every glass surface on the page. Rendered by nav.js. */
.site-footer{
  position:relative;z-index:4;
  max-width:1080px;margin:0 auto;
  padding:3.4rem clamp(1.2rem,4vw,2.5rem) 4.5rem;
}
.foot-head{margin-bottom:2rem}
.foot-grid{
  display:grid;grid-template-columns:minmax(260px,320px) 1fr 1.35fr;
  gap:clamp(.9rem,2vw,1.4rem);align-items:start;
}
@media (max-width:1020px){
  .foot-grid{grid-template-columns:1fr 1.35fr}
  .foot-grid .foot-visit{grid-column:1 / -1;max-width:420px}
}
.foot-visit{
  padding:clamp(1.4rem,2.6vw,2rem);display:grid;gap:.55rem;justify-items:start;
}
.foot-visit .addr{line-height:1.6;margin-bottom:.35rem}
.foot-visit .link{margin-top:.8rem}
.foot-title{
  font-size:.58rem;letter-spacing:.22em;color:var(--ink-faint);
  margin:0 0 .85rem;
}
.foot-visit .foot-title{margin-bottom:.9rem}
.foot-line{font-size:.6rem;letter-spacing:.1em;color:var(--ink-dim);line-height:1.9}
.foot-links{display:contents}   /* the two slabs are foot-grid columns */
.foot-group{padding:clamp(1.1rem,2vw,1.5rem);display:grid;gap:.9rem;align-content:start}
.foot-group .foot-title{margin:0}
.foot-row{display:grid;gap:.5rem}
/* auto-fit with a real minimum: pills wrap to fewer columns instead of
   overlapping their own labels in narrow containers (caught in the real-
   device pass — the 880px subpage footer never had room for three) */
.foot-row--2{grid-template-columns:repeat(auto-fit,minmax(112px,1fr))}
.foot-row--3{grid-template-columns:repeat(auto-fit,minmax(148px,1fr))}   /* SECRET SOCIETY + its parked arrow need 99px inside the padding */
.foot-pill{
  text-decoration:none;color:var(--ink-dim);
  justify-content:center;text-align:center;white-space:nowrap;
}
.foot-pill .pill-go{
  color:var(--amber);transform:translateX(-2px);opacity:0;
  transition:transform .4s cubic-bezier(.16,1,.3,1),opacity .4s;
}
.foot-pill:hover{color:var(--ink)}
.foot-pill:hover .pill-go{transform:none;opacity:1}
.foot-pill.is-here{color:var(--ink);box-shadow:
  0 6px 20px rgba(20,24,28,.12), inset 0 1px 1px rgba(255,255,255,.9),
  inset 0 -1px 2px rgba(255,255,255,.35), inset 0 0 0 1px var(--amber)}
/* tiny mono over a photograph needs the same paper halo the tap labels wear */
.foot-head,.foot-title,.foot-line{text-shadow:0 1px 6px rgba(244,241,234,.7)}
@media (max-width:760px){
  .foot-grid{grid-template-columns:1fr}
  .foot-visit{width:100%;max-width:420px}
}
@media (max-width:640px){
  .foot-row--3{grid-template-columns:repeat(2,minmax(0,1fr))}
}

/* Home is the dark photographic page — same inversion the nav already makes:
   light type, dark halos, and room enough that the landed doorstep frame gets
   its moment before the footer arrives. The glass and pills carry their own
   material and need no re-colouring. */
[data-page="home"] .site-footer{margin-top:16vh}
/* The head sits outside the slabs, so on photographic pages it stays light;
   everything INSIDE a slab reads ink on light glass and needs no override —
   except the dark society, whose glass runs dark. */
:is([data-page="home"],[data-dark]) .foot-head{color:rgba(253,251,248,.8);text-shadow:0 1px 10px rgba(10,12,14,.7)}
[data-dark] .foot-title{color:rgba(253,251,248,.8)}
[data-dark] .foot-line{color:rgba(253,251,248,.88)}
[data-dark] .foot-visit .addr{color:#fdfbf8}
[data-dark] .foot-visit .link{filter:brightness(1.45) saturate(1.05)}
[data-page="home"] .home-disclosure{margin-top:2.4rem}

/* --------------------------------------------------------------- subpages */
/* The six brewery pages (faq · contact · careers · kegs · media kit · secret
   society). One shared skeleton: a fixed photographic plate from the site's
   own library, a wash for the type, glass cards for the content, and the one
   light drifting with the pointer (js/subpage.js). The secret society page
   flips dark ([data-dark]) — the one place darkness is earned. */
.sub-plate{position:fixed;inset:0;z-index:0;overflow:hidden;background:var(--paper)}
.sub-wash{
  position:fixed;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(rgba(244,241,234,.9), rgba(244,241,234,.55) 42%, rgba(244,241,234,.86));
}
[data-dark] body{background:#0c0e11}
[data-dark] .sub-wash{
  background:linear-gradient(rgba(10,12,15,.84), rgba(10,12,15,.52) 45%, rgba(10,12,15,.9));
}
.sub-main{
  position:relative;z-index:4;max-width:880px;margin:0 auto;
  padding:clamp(7rem,16vh,10rem) clamp(1.2rem,4vw,2.5rem) 1.5rem;
}
.sub-hero{margin-bottom:2.6rem}
.sub-hero .display{margin:.7rem 0 1.3rem}
.sub-grid{
  display:grid;gap:1rem;margin:2.4rem 0;
  grid-template-columns:repeat(auto-fit,minmax(250px,1fr));
}
.sub-card{padding:clamp(1.3rem,2.4vw,1.9rem);display:grid;gap:.6rem;align-content:start;justify-items:start}
.sub-card>.mono:first-child{color:var(--ink-faint);font-size:.58rem;letter-spacing:.22em;margin-bottom:.5rem}
.sub-card p{color:var(--ink-dim);line-height:1.62}
.sub-card .big{margin:.15rem 0}
.sub-note{color:var(--ink-dim);max-width:60ch;line-height:1.7}
.sub-real{margin:3rem 0 1.5rem;color:var(--ink-faint);font-size:.55rem;letter-spacing:.14em}

/* FAQ accordions — glass that opens like a tap */
.qa{padding:0;overflow:hidden;margin-bottom:.75rem}
.qa summary{
  list-style:none;cursor:pointer;display:flex;justify-content:space-between;
  align-items:baseline;gap:1rem;padding:1.15rem 1.35rem;
  font-family:var(--mono);font-size:.66rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink);
}
.qa summary::-webkit-details-marker{display:none}
.qa .plus{color:var(--amber);font-size:.9rem;transition:transform .45s cubic-bezier(.16,1,.3,1)}
.qa[open] .plus{transform:rotate(45deg)}
.qa-a{padding:0 1.35rem 1.25rem;color:var(--ink-dim);line-height:1.66;max-width:62ch}
.qa-a a{color:var(--teal)}

/* keg rows — the numbers do the selling */
.keg-row{
  display:grid;grid-template-columns:minmax(120px,auto) 1fr;gap:.2rem 1.6rem;
  align-items:baseline;padding:1.05rem 0;border-top:1px solid var(--line);
}
.keg-row:first-of-type{border-top:0;padding-top:0}
.keg-row .mono{color:var(--ink-faint);font-size:.56rem;letter-spacing:.18em}

/* the dark society */
[data-dark] .display,[data-dark] .sub-card .big{color:#fdfbf8}
[data-dark] .lede,[data-dark] .sub-note,[data-dark] .sub-card p{color:rgba(253,251,248,.78)}
[data-dark] .label,[data-dark] .sub-real{color:rgba(253,251,248,.5)}
[data-dark] .sub-card>.mono:first-child{color:var(--teal)}
[data-dark] .glass{
  background:linear-gradient(var(--ga,150deg),
    rgba(22,26,31,.66) 0%, rgba(22,26,31,.38) 55%, rgba(22,26,31,.6) 100%);
  box-shadow:
    0 12px 40px rgba(0,0,0,.55), 0 2px 8px rgba(0,0,0,.4),
    inset 0 1px 1px rgba(255,255,255,.16), inset 0 -1px 2px rgba(255,255,255,.05);
}
[data-dark] .glass::before{
  background:radial-gradient(130% 95% at var(--gx,50%) var(--gy,6%),
    rgba(255,255,255,.16), rgba(255,255,255,.05) 42%, rgba(255,255,255,0) 68%);
}
[data-dark] .glass::after{
  background:linear-gradient(var(--ga,150deg),
    rgba(255,255,255,.4), rgba(255,255,255,.08) 34%,
    rgba(255,255,255,.04) 58%, rgba(255,255,255,.34));
}
[data-dark] .ghost{background:rgba(24,28,34,.6);color:rgba(253,251,248,.85)}
[data-dark] .foot-pill{color:rgba(253,251,248,.85)}
[data-dark] .foot-pill:hover{color:#fff}

/* The replay offer: bottom-right, silent until the flythrough has landed. */
.fly-again{
  position:fixed;right:clamp(1rem,3vw,2.4rem);bottom:clamp(1rem,3vw,2rem);
  z-index:12;opacity:0;pointer-events:none;transform:translateY(6px);
  transition:opacity .9s,transform .9s cubic-bezier(.16,1,.3,1);
}
.fly-again.on{opacity:1;pointer-events:auto;transform:none}

/* ------------------------------------------------------ finishing touches */
/* Even text selection is on-palette: amber on the paper pages, teal in the
   dark society. */
::selection{background:rgba(201,138,43,.28)}
[data-dark] ::selection{background:rgba(89,217,228,.22)}
/* FAQ answers pour open instead of snapping, where the engine allows it */
@supports (interpolate-size: allow-keywords){
  :root{interpolate-size:allow-keywords}
  .qa::details-content{
    block-size:0;overflow:hidden;
    transition:block-size .5s cubic-bezier(.16,1,.3,1),content-visibility .5s allow-discrete;
  }
  .qa[open]::details-content{block-size:auto}
}

/* ------------------------------------------------------- keyboard focus */
/* Pointer users get the glass hover language; keyboard users get an honest
   amber ring. :focus-visible only — no ring on mouse clicks. */
.tap:focus-visible,.ghost:focus-visible,.foot-pill:focus-visible,
.entry:focus-visible,.site-nav-link:focus-visible,.link:focus-visible,
.qa summary:focus-visible{
  outline:2px solid var(--amber);outline-offset:3px;border-radius:6px;
}

/* ------------------------------------------------------------------ mobile */
@media (max-width:760px){
  .spec{grid-template-columns:1fr}
  .greet{display:none}
  .beat{padding:12vh 0}
  .beat.tall{min-height:200svh}
  .taps{gap:.45rem}
  .tap{flex:1 1 calc(50% - .45rem)}
}

/* the climb's film fills the frame like the canvas it replaced */
.hz-holder video.hz-gl{width:100%;height:100%;object-fit:cover}

/* ------------------------------------------------------------ the can grid */
/* cans.html — seven cans in the round (js/cangrid.js), one draft-only truth.
   The stage is the little theatre: the WebGPU canvas floats over the card's
   glass, the flat render underneath is the honest fallback. Canvas is a
   replaced element: inset alone will not stretch it — width/height must. */
.can-grid{
  display:grid;gap:1rem;margin:2.4rem 0;
  grid-template-columns:repeat(auto-fit,minmax(235px,1fr));
}
.can-card{
  margin:0;padding:clamp(1rem,2vw,1.4rem);display:grid;gap:.9rem;
  align-content:start;transition:transform .5s cubic-bezier(.16,1,.3,1);
}
.cg-live .can-card:not(.can-card--draft):hover{transform:translateY(-5px)}
.can-stage{
  position:relative;width:100%;aspect-ratio:3/4;
  touch-action:pan-y;cursor:grab;
}
.can-stage.is-held{cursor:grabbing}
.can-stage.is-draft{cursor:default}
.can-gl{position:absolute;inset:0;width:100%;height:100%;display:block}
.can-flat{
  position:absolute;inset:0;width:100%;height:100%;object-fit:contain;
  opacity:0;transition:opacity .6s;
}
/* the fallback becomes the picture whenever the light cannot: page-wide
   (html.cg-flat), per-card (.can-stage.cg-flat), or by design (.is-draft) */
.cg-flat .can-flat,.can-stage.cg-flat .can-flat,.can-flat.is-on{opacity:1}
.cg-flat .can-gl,.can-stage.cg-flat .can-gl{display:none}
.can-meta{display:grid;gap:.35rem;justify-items:start}
.can-name{font-weight:700;font-size:1.12rem;line-height:1.2;color:var(--ink)}
.can-spec{font-size:.56rem;letter-spacing:.2em;color:var(--ink-faint)}
.can-card--draft .can-spec{color:var(--amber)}
.can-note{font-size:.86rem;line-height:1.6;color:var(--ink-dim)}
.can-link-eg{color:var(--amber)}
@media (max-width:560px){
  .can-grid{grid-template-columns:repeat(2,1fr);gap:.6rem}
  .can-card{padding:.8rem}
  .can-note{display:none}   /* phones get the object and the facts */
}

/* ------------------------------------------------------- the taproom flight */
/* flight.html — four glasses on a cedar paddle (js/flight.js). The stage is
   one WebGPU canvas; the fallback is the same flight in CSS clothes. */
.fl-card{padding:clamp(1rem,2vw,1.5rem);display:grid;gap:.7rem}
.fl-stage{position:relative;width:100%;cursor:grab;touch-action:pan-y}
.fl-stage:active{cursor:grabbing}
.fl-gl{display:block;width:100%;height:auto}
.fl-hint{font-size:.54rem;letter-spacing:.2em;color:var(--ink-faint);justify-self:center}
.fl-fallback{display:none;grid-template-columns:repeat(4,1fr);gap:1rem;padding:1.4rem .6rem 1rem}
.fl-flat .fl-fallback{display:grid}
.fl-flat .fl-gl{display:none}
.fl-flat .fl-stage{cursor:default}
.fl-fb{display:grid;gap:.5rem;justify-items:center}
.fl-fbglass{
  width:70%;aspect-ratio:5/8;border-radius:4px 4px 8px 8px;
  border:2px solid rgba(20,28,30,.18);border-top:12px solid #f2ecdd;
  box-shadow:inset 0 0 18px rgba(255,255,255,.25), 0 10px 18px rgba(20,28,30,.18);
}
.fl-fb .mono{font-size:.52rem;letter-spacing:.14em;color:var(--ink-dim);text-align:center}
.fl-rail{display:flex;flex-wrap:wrap;gap:.5rem;margin:1.2rem 0}
.fl-pill{
  display:inline-flex;align-items:center;gap:.5rem;
  padding:.55rem .85rem;font-size:.56rem;letter-spacing:.14em;
}
.fl-pill .fl-dot{width:.7rem;height:.7rem;border-radius:50%;box-shadow:inset 0 0 3px rgba(0,0,0,.35)}
.fl-pill .fl-slot{color:var(--amber)}
.fl-pill.is-on{color:var(--ink);box-shadow:0 0 0 1px var(--amber) inset}
.fl-pill:focus-visible{outline:2px solid var(--amber);outline-offset:3px;border-radius:6px}
@media (max-width:560px){
  .fl-rail{gap:.35rem}
  .fl-pill{padding:.45rem .6rem;font-size:.5rem}
}

/* ---------------------------------------------------------- the heritage climb */
/* heritage.html — a fixed raymarched-terrain canvas under a scrolling story
   (js/heritage.js). Stations are glass cards; registers stamp a passport. */
.hz-holder,.hz-holder .hz-gl{position:fixed;inset:0;z-index:0}
.hz-holder .hz-gl{width:100%;height:100%;display:block}
.hz-flatplate{display:none;position:fixed;inset:0;z-index:0}
.hz-flatplate img{width:100%;height:100%;object-fit:cover}
.hz-flat .hz-flatplate{display:block}
.hz-flat .hz-holder{display:none}
.hz-main{position:relative;z-index:4;max-width:880px;margin:0 auto;
  padding:clamp(6rem,14vh,9rem) clamp(1.2rem,4vw,2.5rem) 1.5rem}
.hz-station{min-height:120vh;display:grid;align-content:center}
.hz-summit{min-height:140vh}
.hz-copy{padding:clamp(1.4rem,2.6vw,2.1rem);max-width:34rem;display:grid;gap:.9rem}
.hz-copy .display{margin:.2rem 0}
.hz-hint{font-size:.54rem;letter-spacing:.2em;color:var(--ink-faint)}
.hz-cachewrap{min-height:58vh;display:grid;align-content:center;justify-content:end}
.hz-cache{
  display:grid;gap:.3rem;justify-items:start;text-align:left;
  padding:.9rem 1.15rem;max-width:19rem;cursor:pointer;
}
.hz-cache .mono{font-size:.5rem;letter-spacing:.2em;color:var(--ink-faint)}
.hz-cache strong{font-size:.95rem;color:var(--ink)}
.hz-cache em{font-style:normal;font-size:.72rem;line-height:1.5;color:var(--ink-dim)}
.hz-cache.is-stamped{box-shadow:0 0 0 1px var(--amber) inset}
.hz-cache.is-stamped .mono::after{content:' · STAMPED';color:var(--amber)}
.hz-cache:focus-visible{outline:2px solid var(--amber);outline-offset:3px;border-radius:8px}
.hz-pass{
  position:fixed;left:clamp(1rem,3vw,2.4rem);bottom:clamp(1rem,3vw,2rem);
  z-index:12;padding:.7rem .9rem;display:grid;gap:.45rem;
}
.hz-pass .mono{font-size:.52rem;letter-spacing:.18em;color:var(--ink-dim)}
.hz-dots{display:flex;gap:.35rem}
.hz-dot{width:.72rem;height:.72rem;border-radius:50%;background:transparent;
  box-shadow:0 0 0 1.5px var(--ink-faint) inset;transition:background .5s,box-shadow .5s}
.hz-dot.is-got{background:var(--bc);box-shadow:0 0 0 1.5px var(--amber) inset}
.hz-doorwrap .hz-doorlink{display:none;margin-top:.4rem}
.hz-doorwrap.is-open .hz-doorlink{display:inline-flex}
.hz-doorwrap.is-open .hz-doorhint{display:none}
.hz-doorhint{font-size:.54rem;letter-spacing:.18em;color:var(--ink-faint)}
@media (max-width:640px){
  .hz-cachewrap{justify-content:center}
  .hz-pass{left:.7rem;bottom:.7rem;padding:.5rem .7rem}
}

/* ------------------------------------------------------------------ the bead */
/* The cursor is condensation (js/cursor.js): a water bead with a specular,
   an iron-green shadowed belly, one amber glint for the brand, and a lens
   of backdrop blur. It spreads to wet interactive things (::after is the
   meniscus ring) and squashes under the press. Paint, never furniture. */
html.bead, html.bead *{cursor:none}
.bead-dot,.bead-tail{
  position:fixed;top:0;left:0;pointer-events:none;z-index:999;
  will-change:transform;transition:opacity .4s;
}
.bead-dot{
  width:18px;height:18px;margin:-9px 0 0 -9px;border-radius:50%;
  background:
    radial-gradient(circle at 68% 74%, rgba(201,138,43,.30), transparent 34%),
    radial-gradient(circle at 32% 26%, rgba(255,255,255,.95),
      rgba(255,255,255,.30) 30%, rgba(190,215,225,.12) 55%,
      rgba(110,140,150,.20) 80%, rgba(110,140,150,0) 96%);
  box-shadow:
    inset -1px -2px 3px rgba(70,100,110,.28),
    inset 1px 1px 2px rgba(255,255,255,.85),
    0 2px 6px rgba(20,28,30,.14);
  -webkit-backdrop-filter:blur(2px) saturate(170%) brightness(1.05);
  backdrop-filter:blur(2px) saturate(170%) brightness(1.05);
}
.bead-dot::after{
  content:"";position:absolute;inset:-6px;border-radius:50%;
  border:1px solid rgba(255,255,255,.55);
  opacity:0;transform:scale(.6);
  transition:opacity .35s,transform .45s cubic-bezier(.16,1,.3,1);
}
.bead-dot.is-hover::after{opacity:.6;transform:none}
.bead-tail{
  width:7px;height:7px;margin:-3.5px 0 0 -3.5px;border-radius:50%;opacity:.5;
  background:radial-gradient(circle at 35% 30%, rgba(255,255,255,.85),
    rgba(170,200,210,.28) 60%, transparent 85%);
}
.bead-dot.is-hidden,.bead-tail.is-hidden{opacity:0}
[data-dark] .bead-dot{
  box-shadow:
    inset -1px -2px 3px rgba(0,0,0,.42),
    inset 1px 1px 2px rgba(255,255,255,.6),
    0 2px 8px rgba(0,0,0,.4);
}
@media (pointer:coarse){.bead-dot,.bead-tail{display:none}}

@media (prefers-reduced-motion:reduce){
  .reveal{opacity:1;transform:none;transition:none}
  .hint{animation:none}
  .cross-b,.cross-c{opacity:1;transform:none}
  .can-card{transition:none}
  .cg-live .can-card:not(.can-card--draft):hover{transform:none}
}
