/* ============================================================
   K-STOP — Korean Mart & DIY Ramyeon Nook
   Palette pulled from the storefront: lacquer black, signage
   red, warm bulb amber, and the cream of the in-store posters.
   ============================================================ */

:root{
  --ink:#0d0b0a;
  --ink-2:#191413;
  --ink-3:#2a211f;
  --red:#e0231f;
  --red-dark:#b0140f;
  /* Hero and nav only — the signage red, held one notch cleaner than
     the site red so the black hero reads as a single flat surface. */
  --noir:#0a0a0a;
  --k-red:#e21b1b;
  --k-red-dark:#b81212;
  --amber:#f0a52a;
  --cream:#f6efe2;
  --cream-2:#efe4d2;
  --paper:#fffdf9;
  --muted:#6d635c;
  --muted-light:#b8ada4;
  --line:rgba(13,11,10,.12);
  --line-light:rgba(246,239,226,.16);

  --display:"Archivo Black","Arial Black",Impact,sans-serif;
  --body:"Inter",system-ui,-apple-system,"Segoe UI",sans-serif;

  --wrap:1180px;
  --nav-h:76px;
  --r:16px;
  --shadow:0 24px 60px -28px rgba(13,11,10,.45);
}

*,*::before,*::after{box-sizing:border-box}

/* Reserve the scrollbar so locking the body for the lightbox
   doesn't shift the layout sideways. */
html{scroll-behavior:smooth;scroll-padding-top:88px;scrollbar-gutter:stable}

/* When the JS smooth scroller is running it owns the easing —
   native smooth would fight it and stutter. Anchor jumps are
   routed through the same lerp instead. */
html.has-smooth{scroll-behavior:auto}

body{
  margin:0;
  font-family:var(--body);
  font-size:17px;
  line-height:1.65;
  color:var(--ink);
  background:var(--paper);
  -webkit-font-smoothing:antialiased;
}
/* overflow:hidden alone does not hold the document scroller on iOS
   Safari: the page went on scrolling behind the open lightbox, and
   closing it left you somewhere else on the page. Pinning the body
   and offsetting it by the scroll position does hold — script.js
   sets `top` on lock and restores the position on release. */
body.is-locked{
  position:fixed;
  left:0;right:0;
  width:100%;
  overflow:hidden;
  overscroll-behavior:contain;
}

img{max-width:100%;display:block}
a{color:inherit}

h1,h2,h3,h4{font-family:var(--display);font-weight:400;line-height:1.03;letter-spacing:-.02em;margin:0}

.wrap{width:min(100% - 2.5rem,var(--wrap));margin-inline:auto}

.skip{
  position:absolute;left:-9999px;top:0;z-index:300;
  background:var(--red);color:#fff;padding:.75rem 1.25rem;border-radius:0 0 8px 0;
}
.skip:focus{left:0}

/* Visible to screen readers and crawlers, not to sighted users.
   Clip-based rather than display:none so it stays in the a11y tree. */
.sr-only{
  position:absolute;
  width:1px;height:1px;
  padding:0;margin:-1px;
  overflow:hidden;
  clip-path:inset(50%);
  white-space:nowrap;
  border:0;
}

:focus-visible{outline:3px solid var(--amber);outline-offset:3px;border-radius:4px}

/* ─────────────── Buttons ─────────────── */

.btn{
  --btn-bg:var(--red);
  --btn-fg:#fff;
  display:inline-flex;align-items:center;justify-content:center;
  gap:.5rem;
  background:var(--btn-bg);color:var(--btn-fg);
  font-weight:700;font-size:.95rem;letter-spacing:.01em;
  text-decoration:none;
  padding:.7rem 1.35rem;
  border:2px solid var(--btn-bg);
  border-radius:999px;
  transition:transform .18s ease, background .18s ease, border-color .18s ease, color .18s ease;
  white-space:nowrap;
}
.btn:hover{background:var(--red-dark);border-color:var(--red-dark);transform:translateY(-2px)}
.btn--sm{padding:.5rem 1.05rem;font-size:.85rem}
.btn--lg{padding:.95rem 1.9rem;font-size:1rem}
/* The hover fill and the hover label are two separate variables on
   purpose: `background:currentColor` alongside `color:...` resolves
   both to the same value, so the label vanished into the fill. */
.btn--ghost{
  --btn-bg:transparent;
  --btn-fg:currentColor;
  --ghost-fill:var(--ink);
  --ghost-ink:var(--paper);
  border-color:currentColor;
}
.btn--ghost:hover{
  background:var(--ghost-fill);
  border-color:var(--ghost-fill);
  color:var(--ghost-ink);
  transform:translateY(-2px);
}
/* On black the fill inverts: cream plate, ink label. */
.section--dark .btn--ghost, .hero .btn--ghost{--ghost-fill:var(--cream);--ghost-ink:var(--ink)}

/* ─────────────── Nav ─────────────── */

/* Nothing behind the bar over the hero — it sits on flat black, so
   it starts invisible and turns solid (not frosted) past the fold. */
.nav{
  position:sticky;top:0;z-index:100;
  background:transparent;
  border-bottom:1px solid transparent;
  transition:background .3s ease, border-color .3s ease;
}
.nav.is-stuck{background:var(--noir);border-bottom-color:var(--line-light)}

.nav__inner{display:flex;align-items:center;gap:1.5rem;min-height:76px}

.brand{display:flex;align-items:center;gap:.7rem;text-decoration:none;color:var(--cream);margin-right:auto;min-width:0}
.brand img{width:44px;height:44px;border-radius:50%;flex:none}
.brand span{display:flex;flex-direction:column;line-height:1.15;min-width:0}
.brand strong{font-family:var(--display);font-size:1.15rem;letter-spacing:.01em}
/* Nowrap keeps the tagline on one line — a few px of flex pressure
   would otherwise fold it in two inside the 76px bar. If it ever does
   run short of room it truncates rather than growing the bar. */
.brand small{
  font-size:.66rem;text-transform:uppercase;letter-spacing:.14em;color:var(--muted-light);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}

.nav__links{display:flex;gap:2rem}
.nav__links a{
  color:var(--cream);text-decoration:none;font-size:.88rem;font-weight:500;
  padding-bottom:2px;border-bottom:2px solid transparent;transition:border-color .2s ease,color .2s ease;
  /* Without this, a tight bar shrinks the flex items and breaks labels
     mid-phrase ("How / It / Works") rather than overflowing visibly. */
  white-space:nowrap;
}
.nav__links a:hover{border-bottom-color:var(--k-red);color:#fff}

.nav .btn--sm{--btn-bg:var(--k-red)}
.nav .btn--sm:hover{background:var(--k-red-dark);border-color:var(--k-red-dark)}

/* Only rendered inside the collapsed dropdown. */
.nav__cta{display:none}

.nav__toggle{
  display:none;
  width:44px;height:44px;
  background:none;border:0;cursor:pointer;
  flex-direction:column;justify-content:center;gap:5px;padding:0 10px;
}
.nav__toggle span{display:block;height:2px;background:var(--cream);border-radius:2px;transition:transform .25s ease,opacity .2s ease}
.nav__toggle[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.nav__toggle[aria-expanded="true"] span:nth-child(2){opacity:0}
.nav__toggle[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

/* ─────────────── Hero ───────────────
   Flat matte black, two columns, no chrome: no card, no frosting,
   no gradient wash. The headline carries the weight, the photo says
   what the room is, and the cue at the foot points at the build
   section — which is where the actual storytelling happens.
   ──────────────────────────────────── */

.hero{
  --hero-dim:#8b8079;
  position:relative;
  min-height:min(100vh,940px);
  min-height:min(100svh,940px);
  display:flex;flex-direction:column;
  /* Slides under the transparent bar, then pads back past it. */
  margin-top:calc(var(--nav-h) * -1);
  padding:calc(clamp(2.5rem,5vw,4rem) + var(--nav-h)) 0 clamp(1.75rem,3vw,2.5rem);
  background:var(--noir);
  color:var(--cream);
  overflow:hidden;
}

/* Storefront behind the hero, held down to texture rather than a
   picture: 16% opacity, half the colour pulled out so it can't
   compete with the red or with the neon plate, and enough blur that
   the signage stops resolving into words behind the nav. What is
   left is tonal structure — the black is no longer flat, and that
   is the whole job. Heavier at the top and bottom so the bar and
   the cue still sit on something even. */
.hero__bg{position:absolute;inset:0}
.hero__bg img{
  width:100%;height:100%;
  object-fit:cover;object-position:center 38%;
  opacity:.70;
  filter:grayscale(.55) blur(3px);
  /* The blur samples past the edges and leaves a soft border. */
  transform:scale(1.03);
}
.hero__bg::after{
  content:"";position:absolute;inset:0;
  background:
    radial-gradient(120% 85% at 12% 45%, rgba(10,10,10,.9) 0%, rgba(10,10,10,.55) 50%, rgba(10,10,10,.2) 100%),
    /* Held near-solid through the first 18% — that band is where the
       storefront's own signage sits, and it was still resolving into
       words right behind the wordmark in the bar. */
    linear-gradient(to bottom, rgba(10,10,10,.98) 0%, rgba(10,10,10,.93) 18%, rgba(10,10,10,.45) 50%, rgba(10,10,10,.98) 100%);
}

/* Weighted toward the copy: the headline is the widest thing on the
   page and the photo reads fine as a narrow portrait plate. Both
   columns share the body wrap so the hero lines up with the nav. */
.hero__grid{
  position:relative;z-index:1;
  flex:1;
  display:grid;
  grid-template-columns:minmax(0,1.12fr) minmax(0,.72fr);
  align-items:center;
  gap:clamp(2.5rem,6vw,5.5rem);
}

/* No max-width — the grid column is the measure. */
.hero__copy{min-width:0}

.hero__eyebrow{
  margin:0 0 clamp(1.5rem,3vw,2.25rem);
  font-size:.7rem;font-weight:600;
  text-transform:uppercase;letter-spacing:.24em;
  color:var(--muted-light);
}
/* Hangul doesn't take tracking the way the Latin does — it just
   falls apart. Reset it and let the red carry the emphasis. */
.hero__eyebrow span{
  color:var(--k-red);
  letter-spacing:.02em;
  margin-right:.7em;
}

/* Ceiling set by the longer line: "Korean Ramyeon." in Archivo Black
   at 4.15rem measures ~605px against a ~666px column, so it holds its
   own break rather than wrapping to three ragged lines. Raising this
   without widening the column splits the headline. */
.hero h1{
  font-size:clamp(2.85rem,5vw,4.15rem);
  line-height:.95;
  letter-spacing:-.035em;
  margin:0 0 clamp(1.4rem,2.5vw,1.9rem);
}
.h1__display{display:block}
.hero h1 em{color:var(--k-red);font-style:normal}

.lede{
  font-size:clamp(1.02rem,1.35vw,1.16rem);
  line-height:1.65;
  color:var(--muted-light);
  margin:0 0 clamp(2rem,3.5vw,2.75rem);
  /* Three lines, no orphan. At 32ch it broke to four and left
     "station." alone on the last one. */
  max-width:46ch;
}

.hero__cta{display:flex;flex-wrap:wrap;gap:.85rem;margin:0}
.hero .btn{--btn-bg:var(--k-red)}
.hero .btn:hover{background:var(--k-red-dark);border-color:var(--k-red-dark)}
/* Only the fill needs restating here — .hero .btn:hover above would
   otherwise repaint the ghost button red. */
.hero .btn--ghost{--btn-bg:transparent}
.hero .btn--ghost:hover{background:var(--ghost-fill);border-color:var(--ghost-fill)}

/* The frame is the picture — no border, no radius, nothing floating
   over it. 4:5 crops the 2:3 original to a magazine plate, and the
   svh cap keeps the whole hero — cue included — on one screen: on a
   short window the plate simply crops squarer rather than pushing
   the scroll cue below the fold.

   Every ratio used here is wider than the source's 2:3, so cover
   always scales to the width and trims the height — the horizontal
   half of object-position never does anything. 52% biases the trim
   toward the ceiling so the neon sign and the row of cook stations
   stay in frame however square the plate gets. */
.hero__media{margin:0}
.hero__media img{
  width:100%;
  aspect-ratio:4/5;
  max-height:min(58svh,600px);
  object-fit:cover;
  object-position:center 52%;
}
.hero__media figcaption{
  margin-top:1.1rem;
  font-size:.66rem;font-weight:600;
  text-transform:uppercase;letter-spacing:.18em;
  color:var(--hero-dim);
}

.hero__scroll{
  position:relative;z-index:1;
  align-self:center;
  display:inline-flex;align-items:center;gap:.8rem;
  margin-top:clamp(2.25rem,4.5vw,3.5rem);
  text-decoration:none;
  font-size:.7rem;font-weight:600;
  text-transform:uppercase;letter-spacing:.22em;
  color:var(--hero-dim);
  transition:color .25s ease;
}
.hero__scroll:hover{color:var(--cream)}
.hero__arrow{
  font-size:.95rem;letter-spacing:0;
  animation:hero-bob 2.6s ease-in-out infinite;
}
@keyframes hero-bob{
  0%,100%{transform:translateY(-2px)}
  50%{transform:translateY(3px)}
}

/* ---- Hero entrance ----
   Held back until the intro cover clears, so a first-time visitor
   doesn't spend it behind a full-screen video. script.js puts
   .hero-ready on <html>; without JS the .js gate never applies and
   everything is simply visible. */
.js .hero__copy > *,
.js .hero__media,
.js .hero__scroll{opacity:0}
.js .hero__copy > *{transform:translateY(20px)}
.js .hero__media{transform:scale(1.045)}

.hero-ready .hero__copy > *,
.hero-ready .hero__media,
.hero-ready .hero__scroll{
  opacity:1;transform:none;
  transition:opacity .9s ease, transform 1.1s cubic-bezier(.22,.61,.36,1);
}
.hero-ready .hero__media{transition-delay:.08s}
.hero-ready .hero__eyebrow{transition-delay:.05s}
.hero-ready .hero h1{transition-delay:.14s}
.hero-ready .hero .lede{transition-delay:.26s}
.hero-ready .hero__cta{transition-delay:.38s}
.hero-ready .hero__scroll{transition-delay:.6s}

/* ─────────────── Sections ─────────────── */

.section{padding:clamp(4.5rem,10vw,7.5rem) 0}
.section--cream{background:var(--cream)}
.section--dark{background:var(--ink);color:var(--cream)}

.head{max-width:640px;margin-bottom:3.5rem}
.head h2{font-size:clamp(2.1rem,5vw,3.4rem);margin-bottom:1rem}
.head .sub{margin:0;font-size:1.05rem;color:var(--muted);line-height:1.6}
.head--light .sub{color:var(--muted-light)}

.kicker{
  margin:0 0 .9rem;
  font-size:.72rem;font-weight:700;text-transform:uppercase;letter-spacing:.2em;
  color:var(--red);
}
.section--dark .kicker{color:var(--amber)}

/* ─────────────── Cards ─────────────── */

.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:1.25rem}

.card{
  position:relative;
  background:var(--paper);
  border:1px solid var(--line);
  border-radius:var(--r);
  padding:2.25rem 1.75rem 1.9rem;
  transition:transform .22s ease, box-shadow .22s ease, border-color .22s ease;
}
.card:hover{transform:translateY(-4px);box-shadow:var(--shadow);border-color:transparent}
.card__no{
  display:block;
  font-family:var(--display);font-size:.85rem;letter-spacing:.1em;
  color:var(--red);margin-bottom:1rem;
}
.card h3{font-size:1.32rem;margin-bottom:.7rem}
.card p{margin:0;font-size:.96rem;color:var(--muted);line-height:1.6}

/* ─────────────── Intro ───────────────
   Full-screen once-per-session cover. Light background for the
   same reason as the build section: the footage sits on white,
   so multiply erases it.
   ───────────────────────────────────── */

.intro{
  position:fixed;inset:0;z-index:500;
  background:#fbf7ef;
  display:grid;
  grid-template-rows:1fr auto;
  place-items:center;
  padding:clamp(1.25rem,4vw,2.5rem);
  transition:opacity .7s ease, visibility .7s ease;
}
.intro__inner{
  display:flex;flex-direction:column;align-items:center;
  justify-content:center;
  gap:.25rem;
  max-width:100%;
}
.intro__video{
  width:min(62vw,min(58vh,520px));
  height:auto;
  aspect-ratio:1/1;
  object-fit:contain;
  mix-blend-mode:multiply;
}
.intro__word{
  margin:.25rem 0 0;
  font-family:var(--display);
  font-size:clamp(1.6rem,5vw,2.6rem);
  letter-spacing:.02em;
  color:var(--ink);
}
.intro__tag{
  margin:0;
  font-size:clamp(.62rem,1.8vw,.72rem);
  font-weight:700;text-transform:uppercase;letter-spacing:.28em;
  color:var(--red);
}
.intro__skip{
  justify-self:center;
  background:transparent;
  border:1px solid rgba(13,11,10,.2);
  border-radius:999px;
  padding:.5rem 1.35rem;
  font-family:var(--body);font-size:.78rem;font-weight:600;
  letter-spacing:.08em;
  color:var(--muted);
  cursor:pointer;
  transition:background .2s ease,color .2s ease,border-color .2s ease;
}
.intro__skip:hover{background:var(--ink);border-color:var(--ink);color:var(--cream)}

/* Dismissed — faded out and pulled from the a11y tree. */
.intro.is-done{opacity:0;visibility:hidden;pointer-events:none}

/* Returning visitor this session, or no motion wanted: never show it. */
.intro-seen .intro{display:none}
@media (prefers-reduced-motion:reduce){
  .intro{display:none}
}

/* ─────────────── Scroll-scrubbed build ───────────────
   Scroll position drives video.currentTime. The section is light
   on purpose: the footage is a bowl on pure white, so multiply
   blending erases the background for free.
   ───────────────────────────────────────────────────── */

.section--build{
  background:#fbf7ef;
  color:var(--ink);
}

.build{
  --run:420vh;
  position:relative;
  /* Matches the svh-sized pin below, so the section is exactly one
     pinned screen plus the run. In vh it reserved a URL bar's worth
     of extra height at the end, where the build sat finished and
     frozen while the page kept scrolling. */
  height:calc(100vh + var(--run));
  height:calc(100svh + var(--run));
}
.build__sticky{
  position:sticky;
  /* The nav is sticky at top:0 and 76px tall, so it sits over the
     first 76px of anything pinned behind it. On desktop the centred
     content cleared it by chance; on a phone, where the content fills
     the pin, it hid the top half of the video. */
  top:var(--nav-h);
  /* svh, not vh: on mobile 100vh resolves to the viewport with the
     browser chrome *hidden*, so with the URL bar showing the pinned
     content was ~90px taller than the visible area and overflow:hidden
     silently ate the top of the video and the closing note. */
  height:calc(100vh - var(--nav-h));
  height:calc(100svh - var(--nav-h));
  display:grid;
  grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
  align-items:center;
  gap:clamp(1.5rem,5vw,4rem);
  width:min(100% - 2.5rem,var(--wrap));
  margin-inline:auto;
  overflow:hidden;
}

/* Sized to the footage's own 1:1 ratio rather than to the column, so
   the box *is* the picture. Previously the stage was taller than the
   contained frame and anything pinned to its bottom-left — the scroll
   cue — floated in the letterbox below the image. */
.build__stage{
  display:grid;place-items:center;
  position:relative;
  width:min(100%,78vh,660px);
  aspect-ratio:1;
  margin-inline:auto;
}
.build__video{
  width:100%;height:100%;
  object-fit:contain;
  /* Kills the white backdrop against the light section. */
  mix-blend-mode:multiply;
}

.build__side{max-width:30em}
.build__title{
  font-size:clamp(1.9rem,4.2vw,3rem);
  margin-bottom:1.75rem;
}
.build__title em{color:var(--red);font-style:normal}

.build__steps{
  list-style:none;margin:0 0 2rem;padding:0;
  counter-reset:build;
}
.build__steps li{
  display:flex;align-items:baseline;gap:.85rem;
  padding:.6rem 0;
  font-size:clamp(.95rem,1.6vw,1.08rem);
  color:#a89d93;
  border-bottom:1px solid rgba(13,11,10,.08);
  transition:color .3s ease, transform .3s ease;
}
.build__steps li:last-child{border-bottom:0}
.build__steps li span{
  flex:none;
  min-width:2.6em;
  font-weight:700;font-size:.82em;
  color:#c9beb2;
  transition:color .3s ease;
}
/* Beats already reached */
.build__steps li.is-done{color:#6d635c}
.build__steps li.is-done span{color:var(--red)}
/* The beat currently on screen */
.build__steps li.is-now{
  color:var(--ink);font-weight:600;
  transform:translateX(4px);
}
.build__steps li.is-now span{color:var(--red)}

.build__note{
  margin:0;font-size:.92rem;font-style:italic;color:var(--muted);
}

/* ---- Scroll cue ----
   Sits in the bottom-left of the video stage. The bowl only builds
   as you scroll, and until you do the section looks like a static
   picture — this is the only thing telling you otherwise. */

.scroll-cue{
  position:absolute;left:1rem;bottom:1rem;z-index:2;
  display:flex;flex-direction:column;align-items:flex-start;gap:.6rem;
  margin:0;
  pointer-events:none;
}

.scroll-cue__line{
  position:relative;
  width:1px;height:46px;
  background:linear-gradient(to bottom,rgba(13,11,10,.06),rgba(13,11,10,.22));
  overflow:hidden;
}
/* A bead running the length of the line, in the signage red. */
.scroll-cue__line::after{
  content:"";
  position:absolute;left:-1px;top:0;
  width:3px;height:14px;border-radius:2px;
  background:var(--red);
  animation:cue-run 2.1s cubic-bezier(.65,0,.35,1) infinite;
}
@keyframes cue-run{
  0%  {transform:translateY(-16px);opacity:0}
  20% {opacity:1}
  70% {opacity:1}
  100%{transform:translateY(48px);opacity:0}
}

.scroll-cue__text{
  font-size:.62rem;font-weight:700;
  text-transform:uppercase;letter-spacing:.24em;
  color:var(--muted);
  white-space:nowrap;
}
.scroll-cue__text span{color:var(--red);margin-right:.2rem}

/* Unpinned (reduced motion, no JS, short screens): there is no scrub
   to prompt, so the cue would be misleading. */
.build.is-static .scroll-cue{display:none}

@media (prefers-reduced-motion:reduce){
  .scroll-cue__line::after{display:none}
}

/* Reduced motion / no JS: no pin, poster frame, all copy readable. */
.build.is-static{height:auto}
.build.is-static .build__sticky{position:static;height:auto;padding:4rem 0}
.build.is-static .build__steps li{color:var(--ink)}
.build.is-static .build__steps li span{color:var(--red)}

@media (max-width:900px){
  .build{--run:300vh}
  .build__sticky{
    grid-template-columns:1fr;
    /* The copy takes the height it needs and the video absorbs
       whatever is left. A fixed vh for the stage can't work here —
       the copy block is a different fraction of the viewport on every
       phone, so any constant either clips or leaves a hole. */
    grid-template-rows:minmax(0,1fr) auto;
    align-content:stretch;
    /* The base rule centres items in their track; with the video out
       of flow that left the stage at 0 height. Stretch fills it. */
    align-items:stretch;
    gap:1rem;
    text-align:center;
  }
  /* Sized by the grid row above. The video is taken out of flow so its
     1:1 intrinsic ratio stops propping the track open — in flow it
     reported a 335px min-content height and overflowed the pin by 88px
     no matter what the track said. Absolute + contain lets it fill
     whatever the row ends up being. */
  /* Height comes from the grid row; the 1:1 ratio then derives the
     width, and justify-self stops the stretch from overriding it. */
  .build__stage{
    height:100%;width:auto;max-width:100%;
    min-height:0;justify-self:center;
  }
  .build__video{position:absolute;inset:0}
  .build__side{max-width:none;margin-inline:auto}
  .build__title{font-size:clamp(1.5rem,5.5vw,2rem);margin-bottom:.9rem}
  .build__steps{margin-bottom:1rem}
  .build__steps li{
    justify-content:center;
    padding:.34rem 0;
    font-size:.94rem;
  }
  .build__steps li span{min-width:0;margin-right:.2rem}
  .build__note{font-size:.85rem}

  /* The stage is only ~160px tall on a small phone — a 46px line plus
     text would own a third of it. */
  .scroll-cue{gap:.4rem;left:.7rem;bottom:.7rem}
  .scroll-cue__line{height:26px}
  .scroll-cue__text{font-size:.56rem;letter-spacing:.2em}
  @keyframes cue-run{
    0%  {transform:translateY(-14px);opacity:0}
    20% {opacity:1}
    70% {opacity:1}
    100%{transform:translateY(28px);opacity:0}
  }
}

/* Short phones: once the nav's 76px comes off the top there is only
   ~477px left, and the copy block alone was eating 385px of it —
   leaving an 84px thumbnail. The kicker repeats the heading and the
   note repeats the steps, so they give way to a legible picture.
   Taller phones (720px+) keep both. */
@media (max-width:900px) and (max-height:640px){
  .build__side .kicker{display:none}
  .build__note{display:none}
  .build__title{margin-bottom:.7rem}
  .build__steps{margin-bottom:.5rem}
  .build__steps li{padding:.2rem 0;font-size:.9rem}
}

/* Short viewports — landscape phones above all — can't hold the
   stacked layout at any sensible type size (638px of content against
   a 360px pin). Drop the pin and let the section scroll normally;
   this mirrors the reduced-motion fallback, and the video still
   scrubs as the section passes. */
@media (max-height:520px){
  .build{height:auto}
  .build__sticky{position:static;height:auto;padding:3rem 0}
  .build__stage{height:min(52vh,300px)}
  .build__steps li{color:var(--ink)}
  .build__steps li span{color:var(--red)}
  /* Unpinned here too — the page scrolls normally, so no cue. */
  .scroll-cue{display:none}
  /* Nothing is competing for a fixed viewport any more, so the copy
     the short-phone rule dropped comes back. */
  .build__side .kicker{display:block}
  .build__note{display:block}
}

/* ─────────────── Step cards ───────────────
   Six poster cards, all of them on screen at once.

   This was a pinned stage that took the page over and dealt one card
   per gesture. Readers hit it as the page having stopped: nothing said
   the scroll had been taken, nothing said how many cards were left,
   and on a phone the position indicator was switched off entirely.
   A grid has no hidden state to signal — every step is simply there,
   read by scrolling the page like everything else.

   Six across on a wide screen, three at 940 and two on a phone. The
   posters are small at six across, but they were never legible at
   deck size either: the label under each card carries the step, and
   one tap opens the poster full size in the lightbox.
   ───────────────────────────────────────── */

.steps{
  list-style:none;
  margin:3rem 0 0;
  padding:0;
  display:grid;
  grid-template-columns:repeat(6,1fr);
  gap:1.75rem 1rem;
}

.fcard{
  display:flex;
  flex-direction:column;
  gap:.8rem;
  width:100%;
  padding:0;
  background:none;
  border:0;
  text-align:left;
  cursor:pointer;
  -webkit-tap-highlight-color:transparent;
}

/* The frame the poster sits in. The border, radius and clipping live
   here rather than on the button so the label stays outside the card
   edge, and so the lift has something of its own to move. */
.fcard__inner{
  position:relative;display:block;
  width:100%;
  aspect-ratio:3/4;
  background:var(--ink-2);
  border:1px solid var(--line-light);
  border-radius:14px;
  overflow:hidden;
  transition:transform .28s cubic-bezier(.22,.61,.36,1),
             border-color .28s ease;
}
.fcard:hover .fcard__inner,
.fcard:focus-visible .fcard__inner{
  transform:translateY(-10px) scale(1.03);
  border-color:var(--amber);
}

/* The six posters come in three aspect ratios: 900x1439, 900x1350
   and 900x1200. `fill` stretches each one to the card box rather
   than cropping to it, so every card is the same size on screen and
   no poster loses its footer. The box is step 6's own 900x1200, so
   steps 5 and 6 are untouched; steps 2-4 stretch 12.5% wider and
   step 1 about 20%. The lightbox shows every poster undistorted.

   `cover` was the alternative and it cost more: it cropped the
   bottom sixth off step 1 entirely. */
.fcard img{
  width:100%;height:100%;
  min-width:0;min-height:0;
  object-fit:fill;
  background:#120e0d;
}

/* The step number and title, in the open rather than baked into the
   poster art — at this size the printed lettering is decoration, not
   copy anyone can read. The description stays in the lightbox. */
.fcard__label{display:block}
.fcard__no{
  display:block;
  margin-bottom:.25rem;
  font-family:var(--display);font-size:.92rem;letter-spacing:.06em;
  color:var(--amber);
}
.fcard__title{
  display:block;
  color:var(--cream);
  font-size:.95rem;font-weight:600;line-height:1.35;
}

/* Six across needs a desk. Below that the row folds rather than
   shrinking the posters into stamps — two on a phone still fits
   every step within a screen or so of ordinary scrolling. */
@media (max-width:940px){
  .steps{grid-template-columns:repeat(3,1fr);gap:2rem 1.25rem}
  .fcard__title{font-size:1rem}
}
@media (max-width:680px){
  .steps{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:420px){
  .steps{gap:1.5rem .9rem}
  .fcard__no{font-size:.85rem}
  .fcard__title{font-size:.9rem}
}

/* ─────────────── Lightbox ─────────────── */

.lightbox[hidden]{display:none}
.lightbox{
  position:fixed;inset:0;z-index:200;
  display:grid;place-items:center;
  padding:clamp(1rem,4vw,2.5rem);
}
.lightbox__backdrop{
  position:absolute;inset:0;
  background:rgba(8,6,6,.9);
  backdrop-filter:blur(8px);
  -webkit-backdrop-filter:blur(8px);
}
.lightbox__inner{
  position:relative;z-index:1;
  display:grid;
  grid-template-columns:auto minmax(0,300px);
  gap:clamp(1.5rem,4vw,3rem);
  align-items:center;
  max-width:min(100%,940px);
}
.lightbox__img{
  max-height:min(82vh,780px);
  width:auto;
  border-radius:12px;
  box-shadow:0 40px 90px -30px rgba(0,0,0,.9);
}
/* "Step 3 of 6" above the title. The step number carries the display
   face and the amber; the "of 6" is dropped back to small caps so the
   position reads as a footnote to it rather than part of the count. */
.lightbox__count{
  margin:0 0 .5rem;
  font-family:var(--display);font-size:.95rem;letter-spacing:.06em;
  color:var(--amber);
}
.lightbox__count span{
  font-family:var(--body);font-size:.7rem;font-weight:600;
  letter-spacing:.18em;text-transform:uppercase;
  color:var(--muted-light);margin-left:.35rem;
}
.lightbox__text h3{font-size:clamp(1.5rem,3.5vw,2.2rem);color:var(--cream);margin-bottom:.7rem}
.lightbox__text p:last-child{margin:0;color:var(--muted-light);line-height:1.6}
.lightbox__close{
  position:absolute;top:-.5rem;right:-.5rem;z-index:2;
  width:44px;height:44px;
  display:grid;place-items:center;
  background:var(--ink-2);color:var(--cream);
  border:1px solid var(--line-light);border-radius:50%;
  font-size:1.5rem;line-height:1;cursor:pointer;
  transition:background .2s ease,border-color .2s ease;
}
.lightbox__close:hover{background:var(--red);border-color:var(--red)}

/* Fallback entry when View Transitions aren't available. */
.lightbox:not(.is-vt) .lightbox__inner{animation:pop .3s cubic-bezier(.22,.61,.36,1) both}
@keyframes pop{
  from{opacity:0;transform:scale(.9) translateY(14px)}
  to{opacity:1;transform:none}
}

.notice{
  margin-top:3rem;padding:1.4rem 1.75rem;
  background:rgba(240,165,42,.1);
  border-left:4px solid var(--amber);
  border-radius:0 var(--r) var(--r) 0;
}
.notice p{margin:0;font-size:.95rem;color:#e6ddd0}
.notice strong{color:var(--amber)}

/* ─────────────── Bento / menu ─────────────── */

/* Sub-heading inside a section that already owns the <h2>. */
.menu-group{
  font-family:var(--body);font-weight:700;
  font-size:.78rem;text-transform:uppercase;letter-spacing:.16em;
  color:var(--red);
  padding-bottom:.85rem;margin-bottom:1.75rem;
  border-bottom:2px solid var(--line);
}
.menu-group__sub{margin:-1.25rem 0 1.75rem;font-size:.95rem;color:var(--muted)}

.bento{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:1.5rem;margin-bottom:4rem}

.bento__item{
  border:1px solid var(--line);
  border-radius:var(--r);
  overflow:hidden;
  background:var(--paper);
  transition:transform .22s ease, box-shadow .22s ease;
}
.bento__item:hover{transform:translateY(-4px);box-shadow:var(--shadow)}
.bento__img{aspect-ratio:4/5;overflow:hidden;background:var(--ink-2)}
.bento__img img{width:100%;height:100%;object-fit:cover;transition:transform .5s ease}
.bento__item:hover .bento__img img{transform:scale(1.04)}
.bento__body{padding:1.75rem}
.bento__body h3{font-size:1.4rem;margin-bottom:.55rem}
.bento__body p{margin:0;color:var(--muted);font-size:.96rem}
.price{
  margin-top:1rem !important;
  font-family:var(--display);font-size:1.6rem;color:var(--red) !important;
}

.picks{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:2rem 1.5rem}
.pick h4{
  font-family:var(--body);font-weight:700;
  font-size:.74rem;text-transform:uppercase;letter-spacing:.16em;
  color:var(--red);
  padding-bottom:.75rem;margin-bottom:1rem;
  border-bottom:2px solid var(--line);
}
.pick ul{list-style:none;margin:0;padding:0}
.pick li{
  padding:.5rem 0;font-size:.96rem;
  border-bottom:1px solid var(--line);
}
.pick li:last-child{border-bottom:0}
.pick li span{color:var(--muted);font-size:.84rem}

/* Shop posters. Every file is 3:4, so cover never actually crops —
   the ratio is set so the grid stays even while they lazy-load. */
/* Fixed track counts rather than auto-fit: there are exactly four
   posters, and auto-fit leaves an orphan on the middle widths. */
.posters{
  display:grid;
  grid-template-columns:repeat(4,1fr);
  gap:1rem;
  margin-bottom:4rem;
}
@media (max-width:680px){
  .posters{grid-template-columns:repeat(2,1fr)}
}
.poster{
  position:relative;margin:0;overflow:hidden;
  border-radius:var(--r);
  background:var(--ink-2);
  aspect-ratio:3/4;
  cursor:zoom-in;
  transition:transform .22s ease, box-shadow .22s ease;
}
.poster:hover{transform:translateY(-4px);box-shadow:var(--shadow)}
.poster:focus-visible{outline:3px solid var(--red);outline-offset:3px}
.poster img{width:100%;height:100%;object-fit:cover;transition:transform .6s ease}
.poster:hover img{transform:scale(1.04)}
.poster figcaption{
  position:absolute;left:0;right:0;bottom:0;
  padding:2.5rem 1.25rem 1rem;
  font-size:.82rem;font-weight:600;letter-spacing:.04em;color:#fff;
  background:linear-gradient(to top,rgba(13,11,10,.85),transparent);
}

.foot-note{margin:3rem 0 0;font-size:.9rem;color:var(--muted);font-style:italic}

/* ─────────────── Shop tour ───────────────
   The hero still is the way in. The button is a plain block wrapper so
   `.hero__media img` keeps every aspect ratio it had — the badge is the
   only thing added, and it sits on top of the photo rather than in the
   flow, so nothing below the hero moves by a pixel at any width. */

.hero__tour{
  display:block;position:relative;
  width:100%;padding:0;margin:0;
  border:0;background:none;cursor:pointer;
  color:inherit;font:inherit;
  -webkit-tap-highlight-color:transparent;
}
/* Only the bottom of the photo is darkened, so the neon sign at the top
   is still doing its job behind the label. */
.hero__tour::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(to top,rgba(10,10,10,.72),rgba(10,10,10,.06) 52%,transparent);
  pointer-events:none;
  transition:opacity .25s ease;
}

.hero__tour-badge{
  position:absolute;left:0;right:0;bottom:0;
  display:flex;align-items:center;gap:.7rem;
  padding:1rem;
  text-align:left;
}
.hero__tour-ring{
  width:44px;height:44px;flex:none;position:relative;
  border-radius:999px;
  background:var(--k-red);
  box-shadow:0 8px 24px -8px rgba(0,0,0,.8);
  transition:transform .22s ease, background .22s ease;
}
.hero__tour-ring::after{
  content:"";position:absolute;top:50%;left:50%;
  transform:translate(-40%,-50%);
  border-style:solid;
  border-width:8px 0 8px 13px;
  border-color:transparent transparent transparent #fff;
}
.hero__tour-text{display:grid;gap:.05rem;min-width:0}
.hero__tour-label{
  font-weight:700;font-size:.92rem;letter-spacing:.01em;color:#fff;
  text-shadow:0 1px 12px rgba(0,0,0,.5);
}
.hero__tour-meta{
  font-size:.72rem;letter-spacing:.1em;text-transform:uppercase;
  color:rgba(255,255,255,.72);
}

/* Hover is a desktop affordance; on touch the badge is already the
   whole story and :hover would stick after a tap. */
@media (hover:hover){
  .hero__tour:hover .hero__tour-ring{transform:scale(1.09);background:var(--k-red-dark)}
  .hero__tour:hover::after{opacity:.82}
}

/* ── Fullscreen player ──
   9:16 footage, so it gets the viewport rather than a column. The stage
   is inset by the safe area so the close button clears a notch and the
   video clears the iOS home indicator. */

.tourlb[hidden]{display:none}
.tourlb{
  position:fixed;inset:0;z-index:210;
  background:rgba(6,5,5,.96);
}
.tourlb__backdrop{position:absolute;inset:0}

.tourlb__stage{
  position:absolute;inset:0;
  display:flex;align-items:center;justify-content:center;
  padding:
    calc(env(safe-area-inset-top,0px) + 3.5rem)
    calc(env(safe-area-inset-right,0px) + .75rem)
    calc(env(safe-area-inset-bottom,0px) + .75rem)
    calc(env(safe-area-inset-left,0px) + .75rem);
}
/* max-* on both axes plus the ratio lets the box fit itself to whichever
   dimension runs out first — portrait phone, landscape phone, or a wide
   desktop window all land correctly with no breakpoints. */
.tourlb__video{
  max-width:100%;max-height:100%;
  aspect-ratio:9/16;
  width:auto;height:auto;
  object-fit:contain;
  background:#000;
  border-radius:12px;
}

.tourlb__close{
  position:absolute;
  top:calc(env(safe-area-inset-top,0px) + .5rem);
  right:calc(env(safe-area-inset-right,0px) + .5rem);
  width:44px;height:44px;
  display:grid;place-items:center;
  font-size:1.6rem;line-height:1;
  color:var(--cream);
  background:rgba(255,255,255,.1);
  border:1px solid var(--line-light);
  border-radius:999px;
  cursor:pointer;
  transition:background .2s ease, border-color .2s ease;
}
.tourlb__close:hover{background:var(--red);border-color:var(--red)}

/* Landscape phones have no vertical room to give away — drop the top
   padding back so the video keeps as much height as it can, and let the
   close button overlap the corner instead of reserving a band. */
@media (max-height:600px) and (orientation:landscape){
  .tourlb__stage{padding-top:calc(env(safe-area-inset-top,0px) + .5rem)}
}

/* ─────────────── Review prompt ───────────────
   A card parked in the corner, not an overlay: no backdrop, nothing
   dimmed, the page stays fully usable behind it. z-index sits under
   both the lightbox (200) and the tour (210) on purpose — if someone
   opens a poster while this is up, the poster wins and the prompt is
   simply covered rather than poking through it. */

.rev[hidden]{display:none}
.rev{
  position:fixed;z-index:150;
  right:calc(env(safe-area-inset-right,0px) + 1.25rem);
  bottom:calc(env(safe-area-inset-bottom,0px) + 1.25rem);
  width:min(22rem,calc(100vw - 2.5rem));
  padding:1.5rem 1.5rem 1.35rem;
  background:var(--ink-2);color:var(--cream);
  border:1px solid var(--line-light);
  border-radius:var(--r);
  box-shadow:0 28px 60px -20px rgba(6,5,5,.7);
  /* Held off-screen until the JS adds .is-in, so it never flashes in
     place on load. */
  opacity:0;transform:translateY(1rem);
  transition:opacity .38s ease, transform .38s cubic-bezier(.22,1,.36,1);
}
.rev.is-in{opacity:1;transform:none}

.rev__stars{
  display:flex;gap:.15rem;
  margin:0 0 .8rem;
  color:var(--amber);
}

.rev__title{
  font-family:var(--display);font-weight:400;
  font-size:1.35rem;line-height:1.15;
  margin:0 0 .5rem;
  /* The display face runs hot next to body copy at this size. */
  letter-spacing:-.01em;
}

.rev__copy{
  margin:0 0 1.25rem;
  font-size:.92rem;line-height:1.55;
  color:#d9cfc2;
}

.rev__actions{display:flex;align-items:center;gap:.4rem;flex-wrap:wrap}
.rev .btn{--btn-bg:var(--k-red);font-size:.9rem}
.rev .btn:hover{background:var(--k-red-dark);border-color:var(--k-red-dark)}

/* "Not now" is deliberately a quiet text button rather than a second
   .btn — two equal-weight pills would make declining feel like half
   the point of the card. */
.rev__later{
  padding:.7rem 1rem;
  font:inherit;font-size:.9rem;font-weight:600;
  color:var(--muted-light);
  background:none;border:0;border-radius:999px;
  cursor:pointer;
  transition:color .18s ease;
}
.rev__later:hover{color:var(--cream)}

.rev__close{
  position:absolute;top:.45rem;right:.45rem;
  width:36px;height:36px;
  display:grid;place-items:center;
  font-size:1.35rem;line-height:1;
  color:var(--muted-light);
  background:none;border:0;border-radius:999px;
  cursor:pointer;
  transition:color .18s ease, background .18s ease;
}
.rev__close:hover{color:var(--cream);background:rgba(255,255,255,.08)}

/* Full-width sheet on a phone. Squaring off the bottom corners lets it
   sit on the edge of the screen instead of floating a few pixels above
   it, which on a tall phone just wastes thumb-reachable space. */
@media (max-width:680px){
  .rev{
    right:0;left:0;bottom:0;
    width:auto;
    padding:1.35rem 1.25rem calc(env(safe-area-inset-bottom,0px) + 1.25rem);
    border-width:1px 0 0;
    border-radius:var(--r) var(--r) 0 0;
  }
  .rev__actions{gap:.25rem}
  .rev .btn{flex:1 1 auto}
}

/* The card still appears — it is information, not decoration — it just
   arrives without the slide. */
@media (prefers-reduced-motion:reduce){
  .rev{transition:opacity .01ms;transform:none}
}

/* ─────────────── Gallery ─────────────── */

.gallery{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(260px,1fr));
  grid-auto-rows:240px;
  gap:1rem;
}
.g{
  position:relative;margin:0;overflow:hidden;
  border-radius:var(--r);
  background:var(--ink-2);
}
.g--tall{grid-row:span 2}
.g img{width:100%;height:100%;object-fit:cover;transition:transform .6s ease}
.g:hover img{transform:scale(1.05)}
.g figcaption{
  position:absolute;left:0;right:0;bottom:0;
  padding:2.5rem 1.25rem 1rem;
  font-size:.82rem;font-weight:600;letter-spacing:.04em;color:#fff;
  background:linear-gradient(to top,rgba(13,11,10,.85),transparent);
}

/* ─────────────── Customer wall ───────────────
   Wider than the standard column so it reads as a room full of
   people rather than a tidy little gallery. */

/* Fixed 4 columns x 2 rows for 8 tiles — auto-fit plus row spans
   left holes in the grid and the whole thing read as ragged. */
.wall{
  display:grid;
  grid-template-columns:repeat(4,1fr);
  gap:.6rem;
  width:min(100% - 1.5rem,1400px);
  margin:0 auto 2rem;
}
.wall__item{
  position:relative;margin:0;overflow:hidden;
  aspect-ratio:4/3;
  border-radius:12px;
  background:var(--ink-2);
}
.wall__item img{
  width:100%;height:100%;
  object-fit:cover;
  transition:transform .6s cubic-bezier(.22,.61,.36,1);
}
.wall__item:hover img{transform:scale(1.045)}

/* A warm wash so the mixed phone-camera colour temperatures sit
   together instead of clashing. Lifts on hover. */
.wall__item::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(224,35,31,.06),rgba(13,11,10,.14));
  opacity:1;transition:opacity .4s ease;
  pointer-events:none;
}
.wall__item:hover::after{opacity:0}

/* Only 4 and 2 divide 8 tiles evenly — a 3-column step would leave
   a hole in the last row, which is what made this look ragged. */
@media (max-width:680px){
  .wall{grid-template-columns:repeat(2,1fr);gap:.45rem}
}

/* ─────────────── Visit ─────────────── */

.visit{display:grid;grid-template-columns:1fr 1fr;gap:4rem}
.visit__main h2{font-size:clamp(2.1rem,5vw,3.2rem);margin-bottom:1rem}
.visit__main .sub{color:var(--muted-light);margin:0 0 2rem;font-size:1.05rem}
.visit__main .btn{margin-right:.7rem;margin-bottom:.7rem}

.visit__info{margin:0;display:grid;gap:1.75rem}
.visit__info div{padding-bottom:1.75rem;border-bottom:1px solid var(--line-light)}
.visit__info div:last-child{border-bottom:0;padding-bottom:0}
.visit__info dt{
  font-size:.7rem;font-weight:700;text-transform:uppercase;letter-spacing:.18em;
  color:var(--amber);margin-bottom:.5rem;
}
.visit__info dd{margin:0;color:#e6ddd0;font-size:1rem;line-height:1.6}
.visit__info a{text-decoration:none;border-bottom:1px solid rgba(230,221,208,.35)}
.visit__info a:hover{color:var(--amber);border-color:var(--amber)}
.visit__info .row{display:flex;justify-content:space-between;gap:1.5rem;flex-wrap:wrap}

/* ─────────────── Footer ─────────────── */

.footer{background:var(--ink-2);color:var(--muted-light);padding:3.5rem 0;text-align:center}
.footer__inner{display:flex;flex-direction:column;align-items:center;gap:1rem}
.footer img{width:56px;height:56px;border-radius:50%}
.footer__tag{
  margin:0;font-family:var(--display);
  font-size:.85rem;letter-spacing:.24em;text-transform:uppercase;color:var(--amber);
}
.footer__meta{margin:0;font-size:.86rem;line-height:1.8}
.footer__meta a{color:var(--cream);text-decoration:none;border-bottom:1px solid var(--line-light)}
.footer__meta a:hover{color:var(--red)}

/* ─────────────── Reveal on scroll ─────────────── */

.reveal{opacity:0;transform:translateY(22px)}
.reveal.is-in{opacity:1;transform:none;transition:opacity .7s ease, transform .7s cubic-bezier(.22,.61,.36,1)}

/* ─────────────── Responsive ─────────────── */

@media (max-width:900px){
  .visit{grid-template-columns:1fr;gap:3rem}

  .lightbox__inner{
    grid-template-columns:1fr;
    justify-items:center;
    text-align:center;
    max-height:88vh;
    overflow-y:auto;
  }
  .lightbox__img{max-height:min(58vh,520px)}
  .lightbox__close{top:0;right:0}
}

/* The row is brand (297) + four links (~232 + 96 of gaps) + CTA (152)
   + two 24px gaps ≈ 825px, so with the 40px wrap gutter and the 15px
   reserved scrollbar it wants ~880px. Collapsing at 940px keeps a
   margin against font fallbacks without crushing the items — the
   band where flexbox silently breaks labels mid-phrase is the thing
   to stay clear of, not the exact measurement. */
@media (max-width:940px){
  .nav__toggle{display:flex}
  .nav__inner{gap:.75rem}
  .nav .btn--sm{display:none}

  .nav__links{
    position:absolute;top:100%;left:0;right:0;
    flex-direction:column;gap:0;
    background:var(--noir);
    border-bottom:1px solid var(--line-light);
    padding:.5rem 1.25rem 1.25rem;
    display:none;
  }
  .nav__links.is-open{display:flex}
  .nav__links a{padding:.85rem 0;border-bottom:1px solid var(--line-light)}
  .nav__links a:last-child{border-bottom:0}

  /* Carries the header CTA once the bar collapses. */
  .nav__cta{
    display:block;
    margin-top:1rem;
    background:var(--k-red);
    text-align:center;
    font-weight:700;
    border-radius:999px;
    padding:.85rem 1.25rem !important;
    border-bottom:0 !important;
  }
  .nav__cta:hover{background:var(--k-red-dark);color:#fff}
}

/* Below this the logo, wordmark and hamburger have the bar to
   themselves — the tagline can't fit beside them without truncating
   to nothing useful, and it already appears in the hero copy. */
@media (max-width:480px){
  .brand small{display:none}
}

/* ---- Hero on small and short screens ---- */

/* Two columns stop paying below this: at 6.4vw the headline is under
   55px and the photo column is too narrow to read as a room. Copy
   first, then the photo — the claim is what has to land, and the
   picture is a full screen-width plate right under it. */
@media (max-width:860px){
  .hero{min-height:0;padding-bottom:clamp(2rem,5vw,3rem)}

  .hero__grid{
    grid-template-columns:1fr;
    align-items:start;
    gap:clamp(2.5rem,7vw,3.5rem);
  }
  .hero__copy{max-width:32rem}
  /* "Korean Ramyeon." is 9.1em wide in Archivo Black at this
     tracking, so the size is pinned to whichever is smaller: 9.4% of
     the viewport, or what the 32rem copy column can take. Anything
     larger and the headline breaks into four lines and loses the
     "Build Your Own / Korean Ramyeon." break it is written around. */
  .hero h1{font-size:clamp(1.7rem,9vw,3.3rem)}
  .lede{max-width:38ch}
  .hero__media img{aspect-ratio:5/4}
  .hero__media figcaption{margin-top:.85rem}
}

/* Full-width buttons only once they'd otherwise sit alone on a row
   anyway — above this they still pair. */
@media (max-width:420px){
  .hero__cta{gap:.7rem}
  .hero__cta .btn{flex:1 1 100%}
}

/* The 9.4vw rule above already holds the headline together down to
   320px; what stops fitting here is the tracked-out small caps. */
@media (max-width:360px){
  .hero__eyebrow{letter-spacing:.16em;font-size:.64rem}
  .hero__scroll{letter-spacing:.14em;gap:.6rem}
  .hero__media figcaption{letter-spacing:.12em}
}

@media (max-width:780px){
  html{scroll-padding-top:76px}

  .gallery{grid-auto-rows:200px}
  .g--tall{grid-row:span 1}
}

/* Landscape phones: almost no height to spend, and the top padding is
   sized for a tall screen. Must sit after the 860px block, which is
   what stacks the columns. Two columns are the right call here even
   at 700px wide — side by side is the only way the photo and the
   headline both fit above the fold. */
@media (max-height:600px) and (orientation:landscape){
  .hero{
    min-height:0;
    padding-top:calc(1.75rem + var(--nav-h));
    padding-bottom:1.75rem;
  }
  .hero__grid{
    grid-template-columns:minmax(0,1.05fr) minmax(0,.7fr);
    align-items:center;
    gap:2rem;
  }
  /* Every block gives up a little so the cue still lands above the
     fold on a 420px-tall screen — it is the whole point of the hero. */
  .hero__eyebrow{margin-bottom:.9rem;font-size:.62rem}
  .hero h1{font-size:clamp(2.1rem,5.5vw,3rem);margin-bottom:.9rem}
  .lede{margin-bottom:1.2rem;font-size:1rem}
  .hero__cta .btn--lg{padding:.7rem 1.4rem;font-size:.9rem}
  /* Wide crop — a 4:5 plate would be taller than the whole viewport. */
  .hero__media img{aspect-ratio:16/10}
  .hero__media figcaption{display:none}
  .hero__scroll{margin-top:1.1rem}
}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.01ms !important;transition-duration:.01ms !important}
  .reveal{opacity:1;transform:none}
  /* The blanket rule above only shortens it — an infinite loop at
     0.01ms is worse than the animation it replaces. */
  .hero__arrow{animation:none !important}
}
