/* ============================================================
   E1 — THE WARM-UP
   One palette, walked in five steps instead of cut in one.

     char (hero) -> ember -> patty -> bun -> cream (menu)

   The Director's note was that the dark hero and the bright
   cream menu do not feel like one palette. E1 moves neither
   end. It builds the distance between them out of MATERIALS,
   each with its own band and its own job, so the boundary
   becomes a designed passage rather than a seam.

   Nothing in the bridge is a new colour. --ember is sign red
   darkened, --patty is the badge brown that already sets every
   line of secondary copy on the cream menu below, and the bun
   is cheese gold. That is what keeps the bridge from becoming
   a third unrelated thing: it is made of the page's own stock.

   COLOUR LAW (DESIGN.md, measured — not designed around):
     on cream #F5DFA8 ...  outline #14100E  14.4:1  anything
                           patty   #7B4A2A   5.6:1  secondary text
                           sign red #C8322A  4.06:1 FAILS body ->
                             large display numerals and fills only
                           cheese gold       1.64:1 NEVER text ->
                             fill only; category labels are BLACK
                             type ON a gold sticker (8.8:1)
     white on sign red ....................... 5.3:1  buttons ok
     cream #F5DFA8 on ember #6E1E18 .......... 9.3:1  the ticker
     cream #F5DFA8 on patty #7B4A2A .......... 6.1:1  the warm band
     off-white #E9E4DA on patty .............. 5.8:1  the warm band
   Body copy is never pure #FFFFFF anywhere (deviation B).

   TWO type weights only: the display face (one weight) plus
   body 400 and body 700. Type is referenced only through
   var(--font-display) / var(--font-body).
   ============================================================ */

/* ---- neutralize the global stylesheet inside this skin ----
   NOT svg: the icons, the drips and the buns are SVG and must keep
   their own attributes. */
.skin-home nav, .skin-home section, .skin-home footer, .skin-home header,
.skin-home address, .skin-home h1, .skin-home h2, .skin-home h3, .skin-home h4,
.skin-home p, .skin-home ul, .skin-home ol, .skin-home li, .skin-home form,
.skin-home input, .skin-home button, .skin-home label, .skin-home a,
.skin-home img, .skin-home div, .skin-home aside, .skin-home figure {
  all: unset;
  display: revert;
  box-sizing: border-box;
}
/* S117 (2026-09-06): the all:unset above resets an image's overflow to
   `visible`, which Chrome now reports as a deprecation - a future release will
   let image content paint outside the box. The UA default is `clip`; put it
   back. No image on the page changes a pixel (before/after screenshots at 390
   and 1200 are identical, block 191.3 pins the computed value). */
.skin-home img { max-width: 100%; overflow: clip; }
/* all: unset does NOT reliably clear the UA buttonface on a <button> in every
   embedding context — inside a host wrapper the grey pill survives and paints
   under every .prow, which on a dark menu ground is a 1.1:1 wipeout. State it
   explicitly: our buttons carry no ground of their own unless a rule gives
   them one. */
.skin-home button { background-color: transparent; appearance: none; -webkit-appearance: none; }
.skin-home { display: block; box-sizing: border-box; }

/* The notice is a fixed overlay, so it covers whatever is behind it. This pads
   the page out by exactly the notice's measured height (published as
   --cookienote-h by components/CookieNotice.tsx) so that no menu row can end
   up parked permanently underneath it, at any breakpoint. Falls to 0 the
   instant the notice is dismissed. */
.skin-home { padding-bottom: calc(var(--cookienote-h, 0px) + 12px); }

/* ---------------------------------------------------------- tokens */

.skin-home {
  /* the badge palette — the client's real logo is the source of truth */
  --sign-red: #C8322A;
  --butter: #F5DFA8;
  --cheese-gold: #E8A33A;
  --patty: #7B4A2A;
  --outline: #14100E;

  /* THE BRIDGE, and it invents nothing.
     --ember is sign red taken down to the colour of the grill at rest:
     same hue family, half the luminance, so it belongs to the hero AND
     to the red in the logo at the same time.
     --patty is the badge brown, unchanged, doing double duty as the
     middle of the walk and as the secondary text colour on cream. */
  --ember: #6E1E18;
  --ember-hi: #8A2A21;   /* the ticker's own rule, one step up from ember */

  /* the cookie notice's ground: cream, one step brighter, so a note laid
     over the page is legible as a note and not as a torn piece of menu */
  --butter-hi: #FBEFD2;

  /* the dark side: the hero and everything under the menu */
  --ink: #0A0A0A;
  --surface: #16120F;
  --deep: #070707;
  /* warm off-white. Pure #FFFFFF glares at 11pm, which is when this
     shop is busiest (DESIGN.md deviation B). */
  --on-dark: #E9E4DA;
  --on-dark-muted: #ABA69C;
  /* OpenNow inlines var(--state-dim) for its non-green states */
  --state-dim: #ABA69C;

  --key: 3px;          /* the standard keyline */
  --key-soft: 2px;     /* the secondary keyline */
  --lift: 5px;         /* the hard sticker offset. Never a blur. */
  --pattern-alpha: 0.07;

  font-family: var(--font-body);
  color: var(--on-dark);
  background: var(--ink);
  font-weight: 400;
  line-height: 1.55;
  overflow-x: clip;
}

.skin-home .e1-wrap {
  max-width: 1100px;
  margin: 0 auto;
  padding-left: 20px;
  padding-right: 20px;
}

.skin-home a { color: inherit; cursor: pointer; }
.skin-home button { cursor: pointer; }
.skin-home .e1-red { color: var(--sign-red); }
/* THE GLOWED DISPLAY WORDS — one rule, one token. currentColor means the
   sign-red words glow red and the cheese-gold ones glow gold with no second
   declaration. Strength is capped at the measured 3:1 ceiling; see the token. */
.skin-home .e1-red,
.skin-home .e1-secno,
.skin-home .e1-joinno,
.skin-home .reviews-h-gold { text-shadow: var(--glow-text); }

/* focus: gold on every dark or warm ground, sign red on cream */
.skin-home a:focus-visible,
.skin-home button:focus-visible,
.skin-home input:focus-visible {
  outline: 3px solid var(--cheese-gold);
  outline-offset: 3px;
}
.skin-home .e1-menu a:focus-visible,
.skin-home .e1-menu button:focus-visible,
.skin-home .isheet a:focus-visible,
.skin-home .isheet button:focus-visible,
.skin-home .cookienote a:focus-visible,
.skin-home .cookienote button:focus-visible {
  outline-color: var(--sign-red);
}
.skin-home ::selection { background: var(--sign-red); color: #fff; }
.skin-home .e1-menu ::selection { background: var(--outline); color: var(--butter); }

/* ------------------------------------------------------- buttons
   Sticker construction: flat fill, black keyline, generous radius,
   a hard offset in black rather than a shadow. */

.skin-home .e1-btn,
.skin-home .isheet-order,
.skin-home .cater-call,
.skin-home .franchise-send,
.skin-home .joinform .btn {
  display: inline-block;
  background: var(--sign-red);
  color: #fff;                       /* 5.3:1 on sign red */
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(1rem * var(--type-scale));
  letter-spacing: calc(1px + var(--type-tracking));
  text-transform: uppercase;
  line-height: 1.15;
  padding: 15px 28px;
  border: var(--key) solid var(--outline);
  border-radius: 999px;
  text-align: center;
  /* the sticker offset FIRST, then the glow: the construction the site is
     built from must not be replaced by the new effect, only joined by it */
  box-shadow: var(--lift) var(--lift) 0 var(--outline), var(--glow-btn);
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
/* THE NARROWEST PHONE GETS ITS 4px BACK (slice 27).
   "Add to cart · $9.00" wrapped to two lines at 320 with the webfont blocked -
   72.78px tall against 54.39px loaded, 1.999 line-heights. Measured rather than
   guessed: the button's inner width was 186.39px and the label needs 190.03px
   on one line in the fallback face. THREE POINT SIX FOUR PIXELS short.
   The padding comes in rather than the type going down, because shrinking the
   face to buy 4px costs legibility on the one screen that has the least of it -
   and 20px still leaves the label clear of the pill's radius. Block 70.2 asserts
   the label fits with room to spare at all four phone widths in BOTH font
   states, and prints the shortfall when it does not. */
@media (max-width: 360px) {
  .skin-home .isheet-order { padding-left: 20px; padding-right: 20px; }
}

.skin-home .e1-btn:hover,
.skin-home .isheet-order:hover,
.skin-home .cater-call:hover,
.skin-home .franchise-send:hover,
.skin-home .footbrand .btn:hover,
.skin-home .joinform .btn:hover {
  /* THE FILL IS STATED HERE ON PURPOSE (slice 26). For the four buttons that
     already rest on it this is a no-op; it exists for the fifth. The footer's
     ORDER NOW carries class "btn", so globals.css's V1 rule
     `.btn:hover{background:#f23128}` matches it and matches none of the others
     (.e1-btn, .isheet-order, .cater-call). Deleting that button's inverting
     override alone would have left it hovering to a BRIGHTER red than its
     siblings - a second divergence, invisible unless measured. Naming the
     background in the shared rule is what makes "the same treatment" true
     rather than nearly true. */
  background: var(--sign-red);
  transform: translate(-2px, -2px);
  box-shadow: 7px 7px 0 var(--outline), var(--glow-btn);
}
.skin-home .e1-btn:active,
.skin-home .isheet-order:active,
.skin-home .cater-call:active,
.skin-home .franchise-send:active,
.skin-home .footbrand .btn:active,
.skin-home .joinform .btn:active {
  /* SAME REASONING AS THE HOVER RULE ABOVE: globals.css also carries
     `.btn:active{...box-shadow:3px 3px 0 var(--red-deep)}`, which reaches the
     footer button and nothing else in this group. */
  background: var(--sign-red);
  transform: translate(2px, 2px);
  box-shadow: 3px 3px 0 var(--outline), var(--glow-btn);
}

/* the secondary action is genuinely secondary: no fill, no offset.
   One element per screen may compete with ORDER, and this is not it. */
.skin-home .e1-btn--ghost {
  background: transparent;
  color: var(--on-dark);
  border-color: rgba(233, 228, 218, 0.45);
  box-shadow: none;
}
.skin-home .e1-btn--ghost:hover {
  border-color: var(--on-dark);
  background: rgba(233, 228, 218, 0.07);
  transform: none;
  box-shadow: none;
}
.skin-home .e1-btn--ghost:active { transform: translateY(2px); box-shadow: none; }

.skin-home .e1-cta-row {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  align-items: center;
  margin-top: 28px;
}
/* at 390 the two buttons stack, and a full-width pair reads as one control
   block instead of two loose pills */
@media (max-width: 430px) {
  .skin-home .e1-cta-row { gap: 10px; }
  .skin-home .e1-cta-row > * { flex: 1 1 100%; text-align: center; }
}

/* ----------------------------------------------------- brand row */

.skin-home .e1-top {
  display: flex;
  align-items: center;
  gap: 11px;
  padding-top: 18px;
  /* more space under the badge row than above it, so the mark reads as sitting
     ON the hero rather than floating between two equal gaps */
  padding-bottom: 14px;
}
/* all:unset kills the width/height attributes, so images are sized here */
.skin-home .e1-badge { display: block; width: 44px; height: 44px; }
.skin-home .e1-wordmark {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(1.4rem * var(--type-scale));
  letter-spacing: calc(1px + var(--type-tracking));
  text-transform: uppercase;
  line-height: 1;
}
.skin-home .e1-wordmark b { font-weight: 400; color: var(--sign-red); }

/* ONE ROW AT THE TOP (Carlos, slice 24: "maybe make the logo and smashtime
   smaller to fit the 4 lines"). MEASURED FIRST, then sized from the numbers.

   Badge + wordmark + four links needed 601.10px in the FALLBACK font state and
   487.10px loaded, against 520px of usable width at 560 and 380px at 430. The
   arithmetic is why 390 is not on the one-row list and no amount of shrinking
   puts it there: the four links ALONE want 325.77px of a 350px wrap with the
   webfont blocked, leaving 24px for a badge and a wordmark.

   What this buys: badge 44 -> 34 and the wordmark 22.4 -> 18px drops the brand
   block from 197.66px to 156.64px in the worst state, which is what lets one
   row hold from 560 instead of 620. The LINK keeps its 44px tap floor - only
   the image inside it shrinks. Scoped to the widths that are tight; 768 and up
   already fit at full size. */
@media (max-width: 767px) {
  .skin-home .e1-top .e1-badge { width: 34px; height: 34px; }
  .skin-home .e1-top .e1-wordmark { font-size: calc(1.125rem * var(--type-scale)); }
  .skin-home .e1-homelink { gap: 8px; }
}

/* THE TOP HEADER SHEDS ITS WORDMARK TEXT ON A PHONE (Carlos, slice 28: he wants
   the links beside the logo, not wrapped under it). Measured before accepting
   the wrap, in the FALLBACK face: badge + four compact links need 379.77px, so
   they FIT at 430 with 10.23px to spare and are short by 29.77px at 390, 59.77
   at 360 and 99.77 at 320. The badge alone still says SmashTime and still goes
   home, so the word is what goes.
   BELOW 431 THE ROW STILL WRAPS, and that is reported rather than forced: the
   only way to buy 30px at 390 is to take the nav under this project's readable
   floor, which is not a trade worth making on the screen with the least of it. */
@media (max-width: 430px) {
  .skin-home .e1-top .e1-wordmark { display: none; }
}

/* ============================================================
   STEP 1 — CHAR. The hero, exactly as M3 built it and not
   redesigned: near-black ground, the warm glow bleeding from the
   top right, badge plus small wordmark, cream-white SMASH TIME
   over red BURGER CO, the supporting line, two buttons.
   ============================================================ */

/* STEP 1 — WARM GLOW. Two lights on near-black: gold from the upper right,
   sign red low on the left, over a dark vertical fall.
   A generated charcoal photograph sat under this glow until 2026-07-25. The
   Director cut it: it read as generic charred wood and competed with the
   headline it was supposed to sit behind. The ground's job is to be a ground.
   Do not reintroduce it. This now matches /f2's hero exactly, which is the
   state it was reverted to. */
.skin-home .e1-hero {
  display: block;
  position: relative;
  background:
    radial-gradient(1100px 560px at 72% 10%, rgba(232, 163, 58, 0.26), transparent 56%),
    radial-gradient(1000px 520px at 12% 100%, rgba(200, 50, 42, 0.28), transparent 60%),
    linear-gradient(180deg, #0A0A0A, #16120F);
}
/* Tightened: the headline lockup wants more air under the badge row and less
   dead space before the buttons, so the eye goes badge, title, action. */
.skin-home .e1-hero-main { padding-top: 26px; padding-bottom: 46px; }

.skin-home .eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-size: 0.76rem;
  color: var(--cheese-gold);
  margin-bottom: 16px;
}
.skin-home .eyebrow .dot {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #36d07a;
}

.skin-home .e1-hero-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(clamp(3.1rem, 13.5vw, 7rem) * var(--type-scale));
  text-transform: uppercase;
  line-height: 0.9;
  letter-spacing: calc(0.5px + var(--type-tracking));
  color: #F6ECD9;
  overflow-wrap: break-word;
}
.skin-home .e1-hero-sub {
  max-width: 62ch;
  margin: 18px 0 26px;
  font-size: 1.06rem;
  line-height: 1.6;
  color: var(--on-dark);
}

/* ============================================================
   STEP 2 — EMBER. Sign red taken down to the colour of the grill
   at rest. The first ticker already sat in this zone, so instead
   of being a seam between two strangers it becomes the first warm
   step of the walk. Cream type on ember measures 9.3:1.
   ============================================================ */

/* no border here on purpose: the hero pours INTO this band, and a hard
   rule directly under a wavy pour cancels the pour. The one hard rule in
   the warm-up is the ember/patty step below, where it means something. */
.skin-home .e1-ember { display: block; background: var(--ember); }

.skin-home .e1-ticker {
  overflow: hidden;
  white-space: nowrap;
  background: var(--ember);
  color: var(--butter);              /* 9.3:1 */
  border-top: var(--key-soft) solid var(--ember-hi);
  border-bottom: var(--key-soft) solid var(--ember-hi);
}
.skin-home .e1-ticker-track {
  display: inline-block;
  padding: 10px 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(1.02rem * var(--type-scale));
  letter-spacing: calc(2px + var(--type-tracking));
  text-transform: uppercase;
  /* The track holds SIX copies of the run (art.jsx Ticker) so the scrolling
     half is always wider than the viewport and the wrap never shows a gap.
     e1-scroll travels -50%, i.e. three copies, and the original 34s was tuned
     for one copy — so the duration is 3 x 34s. If you change the copy count,
     change this with it or the speed jumps. */
  animation: e1-scroll 102s linear infinite;
  will-change: transform;
}
.skin-home .e1-ticker--rev .e1-ticker-track { animation-direction: reverse; }
.skin-home .e1-tick {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin: 0 13px;
}
/* the icon is the one gold note in the warm band: 3.4:1 on ember, which
   is a decorative pictogram beside its own label, never the only signal */
.skin-home .e1-tick-icon { display: block; width: 19px; height: 19px; color: var(--cheese-gold); }
@keyframes e1-scroll {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(-50%, 0, 0); }
}

/* ============================================================
   STEP 3 — PATTY. The middle of the walk, and the only palette
   token that is neither dark nor cream.

   The ember/patty boundary is a HARD BLACK RULE, not a pour. Two
   melts in a row read as one long drip; a rule here says two
   distinct materials are stacked, which is the whole argument.
   ============================================================ */

/* STEP 3 — PATTY, now a real griddle surface. The texture is a photograph of a
   seasoned flat-top plate, flattened to a NEUTRAL grain centred on mid grey and
   blended with `overlay`, so it modulates the brown with scratches and sear
   marks without repainting it. The band keeps its exact palette colour, which
   is what lets the contrast figures above stay true (cream 6.1:1, off-white
   5.8:1 on patty). Texture only: no food, no signage — see DECISIONS.md. */
.skin-home .e1-patty {
  display: block;
  background-color: var(--patty);
  background-image: url("./images/texture/griddle.webp");
  background-size: cover;
  background-position: center;
  background-blend-mode: overlay;
  border-top: var(--key) solid var(--outline);
  color: var(--on-dark);
}
.skin-home .e1-patty-inner { padding: 30px 20px 26px; }

.skin-home .e1-warm-kicker {
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: 0.74rem;
  line-height: 1.4;
  color: var(--butter);              /* 6.1:1 on patty */
}
.skin-home .e1-warm-line {
  margin-top: 9px;
  max-width: 46ch;
  font-size: 1.02rem;
  line-height: 1.6;
  color: var(--on-dark);             /* 5.8:1 on patty */
}

/* ============================================================
   STEP 4 — BUN. The warm-up resolves into the top bun: gold dome,
   cream seeds, black keyline, sitting on the patty. Decorative
   and aria-hidden; nothing is ever set on top of it.
   ============================================================ */

.skin-home .e1-buntop { display: block; margin-bottom: -1px; }

/* ============================================================
   STEP 5 — CREAM. The menu region, at full brightness.

   Cream survives because it is a BRAND colour (it is the colour
   of BURGER CO in the badge), not because it is paper: one flat
   fill, heavy black keylines, generous radii, hard black offsets.
   If it ever goes soft it has become the thing the Director
   rejected. E1 does not dim it. It earns it by walking up to it.

   NOTE: no z-index / transform / filter / perspective anywhere on
   this section or any ancestor of it — it is an ancestor of
   <PriceList/>'s portalled item sheet.
   ============================================================ */

.skin-home .e1-menu {
  display: block;
  position: relative;
  background: var(--butter);     /* flat. One value. */
  color: var(--outline);
}

/* the last of the bun. Cheese runs off the crown and lands on the menu, which
   is the moment the warm-up hands over.

   Director, 2026-07-28: the band's GROUND is the menu, not the cheese. It used
   to be filled cheese gold, so the whole strip read as one solid gold block
   with the drip lost inside it. The ground now matches the menu region and the
   only gold in the band is the cheese itself. --menu-ground is set by the
   palette layers; on E1 it falls back to the cream. */
.skin-home .e1-bunlip {
  display: block;
  position: relative;   /* above the pattern tile. position only, never z-index */
  background: var(--menu-ground, var(--butter));
  padding-top: 0;
  /* the cheese hangs PAST this band into the cream below. Nothing here clips
     it: what stops it is the section kicker underneath, which is the whole
     point. Position only, never z-index (PriceList's sheet is portalled into
     this skin and a z-index up here would trap it). */
  overflow: visible;
}

/* the pattern tile, nearly subliminal. It is a brand asset, so it grounds
   the menu rather than decorating it: at 7% it survives the squint test as
   texture and never as an element. Painted by a pseudo-element so the flat
   cream fill underneath stays a single flat colour. */
/* The menu ground carries TWO layers: the brand pattern tile (the burger, fry
   cone, shake cup and spatula that will end up on wrappers) and, under it, a
   real paper grain so the cream reads as stock rather than as a flat fill.
   The grain is a 1KB seamless 600px tile at multiply, low enough that black
   type over it still measures above 13:1. */
.skin-home .e1-menu::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("./images/pattern-tile.svg");
  background-size: 240px 240px;
  background-repeat: repeat;
  opacity: var(--pattern-alpha);
  pointer-events: none;
}
.skin-home .e1-menu::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("./images/texture/paper-grain.webp");
  background-size: 300px 300px;
  background-repeat: repeat;
  /* The tile is centred just below white (232-250), so multiply bites only
     where the paper fibre is. A grain centred on mid grey darkened the cream by
     about a quarter and shifted the palette out from under the measured
     contrast table. Worst case now: cream #F5DFA8 -> #DFCB99, and black type
     over that still measures 12.6:1. */
  mix-blend-mode: multiply;
  pointer-events: none;
}
/* position:relative only (never z-index) lifts the content above the tile */
/* position:relative only (never z-index) lifts the content above the tile.
   padding-top was 46px; it is 84px so the cheese hanging off the bun has cream
   to fall through before it reaches the first kicker. */
.skin-home .e1-menu-inner { position: relative; padding-top: 84px; padding-bottom: 54px; }

/* the heel bun closes the stack, and it closes onto ember: the same
   ladder walked backwards. */
.skin-home .e1-heel { display: block; position: relative; background: var(--ember); }

/* the one heavy rule inside the cream region: it separates the four cards
   from the full list */
.skin-home #menu {
  margin-top: 56px;
  padding-top: 30px;
  border-top: var(--key) solid var(--outline);
}

/* -------------------------------------- section heads (C2's one device)
   `01 MOST POPULAR ————`. The number, the title, then a rule running off
   the heading to the edge. Printed structure for the price of two borders. */

.skin-home .e1-sechead { display: block; margin: 0 0 26px; }
.skin-home .e1-kicker {
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: 0.74rem;
  line-height: 1.4;
  color: var(--patty);            /* 5.6:1 on cream */
}
.skin-home .e1-secline {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 8px;
  min-width: 0;
}
/* sign red on cream is 4.06:1 — legal for LARGE display only, so this is
   never smaller than 28px and never carries a word. */
.skin-home .e1-secno {
  flex: 0 0 auto;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(clamp(1.75rem, 6vw, 2.4rem) * var(--type-scale));
  line-height: 1;
  letter-spacing: calc(1px + var(--type-tracking));
  color: var(--sign-red);
}
.skin-home .e1-sectitle {
  flex: 0 1 auto;
  min-width: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(clamp(2rem, 8vw, 3.4rem) * var(--type-scale));
  line-height: 0.95;
  letter-spacing: calc(0.5px + var(--type-tracking));
  text-transform: uppercase;
  color: var(--outline);
  overflow-wrap: break-word;
}
.skin-home .e1-secrule {
  flex: 1 1 20px;
  min-width: 16px;
  align-self: center;
  height: 0;
  border-top: var(--key) solid var(--outline);
}
.skin-home .e1-secnote {
  margin-top: 12px;
  max-width: 62ch;
  font-size: 0.94rem;
  line-height: 1.6;
  color: var(--patty);
}

/* on the dark ground the same device inverts */
.skin-home .e1-sechead--dark .e1-kicker { color: var(--cheese-gold); }
.skin-home .e1-sechead--dark .e1-sectitle { color: var(--on-dark); }
.skin-home .e1-sechead--dark .e1-secrule { border-top-color: rgba(233, 228, 218, 0.4); }
.skin-home .e1-sechead--dark .e1-secnote { color: var(--on-dark-muted); }

/* ------------------------------------------- 01 most popular: die-cut cards */

.skin-home .e1-featgrid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 20px;
  list-style: none;
  margin: 0;
  padding: 0 var(--lift) var(--lift) 0;   /* room for the hard offset */
}
@media (max-width: 960px) { .skin-home .e1-featgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .skin-home .e1-featgrid { grid-template-columns: minmax(0, 1fr); } }

.skin-home .e1-feat,
.skin-home .e1-bcard {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 9px;
  min-width: 0;
  padding: 18px 18px 16px;
  background: var(--butter);       /* flat, same cream: a sticker, not a panel */
  border: var(--key) solid var(--outline);
  border-radius: 18px;             /* generous radius, logo-shaped */
  box-shadow: var(--lift) var(--lift) 0 var(--outline);
}
/* the number is a GOLD STICKER with black type: keeps the gold identity and
   clears 8.8:1, where gold as type on cream would be 1.64:1 */
/* ONE BADGE TOKEN, and the measurement is why it had to become one (slice 2).
   The pill used to HUG its digits — inline-block with padding — so its width
   was whatever the face made "01" against "04". On a desktop at dpr 1 those
   advances round to the same 52.47px and the four look identical, which is
   how this survived; under the suite's phone profile at dpr 3 they measure
   45.42 / 49.13 / 49.38 / 49.53, a 4.11px spread. The badge is now a FIXED
   pill with its digits centred in it, so identical is a fact of the box
   rather than a property of the font — and tabular figures keep it true when
   the type wheel swaps the display face underneath. */
.skin-home {
  /* the sticky bar's own height, so the anchor offsets below cannot drift
     away from it: 61px desktop, 56px on the phone variant */
  --feat-badge-w: 52px;
  --feat-badge-h: 36px;

  /* ============================================================
     THE GLOW — ONE TOKEN PAIR, and the two strengths are a
     MEASURED consequence, not a taste.

     A halo around type raises the local background TOWARD the
     glyph's own colour, so a red glow on red display type spends
     exactly the contrast that type has left. Measured before
     building, glyph against its own halo:

         alpha    0.12   0.18   0.25   0.35   0.55
         hero     3.42   3.24   3.01   2.67   2.00
         visit    3.08   2.91   2.71   2.41   1.86
         cream    3.45   3.18   2.88   2.49   1.85

     Every one of those words is large display type, so the floor
     is 3:1 — and the tightest ground fails from 0.18 upward. TEXT
     THEREFORE TAKES 0.12 AND NO MORE. It is a restrained glow
     because that is the whole budget the palette leaves; the
     alternative is an illegible heading, and the floor wins.

     A BUTTON'S GLOW IS FREE by comparison: it is painted OUTSIDE a
     filled control, so it cannot touch the white-on-red label at
     all. That is why it can be four times stronger.

     currentColor, so ONE token serves both the sign-red words and
     the cheese-gold ones (which measure 8.47:1 and 9.09:1 and have
     headroom to spare) without a second rule per colour. */
  --glow-text: 0 0 12px color-mix(in srgb, currentColor 12%, transparent);
  --glow-btn: 0 0 22px color-mix(in srgb, var(--sign-red) 55%, transparent);
}
.skin-home .e1-feat-no {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--feat-badge-w);
  height: var(--feat-badge-h);
  padding: 0 10px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(1.15rem * var(--type-scale));
  line-height: 1;
  letter-spacing: calc(1px + var(--type-tracking));
  font-variant-numeric: tabular-nums;
  color: var(--outline);
  background: var(--cheese-gold);
  border: var(--key-soft) solid var(--outline);
  border-radius: 999px;
}
.skin-home .e1-feat-name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(1.3rem * var(--type-scale));
  line-height: 1.05;
  letter-spacing: calc(0.5px + var(--type-tracking));
  text-transform: uppercase;
  color: var(--outline);
  overflow-wrap: anywhere;
}
.skin-home .e1-feat-blurb {
  flex: 1;
  font-size: 0.88rem;
  line-height: 1.55;
  color: var(--patty);             /* 5.6:1 */
  max-width: 40ch;
}
/* prices on cream are NEVER red (4.06:1). Black. */
.skin-home .e1-feat-price {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(1.3rem * var(--type-scale));
  line-height: 1.2;
  letter-spacing: calc(0.5px + var(--type-tracking));
  color: var(--outline);
  font-variant-numeric: tabular-nums;
  padding-top: 10px;
  border-top: var(--key-soft) solid rgba(20, 16, 14, 0.28);
  width: 100%;
}

/* THE BRUSH SWASH — the client's own promo language, on these four prices only.
   The mark is behind the number, not around it: the price stays outline black
   on cream where it clears 14.4:1, and the swash reads as ink pulled under it
   rather than as a coloured chip the price has to survive. */
.skin-home .e1-feat-price {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0;
  margin-top: 12px;
}
/* ONE BLOB TOKEN. Two things were measured wrong here and only one of them
   was the one anybody had guessed.

   THE GUESS — that the blob hugs its text, so a five-character price gets a
   different blob than a six — IS FALSE. Every blob is this same fixed box
   whatever the price reads.

   WHAT WAS ACTUALLY WRONG: the four cards passed two DIFFERENT hand-drawn
   swash paths, alternating, which painted 113.43 x 26.68 on cards 1 and 3
   against 112.15 x 28.42 on cards 2 and 4. The per-card `pull` overrides are
   gone from the markup, so all four now draw the component's one default
   stroke.

   AND THE LOUDEST DIFFERENCE NOBODY NAMED: with a fixed blob and a variable
   price, the gold trailing the figure ran 56.03px behind $9.00 against
   46.37px behind $12.00 — a 10px swing that reads as four different blobs
   even when the blobs are identical. The price is centred on the blob now,
   from the same two tokens the blob is drawn from, so the gold sits the same
   way on every card whatever the figure. */
.skin-home {
  --feat-blob-w: 116px;
  --feat-blob-x: -6px;
}
.skin-home .e1-swash {
  position: absolute;
  left: var(--feat-blob-x);
  top: 50%;
  transform: translateY(-46%);
  width: var(--feat-blob-w);
  height: 2.05em;
  pointer-events: none;
  color: var(--cheese-gold);
  fill: currentColor;
}
.skin-home .e1-feat-price-t {
  position: relative;
  display: inline-block;
  min-width: var(--feat-blob-w);
  margin-left: var(--feat-blob-x);
  text-align: center;
}
/* the swash is a flourish, not information: if motion or paint is unwelcome the
   price still reads exactly the same underneath */
@media (forced-colors: active) {
  .skin-home .e1-swash { display: none; }
}

/* ============================================================
   02 THE WHOLE MENU — the shared <PriceList/>, and the middle
   of the BURGER FRAME.

   Each category is a filling in the stack, so <PriceList/> emits
   a .pcat-drip above every heading and this skin colours it with
   --drip-fill. Scrolling the menu is meant to read as eating down
   through the burger.

   Two disciplines keep the device from turning into wallpaper:
     - every fill is a badge token, and one of them is --ember, so
       the bridge colour from the top of the page reappears inside
       the menu instead of being abandoned at the door;
     - nothing is ever set ON a drip. They sit in the gap above a
       heading, they are aria-hidden, and legibility wins.
   ============================================================ */

.skin-home .pricelist {
  /* one column below the breakpoint; the flow takes over at 760 (see (a)).
     `display: block` rather than a one-column grid because a multi-column
     container IS a block container - keeping `display: grid` here and adding
     `columns` above would leave two layout models fighting over the same
     element, which is how the previous version of this rule ended up inert. */
  display: block;
  column-gap: 56px;
}
@media (min-width: 760px) { .skin-home .pricelist { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }

.skin-home .pcat { display: block; min-width: 0; padding: 0 0 22px; }

/* The fillings, top to bottom of the stack. Note what is NOT here: sign
   red. DESIGN.md is explicit that colour lives on interactive elements and
   that a decorative red block competes with the order button and loses the
   squint test, so red stays on buttons and large display numerals only.
   Every drip fill is a warm-up material, which is the point: the bridge
   colours reappear inside the menu instead of being abandoned at the door. */
.skin-home .pcat[data-cat="1"] { --drip-fill: var(--patty); }        /* the meat */
.skin-home .pcat[data-cat="2"] { --drip-fill: var(--cheese-gold); }  /* the melt */
.skin-home .pcat[data-cat="3"] { --drip-fill: var(--ember); }        /* the char */
.skin-home .pcat[data-cat="4"] { --drip-fill: var(--patty); }        /* the meat */
.skin-home .pcat[data-cat="5"] { --drip-fill: var(--cheese-gold); }  /* the melt */

.skin-home .pcat-drip { display: block; margin: 26px 0 -6px; }
/* the first category already sits under the section rule, so it does not
   need a second gap above its pour */
.skin-home .pcat:first-child .pcat-drip { margin-top: 14px; }

/* the category head reuses the section device: icon, gold sticker label,
   rule running off */
.skin-home .pcat-title {
  display: flex;
  align-items: center;
  gap: 11px;
  min-width: 0;
  margin: 16px 0 8px;
}
.skin-home .pcat-icon {
  flex: 0 0 auto;
  display: block;
  width: 26px;
  height: 26px;
  color: var(--outline);
}
/* GOLD IS A FILL. Black type on a gold sticker is 8.8:1; gold type on cream
   would be 1.64:1 and is forbidden. */
.skin-home .pcat-label {
  flex: 0 1 auto;
  min-width: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(1.18rem * var(--type-scale));
  line-height: 1.1;
  letter-spacing: calc(1px + var(--type-tracking));
  text-transform: uppercase;
  color: var(--outline);
  background: var(--cheese-gold);
  border: var(--key-soft) solid var(--outline);
  border-radius: 999px;
  padding: 6px 15px 5px;
  overflow-wrap: break-word;
}
.skin-home .pcat-rule {
  flex: 1 1 16px;
  min-width: 12px;
  align-self: center;
  height: 0;
  border-top: var(--key-soft) solid var(--outline);
}

.skin-home .prows { list-style: none; margin: 0; padding: 0; }
.skin-home .prows li { display: block; min-width: 0; }

.skin-home .prow {
  display: flex;
  align-items: flex-end;
  /* THE THUMB FLOOR. These rows measured 41px, and this site's own doctrine is
     one thumb on a 390px phone — 44 menu rows sitting a few pixels under the
     floor is the most-used control on the page being the hardest to hit.
     Padding, not height, so the dot leader and price stay on their baseline. */
  min-height: 44px;
  width: calc(100% + 16px);
  min-width: 0;
  margin: 0 -8px;
  padding: 10px 8px;
  border-radius: 10px;
  font-family: var(--font-body);
  text-align: left;
  color: var(--outline);
  cursor: pointer;
  transition: background-color 0.12s ease;
}
.skin-home .prow:hover { background: rgba(20, 16, 14, 0.07); }
.skin-home .prow:active { background: rgba(20, 16, 14, 0.13); }

.skin-home .prow-name {
  flex: 0 1 auto;
  min-width: 0;
  font-weight: 700;
  font-size: 0.97rem;
  line-height: 1.35;
  overflow-wrap: anywhere;
}
/* real dots, bottom-anchored so they share the price baseline */
.skin-home .prow-dots {
  flex: 1 1 16px;
  min-width: 14px;
  align-self: flex-end;
  height: 5px;
  margin: 0 8px 6px;
  background-image: radial-gradient(circle, rgba(20, 16, 14, 0.55) 1.2px, transparent 1.6px);
  background-size: 8px 5px;
  background-position: right bottom;
  background-repeat: repeat-x;
}
/* black, not red: sign red on cream is 4.06:1 and prices are body-critical */
.skin-home .prow-price {
  flex: 0 0 auto;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(1.06rem * var(--type-scale));
  line-height: 1.2;
  letter-spacing: calc(0.5px + var(--type-tracking));
  color: var(--outline);
  font-variant-numeric: tabular-nums;
}
/* An item we cannot price honestly says so in words. Body face, not the
   display face: it is a sentence, not a figure, and it must not read as a
   number. Patty brown is 5.6:1 on cream, which clears secondary text. */
.skin-home .prow-price[data-price-unconfirmed] {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.78rem;
  letter-spacing: 0;
  line-height: 1.5;
  text-transform: none;
  color: var(--patty);
  max-width: 46%;
  text-align: right;
}

/* the board's own section note, e.g. two patties on every signature burger */
.skin-home .pcat-note {
  display: block;
  margin: -4px 0 12px;
  font-family: var(--font-body);
  font-size: 0.83rem;
  line-height: 1.5;
  color: var(--patty);
}

/* board groups that price options rather than dishes: toppings, add ons,
   sauces. Secondary to the price rows on purpose: they are reference, not
   the thing being chosen. */
.skin-home .pmods {
  display: block;
  margin: 14px 0 4px;
  padding: 11px 13px;
  border: var(--key-soft) solid rgba(20, 16, 14, 0.22);
  border-radius: 12px;
  background: rgba(20, 16, 14, 0.035);
}
.skin-home .pmods-h {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  margin: 0 0 4px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(0.82rem * var(--type-scale));
  letter-spacing: calc(0.6px + var(--type-tracking));
  text-transform: uppercase;
  color: var(--outline);
}
/* black type on a gold sticker is 8.8:1; gold as type on cream is 1.64:1 and
   is never allowed. Sticker, not text. */
.skin-home .pmods-price {
  font-family: var(--font-body);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
  color: var(--outline);
  background: var(--cheese-gold);
  border: 2px solid var(--outline);
  border-radius: 999px;
  padding: 2px 9px 1px;
}
.skin-home .pmods-list {
  display: block;
  margin: 0;
  font-family: var(--font-body);
  font-size: 0.83rem;
  line-height: 1.6;
  color: var(--patty);
}
/* THE ASTERISK'S KEY, ON THE MENU (2026-08-28). Same register as .pmods-list -
   this is a footnote, not a heading - and patty brown on the cream is 5.6:1,
   the secondary colour the colour law allows for exactly this. */
.skin-home .pmods-prov-note {
  margin-top: 10px;
  font-family: var(--font-body);
  font-size: 0.78rem;
  line-height: 1.5;
  color: var(--patty);
}


/* ------------------------------------------------------ the item sheet
   INVARIANT 11: the sheet belongs to the menu surface it opens from. This
   menu is cream, so the sheet is cream. A black sheet over a cream menu
   was the bug this round fixed, and it is not coming back. */

.skin-home .isheet-backdrop {
  position: fixed;
  inset: 0;
  z-index: 80;
  background: rgba(7, 6, 4, 0.72);
}
.skin-home .isheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 81;
  width: 100%;
  max-height: 88dvh;
  overflow: auto;
  overscroll-behavior: contain;
  background: var(--butter);
  color: var(--outline);
  border: var(--key) solid var(--outline);
  border-bottom: none;
  border-radius: 22px 22px 0 0;
}
@media (min-width: 700px) {
  .skin-home .isheet {
    /* centred by auto margins rather than a transform, so nothing here is
       tempted to migrate a transform up the tree onto a PriceList ancestor */
    inset: 0;
    margin: auto;
    height: fit-content;
    width: min(520px, 92vw);
    max-height: 86vh;
    border: var(--key) solid var(--outline);
    border-radius: 20px;
    box-shadow: 10px 10px 0 rgba(20, 16, 14, 0.55);
  }
}
.skin-home .isheet-inner { display: block; position: relative; padding-bottom: 22px; }

/* THE SCROLLBAR STAYS, STYLED — Director's call, 2026-08-16 (slice 1e), and
   the reason is the whole point: a hidden scrollbar means a customer never
   learns the drawer scrolls and never reaches ADD TO CART. So it is made
   quiet, not invisible — thin and dark on the cream — and
   `scrollbar-width: none` is banned by tests/demo-drawer.spec.ts.

   THE BRIEF SAID "LOW CONTRAST" AND THE FLOOR WON, which is the standing
   rule when the two disagree. The first cut used 0.38 alpha and MEASURED
   2.38:1 against the cream, under the 3:1 floor for a non-text control — a
   scrollbar kept for visibility that was too faint to see is the same defect
   as hiding it. 0.55 measures 3.87:1: still quiet, now actually visible.
   BOTH SCROLLERS, because which element scrolls moves with the breakpoint:
   .isheet-inner under 700px, .isheet above it (measured, not assumed). Both
   syntaxes: the standard properties are what current Chrome and Firefox
   honour, the ::-webkit- rules are the fallback for older WebKit. */
.skin-home .isheet,
.skin-home .isheet-inner {
  scrollbar-width: thin;
  scrollbar-color: rgba(20, 16, 14, 0.55) transparent;   /* 3.87:1 on the cream — see the note above */
}
.skin-home .isheet::-webkit-scrollbar,
.skin-home .isheet-inner::-webkit-scrollbar { width: 10px; }
.skin-home .isheet::-webkit-scrollbar-track,
.skin-home .isheet-inner::-webkit-scrollbar-track { background: transparent; }
.skin-home .isheet::-webkit-scrollbar-thumb,
.skin-home .isheet-inner::-webkit-scrollbar-thumb {
  background: rgba(20, 16, 14, 0.55);
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: 999px;
}
.skin-home .isheet::-webkit-scrollbar-thumb:hover,
.skin-home .isheet-inner::-webkit-scrollbar-thumb:hover { background: rgba(20, 16, 14, 0.7); background-clip: content-box; }

.skin-home .isheet-x {
  position: absolute;
  /* ABOVE the cut-out slot. The photo treatment puts a sticker across the top
     of the sheet, and it swallowed this button whole: the close was still in
     the DOM, still focusable, and completely untappable. z-index is safe HERE
     because .isheet-x is a DESCENDANT of the portalled sheet, not an ancestor
     of <PriceList /> — that is the rule this project keeps tripping over. */
  z-index: 2;
  top: 12px;
  right: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 999px;
  background: var(--butter);
  border: var(--key-soft) solid var(--outline);
  color: var(--outline);
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
  transition: background-color 0.12s ease;
}
.skin-home .isheet-x:hover { background: var(--cheese-gold); }

.skin-home .isheet-media { display: block; overflow: hidden; line-height: 0; }
.skin-home .isheet-img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 300px;
  object-fit: cover;
  border-bottom: var(--key) solid var(--outline);
  border-radius: 19px 19px 0 0;
}
/* honest empty state: never a broken image, never a stock stand-in */
.skin-home .isheet-nophoto {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 40px 24px 34px;
  text-align: center;
  background: var(--butter);
  border-bottom: var(--key) solid var(--outline);
  border-radius: 19px 19px 0 0;
}
.skin-home .isheet-nophoto-h {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(1.3rem * var(--type-scale));
  line-height: 1.1;
  letter-spacing: calc(1px + var(--type-tracking));
  text-transform: uppercase;
  color: var(--outline);
  background: var(--cheese-gold);
  border: var(--key-soft) solid var(--outline);
  border-radius: 999px;
  padding: 8px 18px 7px;
}
.skin-home .isheet-nophoto-p {
  max-width: 32ch;
  font-size: 0.88rem;
  line-height: 1.55;
  color: var(--patty);
}

.skin-home .isheet-body { display: block; padding: 18px 20px 0; background: var(--butter); }
.skin-home .isheet-cat {
  display: inline-block;
  font-weight: 700;
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--outline);
  background: var(--cheese-gold);
  border: 2px solid var(--outline);
  border-radius: 999px;
  padding: 4px 11px 3px;
}
.skin-home .isheet-name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(1.75rem * var(--type-scale));
  line-height: 1;
  letter-spacing: calc(0.5px + var(--type-tracking));
  text-transform: uppercase;
  color: var(--outline);
  margin: 12px 0 4px;
  overflow-wrap: anywhere;
}
.skin-home .isheet-price {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(1.3rem * var(--type-scale));
  letter-spacing: calc(0.5px + var(--type-tracking));
  color: var(--outline);          /* not red: 4.06:1 fails here */
  font-variant-numeric: tabular-nums;
}
/* a board qualifier that belongs to the price, e.g. "Add a patty +3.00" */
.skin-home .isheet-note {
  display: block;
  margin: 4px 0 0;
  font-family: var(--font-body);
  font-size: 0.83rem;
  line-height: 1.5;
  color: var(--patty);
}
.skin-home .isheet-desc {
  margin-top: 10px;
  max-width: 62ch;
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--patty);
}

/* --------------------------------------------------- the build sheet
   READ-ONLY. Ordering is not live, so nothing here may carry a control
   affordance: no chips, no boxes, no pointer cursor, no hover, no
   remove-looking icon. It is a printed ingredient list, grouped by
   space and one hairline rule. */
/* NO RULE ABOVE THIS SECTION — Director's call, 2026-08-16 (slice 1c): the
   label and the space already separate it. The divider occupied 34px here
   (20 margin + 14 padding, the line at the 20) and ALL 34 are kept as clear
   air — a first cut said 34 in the comment and set 30, which is how a
   "removed the line, kept the space" claim quietly becomes a 4px loss. */
.skin-home .isheet-build {
  display: block;
  margin-top: 34px;
  padding-top: 0;
  border-top: 0;
}
/* the heel of the burger: the closing bun's icon is flipped so the list reads
   as a cross-section, crown at the top, heel at the bottom. Marked in the
   data (see buildLines), never inferred from position. */
.skin-home .isheet-build-line.is-heel .isheet-build-icon { transform: scaleY(-1); }
.skin-home .isheet-build-h {
  font-weight: 700;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--patty);
}
.skin-home .isheet-build-list {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
/* S141: THE LINE IS A GRID, ITS ROW IS THE OLD FLEX BOX.
   A height cannot be transitioned from `auto`, which is why the previous
   collapse used max-height - and why S131 had to delete it, because a cap that
   exists AT REST can clip the label (25.59px of it, measured, on .v2).
   `grid-template-rows: 1fr -> 0fr` has no resting cap at all: at 1fr the track
   IS the content's height, so no label length, width or engine can hide a word.
   That is the whole reason for the wrapper. */
.skin-home .isheet-build-line {
  display: grid;
  grid-template-rows: 1fr;
  min-width: 0;
  cursor: default;      /* explicitly not interactive */
  transition: grid-template-rows 0.34s ease, opacity 0.34s ease;
}
.skin-home .isheet-build-row {
  display: flex;
  align-items: center;
  gap: 11px;
  min-width: 0;
  padding: 4px 0;
  /* min-height:0 lets the track actually reach 0fr - without it the row keeps
     its min-content height and the collapse does nothing.
     ⚠️ NO `overflow: hidden` HERE. The first draft of this rule put it on the
     row permanently and MEASURED A 3px CLIP AT REST on four of six lines: the
     44px touch target is taller than the 38px text row and was being cut to 41.
     That is precisely the S131 defect - a clipping region that exists when
     nothing is animating - reintroduced by the slice restoring the animation.
     The clip now lives on `.is-leaving` only, so at rest there is none. */
  min-height: 0;
}
.skin-home .isheet-build-icon {
  flex: 0 0 auto;
  display: block;
  width: 19px;
  height: 19px;
  color: var(--patty);
}
.skin-home .isheet-build-label {
  min-width: 0;
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--outline);
  overflow-wrap: anywhere;
}

.skin-home .isheet-cta { display: block; margin-top: 20px; }
.skin-home .isheet-callin {
  margin-top: 14px;
  font-size: 0.86rem;
  line-height: 1.55;
  color: var(--patty);
}
.skin-home .isheet-callin a {
  color: var(--outline);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ============================================================
   03 the story beat — the page is back in the dark room, and it
   got there by the same ladder it climbed.
   ============================================================ */

.skin-home .e1-hood { display: block; padding: 62px 0; background: var(--ink); }
.skin-home .e1-hood-grid {
  display: grid;
  grid-template-columns: minmax(0, 330px) minmax(0, 1fr);
  gap: 40px;
  align-items: center;
}
@media (max-width: 820px) { .skin-home .e1-hood-grid { grid-template-columns: minmax(0, 1fr); gap: 30px; } }

.skin-home .e1-mural { display: block; margin: 0; }
.skin-home .e1-mural img {
  display: block;
  width: 100%;
  max-width: 330px;
  height: auto;
  border: var(--key) solid var(--butter);
  border-radius: 14px;
}
@media (max-width: 820px) { .skin-home .e1-mural img { margin: 0 auto; max-width: 300px; } }

.skin-home .e1-hood-copy { min-width: 0; }
.skin-home .e1-hood-p { max-width: 62ch; font-size: 1.04rem; line-height: 1.65; color: var(--on-dark); }
.skin-home .e1-iglink {
  display: inline-block;
  margin-top: 20px;
  padding: 9px 17px;
  border: 2px solid rgba(232, 163, 58, 0.5);
  border-radius: 999px;
  color: var(--cheese-gold);
  font-weight: 700;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}
.skin-home .e1-iglink:hover { border-color: var(--cheese-gold); background: rgba(232, 163, 58, 0.1); }

/* ============================================================
   04 the list — shared <Join/>
   ============================================================ */

.skin-home .join { display: block; padding: 62px 0; background: var(--surface); }
.skin-home .join .wrap { display: block; max-width: 1100px; margin: 0 auto; padding: 0 20px; }
.skin-home .join h2 {
  display: block;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(clamp(2rem, 7vw, 3.2rem) * var(--type-scale));
  line-height: 1;
  letter-spacing: calc(0.5px + var(--type-tracking));
  text-transform: uppercase;
  color: var(--on-dark);
}
.skin-home .e1-joinno {
  display: inline-block;
  margin-right: 14px;
  font-size: calc(clamp(1.75rem, 6vw, 2.4rem) * var(--type-scale));
  color: var(--cheese-gold);
}
.skin-home .join > .wrap > p {
  max-width: 62ch;
  margin: 16px 0 22px;
  font-size: 1.02rem;
  line-height: 1.6;
  color: var(--on-dark);
}

.skin-home .joinform { display: flex; gap: 12px; max-width: 480px; flex-wrap: wrap; }
.skin-home .joinform input {
  flex: 1 1 200px;
  min-width: 0;
  background: #120F0D;
  border: 2px solid rgba(233, 228, 218, 0.3);
  border-radius: 999px;
  color: var(--on-dark);
  padding: 14px 20px;
  font-size: 1rem;
  font-family: var(--font-body);
}
.skin-home .joinform input::placeholder { color: var(--on-dark-muted); opacity: 1; }

.skin-home .consent {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  max-width: 62ch;
  margin-top: 14px;
  text-align: left;
  color: var(--on-dark-muted);
  font-size: 0.8rem;
  line-height: 1.55;
  cursor: pointer;
}
.skin-home .consent input {
  display: inline-block;
  appearance: auto;
  -webkit-appearance: checkbox;
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  margin-top: 3px;
  accent-color: var(--sign-red);
  cursor: pointer;
}
.skin-home .consent a { text-decoration: underline; text-underline-offset: 2px; color: var(--on-dark); }

/* the honest velvet rope: no list yet, nothing sent, nothing saved */
.skin-home .rope {
  display: block;
  max-width: 520px;
  padding: 18px 20px;
  background: var(--butter);
  border: var(--key) solid var(--outline);
  border-radius: 16px;
  box-shadow: var(--lift) var(--lift) 0 var(--outline);
  color: var(--outline);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(1.05rem * var(--type-scale));
  letter-spacing: calc(0.5px + var(--type-tracking));
  text-transform: uppercase;
  line-height: 1.3;
}
.skin-home .rope small {
  display: block;
  margin-top: 9px;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 0.85rem;
  line-height: 1.55;
  letter-spacing: 0;
  text-transform: none;
  color: var(--patty);
}

/* ============================================================
   05 find us
   ============================================================ */

.skin-home .e1-visit { display: block; padding: 62px 0; background: var(--ink); }
.skin-home .open {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin: 0 0 14px;
  color: #4FD68C;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.85rem;
}
.skin-home .open .dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; background: #4FD68C; }

/* THE STATE HALF NEVER SPLITS (3a, 2026-08-23). On a real iPhone this badge
   broke as

       CLOSED          OPEN EVERY DAY, 12PM TO
       NOW        ·    10PM

   with "CLOSED NOW" torn across two lines and the separator dangling between
   two columns. Measured here with Range.getClientRects() over each text node -
   a count of span TOPS says one line and cannot see a wrap INSIDE a span, which
   is why a first pass reported no defect. At default text size the closed badge
   wrapped at 320, 360, 390 AND 430; at 1.15x and 1.3x (Dynamic Type) so did the
   open one.

   nowrap on the state alone, not on both: "CLOSED NOW" is two words that mean
   one thing, while the hours are a sentence and may break like one. flex-wrap
   lets the two halves stack as halves instead of the state tearing. */
.skin-home .open { flex-wrap: wrap; }
.skin-home .open-state { white-space: nowrap; }

/* AND THE SEPARATOR GOES WHEN THEY STACK, because a dot between two stacked
   lines is punctuation for a layout that no longer exists. CSS cannot ask
   "did this wrap", and a width breakpoint tuned to the loaded font is the trap
   CLAUDE.md already records - so this is keyed to the width below which
   measurement shows the badge stacking in EVERY state and text size, not to the
   width where it happens to fit today. The flex gap separates the halves on one
   line, and the closed state's own keyline pill separates them on two. */
@media (max-width: 620px) {
  .skin-home .open-sep { display: none; }
}
/* never colour alone as a state signal: the closed and unresolved states
   also lose the pill's weight and gain a keyline, so a colour-blind read
   still separates them */
.skin-home .open[data-open="closed"],
.skin-home .open[data-open="unknown"] {
  padding: 5px 13px;
  border: var(--key-soft) solid rgba(233, 228, 218, 0.35);
  border-radius: 999px;
  font-weight: 400;
}
.skin-home .e1-address {
  display: block;
  font-style: normal;
  color: var(--on-dark);
  font-size: 1.08rem;
  line-height: 1.65;
  margin-bottom: 6px;
}
.skin-home .e1-hours {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(clamp(1.1rem, 4vw, 1.5rem) * var(--type-scale));
  letter-spacing: calc(1px + var(--type-tracking));
  text-transform: uppercase;
  color: var(--cheese-gold);
  margin-bottom: 24px;
}

/* ============================================================
   footer
   ============================================================ */

.skin-home .e1-footer {
  display: block;
  position: relative;
  background: var(--deep);
  padding: 44px 0 28px;
  border-top: var(--key-soft) solid rgba(233, 228, 218, 0.12);
}
/* the pattern's other home, at the same near-subliminal strength */
.skin-home .e1-footer::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("./images/pattern-tile.svg");
  background-size: 240px 240px;
  opacity: var(--pattern-alpha);
  pointer-events: none;
}
.skin-home .e1-foot-grid {
  position: relative;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 26px;
  flex-wrap: wrap;
}
.skin-home .e1-foot-brand { display: flex; align-items: center; gap: 11px; }
.skin-home .e1-foot-links { display: flex; flex-direction: column; gap: 9px; min-width: 0; }
.skin-home .e1-foot-links a { color: #C9C4BC; font-size: 0.92rem; }
.skin-home .e1-foot-links a:hover { color: var(--on-dark); text-decoration: underline; text-underline-offset: 3px; }
.skin-home .e1-copy {
  position: relative;
  max-width: 1100px;
  margin: 26px auto 0;
  padding: 16px 20px 0;
  border-top: 1px solid rgba(233, 228, 218, 0.12);
  color: var(--on-dark-muted);
  font-size: 0.8rem;
  line-height: 1.6;
}

/* THE ORDER-SOON TOAST WENT WITH ITS MARKUP (2026-08-25) - see block 122. It
   was styled in TWO stylesheets, and the second copy was found only because
   the guard swept the tree rather than the file being edited. */

/* ============================================================
   the cookie notice — a NOTE, not a wall.

   Colours from D3 (bright cream ground, gold sticker buttons with
   black type at 8.8:1, hard black offset) at a compact scale.

   REBUILT 2026-07-25. It was correctly anchored to the bottom the
   whole time, but at 229px on a 360x844 phone it stood a third of
   the way up the screen and sat on top of the price list. The
   Director's call: it is the least important element on the page
   and was the most intrusive, which inverts the hospitality the
   notice exists for. Two fixes, and both matter:

     1. the copy was halved (Director-approved replacement, now
        canonical in docs/copy-deck.md), which is what actually
        buys the height back — layout alone could not;
     2. it RESERVES its own height via --cookienote-h, so the page
        pads out underneath it and no menu row is ever parked
        permanently behind it.

   Ceiling is now 150px on the SMALL phone (360x640), enforced by
   invariant 9 at both widths. max-height is a hard guarantee
   rather than a design choice — the typography round swaps the
   display face next, and an invariant should not be able to break
   on a font metric.

   The gold fill is also doing squint-test work: the cookie note
   must never be the red thing on screen, because ORDER is.
   ============================================================ */

.skin-home .cookienote {
  position: fixed;
  left: 8px;
  right: 8px;
  bottom: 10px;
  z-index: 60;
  display: block;
  max-width: 560px;
  max-height: 158px;
  overflow: auto;
  overscroll-behavior: contain;
  margin: 0 auto;
  background: var(--butter-hi);
  color: var(--outline);
  border: var(--key) solid var(--outline);
  border-radius: 16px;
  box-shadow: 5px 5px 0 var(--outline);
}
.skin-home .cookienote-inner { display: block; padding: 8px 13px 9px; }
.skin-home .cookienote-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
}
.skin-home .cookienote-h {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(0.98rem * var(--type-scale));
  line-height: 1.05;
  letter-spacing: calc(0.5px + var(--type-tracking));
  text-transform: uppercase;
  color: var(--outline);
}
.skin-home .cookienote-p {
  margin-top: 5px;
  font-size: 0.72rem;
  line-height: 1.3;
  color: var(--patty);            /* 5.6:1, and better than 5.6 on butter-hi */
}
.skin-home .cookienote-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 7px; }

/* THE TWO BUTTONS ARE ONE RULE. There is deliberately no second selector
   anywhere in this file that could ever style one of them differently: a
   demoted decline is a dark pattern no matter what the copy says. */
.skin-home .cookienote-btn {
  flex: 1 1 140px;
  display: inline-block;
  background: var(--cheese-gold);
  color: var(--outline);           /* 8.8:1 */
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(0.8rem * var(--type-scale));
  letter-spacing: calc(1px + var(--type-tracking));
  text-transform: uppercase;
  line-height: 1.1;
  text-align: center;
  padding: 8px 13px;
  border: var(--key-soft) solid var(--outline);
  border-radius: 999px;
  opacity: 1;
  cursor: pointer;
}
.skin-home .cookienote-fine {
  display: inline-block;
  flex: 0 0 auto;
  font-size: 0.7rem;
  line-height: 1.35;
  font-weight: 700;
  color: var(--patty);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ============================================================
   reduced motion — the marquee stops, nothing else moves.
   The buns and drips never animated, so there is nothing else
   here to turn off.
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  .skin-home .e1-ticker-track { animation: none; }
  .skin-home .e1-btn,
  .skin-home .isheet-order,
  .skin-home .joinform .btn,
  .skin-home .isheet-x,
  .skin-home .prow,
  .skin-home .e1-iglink { transition: none; }
  .skin-home .e1-btn:hover,
  .skin-home .isheet-order:hover,
  .skin-home .joinform .btn:hover { transform: none; }
}


/* ============================================================
   THE ITEM IMAGE — a sticker laid ON the card, not in it.

   The image is oversized, wider than the card, and the card's
   top edge crosses it at roughly its own lower third. Its top
   floats free on the section ground; its bottom lands inside the
   card's upper area. The card behind it carries name, blurb and
   price and nothing else: no frame, no inner box, no band.

   THE GEOMETRY, in two variables so it stays honest:
     --art       the image's size, deliberately >= the card width
     --art-rise  how much of it floats ABOVE the card's top edge

   Everything else is derived. The card reserves (art - rise) of
   top padding so its own text starts below the landing zone, the
   grid reserves `rise` of top padding so row 1 is not clipped by
   the heading above it, and the row gap carries `rise` so a
   phone-stacked image never lands on the card above.

   ON A PHONE the rise is TIGHTENED rather than the image shrunk
   (Director): --art stays big, --art-rise drops to about half,
   so the picture stays the loud thing and the stack stays sane.

   NO z-index ANYWHERE. The slot is positioned and comes first in
   its card, and each card is positioned, so paint order alone
   does the work — this section sits above <PriceList />, whose
   portalled sheet breaks if an ancestor gains a stacking context.

   NO transform either: the centring is left:50% + a negative
   margin, so nothing here can become a containing block.
   ============================================================ */

.skin-home .e1-featgrid {
  --art: 188px;
  --art-rise: calc(var(--art) * 0.64);
  position: relative;
  overflow: visible;                 /* the images break out of this box */
  padding-top: calc(var(--art-rise) + 10px);
  row-gap: calc(var(--art-rise) + 26px);
}
@media (max-width: 960px) {
  .skin-home .e1-featgrid { --art: 205px; }
}
@media (max-width: 560px) {
  /* one column: tighten the OVERLAP, never the picture */
  .skin-home .e1-featgrid { --art: 236px; --art-rise: calc(var(--art) * 0.48); }
}

.skin-home .e1-feat,
.skin-home .e1-bcard {
  position: relative;
  overflow: visible;
  padding-top: calc(var(--art) - var(--art-rise) + 12px);
}

.skin-home .cutslot--card {
  position: absolute;
  top: calc(var(--art-rise) * -1);
  left: 50%;
  margin-left: calc(var(--art) / -2);
  width: var(--art);
  height: var(--art);
  pointer-events: none;              /* decoration never eats a tap */
}
.skin-home .cutslot--card .cutslot-art,
.skin-home .cutslot--card .cutslot-cutout,
.skin-home .cutslot--card .cutslot-photo {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
/* Director, 2026-07-28: no frame around the food on a card. The keyline and the
   hard offset made every photo read as a boxed thumbnail sitting ON the card
   rather than as a sticker laid over it. The photo now floats free and keeps
   object-fit: contain from the rule above, so nothing is cropped to a box.
   The item sheet keeps its frame: there the photo IS the subject of the panel. */
.skin-home .cutslot--card .cutslot-photo {
  border: none;
  border-radius: 0;
  box-shadow: none;
}
/* no drawing and no photo: the plain honest state, still in the slot */
.skin-home .cutslot--card .cutslot-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 100%;
  padding: 16px;
  text-align: center;
  background: var(--butter-hi);
  border: var(--key) solid var(--outline);
  border-radius: 16px;
  box-shadow: 5px 5px 0 var(--outline);
}

/* the promise, now a caption rather than the whole card */
/* A CAPTION, not a headline. It sits first in the card, right under the
   drawing, which is where it belongs — but at full body size it was the loudest
   thing on the card and read as an apology. Small, and it stays above the rule
   that 4.5:1 would demand of body copy only because patty on cream is 5.6:1. */
.skin-home .cutslot-note {
  margin: 0 0 4px;
  font-family: var(--font-body);
  /* 0.75rem, NOT the 0.66rem this rule was ported with (2026-08-23). At 0.66 it
     measured 10.56px, under this project's own 11px floor — and block 54 would
     have failed on it, which is the floor doing its job.

     The size is not a detail here. This line is the ONLY thing telling a
     customer that the photograph beside an item's name and price is stock
     rather than that item. A disclosure set below the legibility floor is
     labelling in name only, and the whole point of invariant 14 is that the
     label be one a person actually reads. */
  font-size: 0.75rem;
  line-height: 1.45;
  letter-spacing: 0.2px;
  color: var(--patty);               /* 5.6:1 on cream — secondary-text legal */
}

.skin-home .cutslot-empty-h {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(0.9rem * var(--type-scale));
  line-height: 1.1;
  letter-spacing: calc(0.5px + var(--type-tracking));
  text-transform: uppercase;
  color: var(--outline);
}
.skin-home .cutslot-empty-p {
  font-size: 0.72rem;
  line-height: 1.4;
  color: var(--patty);
}

/* ---- the item sheet: the checkerboard STAYS here ---- */

.skin-home .isheet-media {
  display: block;
  position: relative;
  overflow: visible;
  line-height: 0;
  padding: 0 0 6px;
  /* Director, 2026-07-28: the photo was sized by its own aspect and pushed the
     build list off a 390px screen. Capped to a band, and the image is contained
     inside it so nothing is cropped through the food. */
  height: 208px;
}
/* Director, 2026-07-28: the photo is a subject sitting IN a band, not a
   full-bleed image. Cream ground, no checked paper, and the burger hangs past
   the band's lower keyline the way a cut-out breaks its frame. */
.skin-home .isheet-media {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  overflow: visible;
  height: 186px;
  padding: 0;
  background: var(--menu-ground, var(--butter));
  border-bottom: var(--key) solid var(--outline);
  border-radius: 19px 19px 0 0;
}
/* Director, 2026-07-28: no checkered surround. The stand-in is shot on checked
   paper, so the frame crops past it and sits on the food, lowered slightly so
   the burger is centred in the band rather than riding its top edge. */
.skin-home .isheet-media .isheet-img {
  width: auto;
  height: auto;
  max-width: 66%;
  max-height: 172px;
  object-fit: contain;
  margin-bottom: -22px;
  border: 0;
  border-radius: 0;
}
/* Q5 (Carlos, 2026-09-25): the drinks and the Single Combo draw larger in the
   item sheet (index.html SHEET_ART_BIG, block 236); the band grows with them.
   The phone's numbers are in the max-width:... block below. */
.skin-home .isheet-media:has(.isheet-img--big) { height: 230px; }
.skin-home .isheet-media .isheet-img--big { max-height: 216px; }
.skin-home .cutslot--sheet {
  position: relative;
  display: block;
  height: 196px;
  padding-top: 16px;
}
.skin-home .cutslot--sheet .cutslot-band {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 124px;
  background-color: var(--butter);
  background-image:
    conic-gradient(
      var(--sign-red) 25%,
      transparent 0 50%,
      var(--sign-red) 0 75%,
      transparent 0
    );
  background-size: 26px 26px;
  border-bottom: var(--key-soft) solid var(--outline);
  border-radius: 19px 19px 0 0;
}
/* the subject sits IN FRONT of the band and breaks past its lower edge */
.skin-home .cutslot--sheet .cutslot-art,
.skin-home .cutslot--sheet .cutslot-cutout,
.skin-home .cutslot--sheet .cutslot-photo,
.skin-home .cutslot--sheet .cutslot-empty {
  position: relative;
  display: block;
  height: 182px;
  max-height: 182px;
  width: auto;
  max-width: 88%;
  margin: 0 auto;
  object-fit: contain;
}
.skin-home .cutslot--sheet .cutslot-photo {
  object-fit: cover;
  border: var(--key) solid var(--outline);
  border-radius: 14px;
  box-shadow: 4px 4px 0 var(--outline);
}
.skin-home .cutslot--sheet .cutslot-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 16px 20px;
  text-align: center;
  background: var(--butter-hi);
  border: var(--key) solid var(--outline);
  border-radius: 16px;
  box-shadow: 4px 4px 0 var(--outline);
}
.skin-home .cutslot--sheet + .cutslot-note {
  margin: 2px 0 0;
  padding: 0 20px;
  text-align: center;
}

/* ---- the card, restyled around the image ----
   Name in the brand red at 1.55rem (24.8px at scale 1) and NOT smaller: sign
   red on cream is 4.06:1, which fails body text and only clears the 3:1 bar as
   LARGE text at 24px+. The size is load-bearing, not taste; invariant 12 pins
   it. The price stays outline black and quiet — red would fail outright at
   that size, and a loud price fights the picture above it. */
.skin-home .e1-feat-name {
  font-size: calc(1.55rem * var(--type-scale));
  color: var(--sign-red);
}
.skin-home .e1-feat-price-t { font-size: calc(0.95rem * var(--type-scale)); }

/* ============================================================
   THE EDITABLE BUILD SHEET (behind ORDERING_LIVE)

   The modal IS the ordering step: tap a burger, strip it down
   right there, order it, move on. No separate customization
   screen.

   The satisfying part is the list SHRINKING as it is stripped,
   so the remove control stays quiet until touched and the
   remaining lines settle quickly rather than sliding around.

   Nothing is lost when a line leaves: it reappears on the ticket
   below in the kitchen's own words, and tapping it puts it back.

   DEFAULT STATE IS UNCHANGED. With the flag off, none of these
   controls render at all — not disabled, absent — and the sheet
   is the read-only list it has always been with the call-in line
   underneath.
   ============================================================ */

.skin-home .isheet-build-row {
  display: flex;
  align-items: center;
  gap: 10px;
}
/* the line's own text takes the slack so the control sits hard right */
.skin-home [data-build-editable] .isheet-build-label { flex: 1 1 auto; min-width: 0; }

/* 44px touch target, but a SMALLER visible sticker inside it: the thumb gets
   the area the guidance asks for without a heavy button on every row. */
.skin-home .isheet-build-x {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin: -8px -6px -8px 0;      /* the target overhangs the row, the ink does not */
  padding: 0;
  background: none;
  border: 0;
  color: var(--patty);
  cursor: pointer;
  border-radius: 999px;
}
.skin-home .isheet-build-x span {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  font-size: 1rem;
  line-height: 1;
  border: var(--key-soft) solid currentColor;
  border-radius: 999px;
  transition: background-color 0.12s ease, color 0.12s ease;
}
/* quiet until touched */
.skin-home .isheet-build-x:hover span,
.skin-home .isheet-build-x:focus-visible span {
  background: var(--sign-red);
  border-color: var(--outline);
  color: #fff;                    /* 5.3:1 on sign red */
}
.skin-home .isheet-build-x:active span { transform: scale(0.92); }

/* ---- the ticket ---- */

.skin-home .isheet-ticket {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 2px dashed rgba(20, 16, 14, 0.35);
}
.skin-home .isheet-ticket-h {
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(0.8rem * var(--type-scale));
  letter-spacing: calc(0.8px + var(--type-tracking));
  text-transform: uppercase;
  color: var(--patty);
}
.skin-home .isheet-ticket-list { list-style: none; margin: 0; padding: 0; display: block; }
.skin-home .isheet-ticket-list li { display: block; margin-bottom: 6px; }

/* a ticket line reads like the kitchen's own paper, and the whole line is the
   undo target so the thumb never has to find a small control */
.skin-home .isheet-ticket-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  min-height: 44px;
  padding: 8px 12px;
  text-align: left;
  background: var(--butter-hi);
  border: var(--key-soft) solid var(--outline);
  border-radius: 8px;
  cursor: pointer;
}
.skin-home .isheet-ticket-text {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(0.92rem * var(--type-scale));
  letter-spacing: calc(0.6px + var(--type-tracking));
  text-transform: uppercase;
  color: var(--outline);          /* 14.4:1 */
}
.skin-home .isheet-ticket-undo {
  flex: 0 0 auto;
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--patty);            /* 5.6:1 */
  text-decoration: underline;
  text-underline-offset: 3px;
}
.skin-home .isheet-ticket-line:hover,
.skin-home .isheet-ticket-line:focus-visible { background: var(--cheese-gold); }

/* the settle: quick, and off entirely for anyone who asked for less motion */
@media (prefers-reduced-motion: no-preference) {
  .skin-home .isheet-build-list { transition: none; }
  .skin-home .isheet-ticket-list li {
    animation: st-ticket-in 0.14s ease-out both;
  }
}
@keyframes st-ticket-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}

/* ============================================================
   CATERING (S0f) — the highest-value order the shop takes.

   Quiet on purpose. It sits between the list and the address,
   and it must not fight the menu or the descent: no new ground
   colour, no band, no second red button competing with ORDER.
   It reads as the counter telling you something useful.

   The action is a phone call, and the call is the only control
   here. See components/Catering.tsx for why there is no form.
   ============================================================ */

/* Director, 2026-07-28: this was a cream section sitting between the dark list
   and the dark find-us, so it read as a slab of the menu that had escaped. The
   descent already ended at the heel bun — everything after the menu belongs to
   the dark half of the walk, catering included. */
.skin-home .cater {
  padding: 44px 0 52px;
  background: var(--surface);
  color: var(--on-dark);
}
/* Director, 2026-07-28: catering was the only section on a 860px measure, so
   its heading sat 120px inboard of every other section. Same 1100px wrap and
   same 20px gutter as the menu, the list and the neighbourhood. */
.skin-home .cater .wrap {
  max-width: 1100px;
  padding: 0 20px;
  margin: 0 auto;
}
.skin-home .cater h2 {
  margin: 0 0 12px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(2rem * var(--type-scale));
  line-height: 1.02;
  letter-spacing: calc(0.5px + var(--type-tracking));
  text-transform: uppercase;
  color: var(--on-dark);              /* 13.9:1 on the surface */
}
.skin-home .cater-lede {
  margin: 0 0 20px;
  max-width: 46ch;
  font-size: 1rem;
  line-height: 1.5;
  color: var(--on-dark-muted);        /* 7.4:1 */
}
.skin-home .cater-ready {
  margin: 0 0 10px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(0.85rem * var(--type-scale));
  letter-spacing: calc(0.8px + var(--type-tracking));
  text-transform: uppercase;
  color: var(--cheese-gold);          /* gold is legal as type on the dark */
}
.skin-home .cater-list {
  margin: 0 0 26px;
  padding: 0;
  list-style: none;
  max-width: 46ch;
}
/* the marker is a drawn rule, not a bullet glyph and never an emoji */
.skin-home .cater-list li {
  position: relative;
  padding: 0 0 0 22px;
  margin-bottom: 8px;
  font-size: 0.95rem;
  line-height: 1.45;
  color: var(--on-dark);
}
.skin-home .cater-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 12px;
  height: 3px;
  background: var(--sign-red);        /* a fill, never type: 4.06:1 is legal as ink */
  border-radius: 2px;
}
.skin-home .cater-call {
  display: inline-block;
  margin-bottom: 14px;
}
.skin-home .cater-note {
  margin: 0;
  max-width: 46ch;
  font-size: 0.82rem;
  line-height: 1.45;
  color: var(--on-dark-muted);        /* 7.4:1 */
}

/* ---- the ending: what to say when you call ----
   It replaces the plain call-in line only once the customer has actually
   changed something. Louder than that line, because at that moment it is the
   most useful thing on the screen, but it is NOT a receipt and must never read
   like one: no order number, no total, no "on its way". */
.skin-home .isheet-say {
  margin-top: 16px;
  padding: 14px 16px 16px;
  background: var(--butter-hi);
  border: var(--key-soft) solid var(--outline);
  border-radius: 12px;
}
.skin-home .isheet-say-line {
  margin: 0 0 10px;
  font-size: 0.92rem;
  line-height: 1.45;
  color: var(--patty);                /* 5.6:1 */
}
.skin-home .isheet-say-words {
  display: block;
  margin-top: 4px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(1.05rem * var(--type-scale));
  letter-spacing: calc(0.6px + var(--type-tracking));
  text-transform: uppercase;
  color: var(--outline);              /* 14.4:1 */
}
.skin-home .isheet-say-call {
  display: inline-block;
  margin-bottom: 8px;
  padding: 12px 22px;
  background: var(--sign-red);
  color: #fff;                        /* 5.3:1 on sign red */
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(1rem * var(--type-scale));
  letter-spacing: calc(1px + var(--type-tracking));
  text-transform: uppercase;
  line-height: 1.15;
  border: var(--key) solid var(--outline);
  border-radius: 999px;
  box-shadow: 4px 4px 0 var(--outline);
}
.skin-home .isheet-say-note {
  margin: 0;
  font-size: 0.76rem;
  line-height: 1.4;
  color: var(--patty);
}

/* ============================================================
   THE CART (S04.1) — a real cart, client-side.

   The indicator floats above the page but NEVER over the item
   sheet: the sheet is a portalled dialog and paints later, so
   paint order handles it without a z-index war. It sits clear of
   the cookie notice by riding the same --cookienote-h the skin
   already reserves.
   ============================================================ */

.skin-home .cartbtn {
  position: fixed;
  left: 50%;
  margin-left: -100px;
  width: 200px;
  bottom: calc(var(--cookienote-h, 0px) + 18px);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 52px;                  /* well past the 44px thumb floor */
  padding: 12px 20px;
  background: var(--sign-red);
  color: #fff;                       /* 5.3:1 on sign red */
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(1rem * var(--type-scale));
  letter-spacing: calc(1px + var(--type-tracking));
  text-transform: uppercase;
  border: var(--key) solid var(--outline);
  border-radius: 999px;
  box-shadow: 5px 5px 0 var(--outline);
  cursor: pointer;
}
.skin-home .cartbtn-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 26px;
  height: 26px;
  padding: 0 6px;
  background: var(--cheese-gold);
  color: var(--outline);             /* 8.8:1 on gold — the sticker device */
  border: var(--key-soft) solid var(--outline);
  border-radius: 999px;
  font-size: 0.86rem;
}

/* ---- the review sheet ---- */

.skin-home .cart-empty {
  margin: 8px 0 0;
  font-size: 0.95rem;
  color: var(--patty);
}
.skin-home .cart-lines { list-style: none; margin: 14px 0 0; padding: 0; }
.skin-home .cart-line {
  padding: 14px 0;
  border-top: var(--key-soft) solid rgba(20, 16, 14, 0.28);
}
.skin-home .cart-line-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.skin-home .cart-line-name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(1.05rem * var(--type-scale));
  letter-spacing: calc(0.4px + var(--type-tracking));
  text-transform: uppercase;
  color: var(--outline);
}
.skin-home .cart-line-price { font-size: 0.95rem; color: var(--outline); }
.skin-home .cart-line-mods { list-style: none; margin: 6px 0 0; padding: 0; }
/* the removals in the kitchen's words, quieter than the item name */
.skin-home .cart-line-mod {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(0.78rem * var(--type-scale));
  letter-spacing: calc(0.5px + var(--type-tracking));
  text-transform: uppercase;
  color: var(--patty);               /* 5.6:1 */
}
.skin-home .cart-line-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 10px;
}
.skin-home .cart-qty { display: flex; align-items: center; gap: 4px; }
.skin-home .cart-qty-btn {
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.2rem;
  line-height: 1;
  background: var(--butter-hi);
  color: var(--outline);
  border: var(--key-soft) solid var(--outline);
  border-radius: 999px;
  cursor: pointer;
}
.skin-home .cart-qty-n {
  min-width: 34px;
  text-align: center;
  font-family: var(--font-display);
  font-size: calc(1rem * var(--type-scale));
  color: var(--outline);
}
.skin-home .cart-line-remove {
  min-height: 44px;
  padding: 0 6px;
  background: none;
  border: 0;
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--patty);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.skin-home .cart-sub {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-top: 16px;
  padding-top: 12px;
  border-top: 2px dashed rgba(20, 16, 14, 0.35);
  font-family: var(--font-display);
  font-size: calc(1.1rem * var(--type-scale));
  letter-spacing: calc(0.4px + var(--type-tracking));
  text-transform: uppercase;
  color: var(--outline);
}
.skin-home .cart-sub-note {
  margin: 6px 0 0;
  font-size: 0.78rem;
  color: var(--patty);
}

/* ---- the honest ending, and the seam for S02 ---- */
.skin-home .cart-next {
  margin-top: 18px;
  padding: 14px 16px 16px;
  background: var(--butter-hi);
  border: var(--key-soft) solid var(--outline);
  border-radius: 12px;
}
.skin-home .cart-next-h {
  margin: 0 0 6px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(0.95rem * var(--type-scale));
  letter-spacing: calc(0.6px + var(--type-tracking));
  text-transform: uppercase;
  color: var(--outline);
}
.skin-home .cart-next-p {
  margin: 0 0 10px;
  font-size: 0.85rem;
  line-height: 1.45;
  color: var(--patty);
}
.skin-home .cart-next-call {
  display: inline-block;
  min-height: 44px;
  padding: 11px 0 0;
  font-family: var(--font-display);
  font-size: calc(1.05rem * var(--type-scale));
  letter-spacing: calc(0.6px + var(--type-tracking));
  color: var(--outline);
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* ============================================================
   THE MENU LAYOUT PASS (2026-07-26, Director's list).

   a. COLUMN BALANCE. The two columns were a GRID, so categories
      sat in locked rows and every row grew to its tallest cell —
      Nashville Hot Chicken was padded out to Burgers' height and
      left ~600px of dead space. Multi-column FLOW instead: each
      category starts where the last one ended.
   c. THE DRIPS all pour ONE colour now. Five different fills at
      22px read as five different smudges, and --ember in
      particular read as dirt. Variation comes from the profile
      alone, which is what "controlled variation" means.
   d. HEADER. Icon, sticker and rule are locked to one baseline
      with fixed gaps instead of drifting on flex defaults.
   e. NOTHING IS COVERED. The cart pill reserves its own height
      the same way the cookie notice does, so the last menu rows
      cannot end up parked underneath it.
   f. RHYTHM. One spacing scale between category groups.
   ============================================================ */

/* (e) both fixed overlays reserve their own space, and they stack
   rather than overlap: the pill sits ABOVE the notice.

   THIS USED TO READ `calc(var(--cookienote-h) + var(--cartbtn-h) + 46px)` AND
   --cartbtn-h WAS PUBLISHED BY NOTHING - one consumer, no producer, anywhere in
   the demo. So the pill's whole reserve was the typed 46, and a typed reserve
   beside a fixed element is wrong in both directions at once. Measured at
   1280x800 with consent stored:

     cart EMPTY   no pill exists, yet 46px of .tail-a ground still sat below the
                  footer - and .tail-a paints rgb(17,13,9) against the footer's
                  rgb(14,11,9), so it read as a lighter empty strip rather than
                  blending away. That is the "dead space below the footer".
     cart LOADED  the pill occupies 74px (bottom:18px + its 56px box) against a
                  46px reserve. Rect intersection with the footer, both axes:
                  200 x 27.84px, with .wrap.footbase behind it. On a phone the
                  same sum is 126 vs 97 and elementFromPoint at .footcopy's
                  centre returned div.cartbtn.

   --cartbtn-reserve is published BY THE BUTTON (index.html, cartBtnRef) as the
   pixels it occupies up from the viewport floor, and set to 0px when sc-if
   unmounts it. max() then picks whichever of the two overlays actually needs
   more room, and the empty-cart case falls back to the notice's own clearance
   with no constant left to be wrong. */
.skin-home {
  padding-bottom: max(
    calc(var(--cookienote-h, 0px) + 12px),
    calc(var(--cartbtn-reserve, 0px) + 12px)
  );
}

/* (a) INDEPENDENT COLUMN FLOW — and this REVERSES slice 6a, which itself
   reversed the flow that was here before it. Director's ruling 2026-08-23,
   Carlos having looked at the laptop layout. Both directions are recorded
   because this has now been decided twice and the losing side has a real cost
   each time.

   WHAT SLICE 6a BOUGHT AND THIS GIVES BACK. A grid pairs the categories into
   rows, so two categories sharing a row share a heading baseline. A flow packs
   each column independently, so ONLY the two categories at the top of the
   columns can ever line up — measured in the flow, Burgers and Fries aligned
   exactly (both headings at 14px) and nothing below them did: Nashville sat at
   760.55 against Sides at 351.64. That misalignment is the price of this rule
   and it is not a bug to be fixed later.

   WHAT THE GRID COST, which is what Carlos was looking at when he ruled. Each
   row is as tall as its taller cell and the difference is void:

     Burgers 746.8  vs  Nashville Hot Chicken 293.7   ->  453.1px of nothing
     Hot Dogs 374.3 vs  Fries 337.7                   ->   36.7px
     Sides   502.3  vs  Drinks 265.8                  ->  236.6px

   Worst beside Nashville and beside Drinks, which is exactly what he reported.

   THE SAME TRADE, MEASURED FROM BOTH SIDES ON DIFFERENT DAYS, and the numbers
   agree to within a pixel — which is the useful part of having done it twice:

     slice 6a  "the flow left 308.78px of dead space at the foot of the shorter
                column; this grid costs +208.61px of total height"
     today     the flow's ragged bottom measures 323px; the grid is 208.7px
                taller (1623.5 vs 1414.8)

   So nobody is disagreeing about the facts. The ruling is a preference between
   two real costs: a hole beside a heading, or headings that do not line up.
   Carlos has now chosen the second, having seen the first.

   WHY NOT REORDER INSTEAD (option B, rejected): pairing Burgers with Sides cut
   the worst void to 244.4px, but it put Nashville Hot Chicken fifth of six
   under Sides on a burger-and-chicken menu — and because `order` only applies
   above 760px it would have made the desktop and the phone present different
   sequences. This flow keeps SOURCE ORDER, so the two agree.

   break-inside: avoid is load-bearing, not tidiness: without it a category
   splits across the column break and price rows land under a heading they do
   not belong to.

   THE ITEM SHEET WAS CHECKED BEFORE THIS LANDED, with a positive control. The
   sheet is NOT a descendant of .pricelist here — its ancestor chain is
   div.skin-home < div.sc-host < div < body — so a fragmentation context on this
   element cannot reach it, and it measured on top at 390/768/1280/1440/1920
   with the flow applied. The control (transform on .skin-home, a REAL shared
   ancestor) did trap it: top 63 -> 1056.4, elementFromPoint null. An earlier
   control aimed at .pricelist did NOT trap, which is how the wrong target was
   caught — CLAUDE.md's "any ancestor of <PriceList />" describes the Next site,
   where the sheet is portalled inside the component. */
@media (min-width: 760px) {
  .skin-home .pricelist {
    columns: 2;
    column-gap: 56px;
  }
  .skin-home .pcat {
    break-inside: avoid;
    -webkit-column-break-inside: avoid;
    page-break-inside: avoid;
  }
  /* N4 (Carlos 2026-09-24, alignment only): a heading's 14px top margin is
     TRUNCATED at a column break but kept at the top of the multicol box, so
     column 1's first heading sat 14.00px below column 2's. Written with more
     specificity (0,4,0) than the `margin` shorthand below (0,2,0), which would
     otherwise set it back - the shorthand-beats-longhand trap. Two columns only:
     on the phone the margin collapses out of the list, so nothing there moves
     (block 50.4). */
  .skin-home .pcat:first-child .pcat-title { margin-top: 0; }
}

/* (f) ONE spacing scale. --cat-gap is the only vertical number that
   separates category groups; everything else derives from it. */
.skin-home .pricelist { --cat-gap: 34px; }
.skin-home .pcat { padding: 0 0 var(--cat-gap); }
.skin-home .pcat-drip { display: block; margin: 0 0 -4px; }
.skin-home .pcat:first-child .pcat-drip { margin-top: 0; }

/* (c) one pour, one colour. Patty brown is 5.6:1 on cream, it is the
   sauce colour, and it survives being 22px tall. */
.skin-home .pcat[data-cat="1"],
.skin-home .pcat[data-cat="2"],
.skin-home .pcat[data-cat="3"],
.skin-home .pcat[data-cat="4"],
.skin-home .pcat[data-cat="5"],
.skin-home .pcat[data-cat="6"] { --drip-fill: var(--patty); }

/* (d) icon | sticker | rule, on one line with fixed gaps */
.skin-home .pcat-title {
  display: grid;
  grid-template-columns: 26px auto minmax(24px, 1fr);
  align-items: center;
  gap: 0 12px;
  margin: 14px 0 6px;
}
.skin-home .pcat-rule { align-self: center; margin: 0; }

/* (b) the compacted box: one border, one row per board group */
.skin-home .pmods { margin: 16px 0 0; padding: 12px 14px; }
.skin-home .pmods-row + .pmods-row {
  margin-top: 10px;
  padding-top: 10px;
  border-top: var(--key-soft) solid rgba(20, 16, 14, 0.14);
}
.skin-home .pmods-h { margin: 0 0 2px; }
.skin-home .pmods-list { line-height: 1.5; }


/* ============================================================
   THE RETURN TRIP, 2026-07-28 (Director).

   "I love the colors back here, can the same be used after the menu."
   The hero's ground is not flat ink: it is ink with amber bleeding from
   the top right and sign red from the bottom left, which is what makes it
   read as a room you are standing in rather than a dark rectangle. Every
   section after the heel bun was flat --ink or --surface, so the second
   half of the walk lost the light the first half had.

   Same two washes, at roughly half strength, laid over each section's own
   ground so the ink and surface steps are still distinct. Alternating the
   corner they enter from keeps four stacked sections from reading as one
   long gradient. Nothing new in the palette, and no colour lands on type.
   ============================================================ */

.skin-home .e1-hood,
.skin-home .join,
.skin-home .cater,
.skin-home .e1-visit {
  background-image:
    radial-gradient(900px 460px at 78% 6%, rgba(232, 163, 58, 0.13), transparent 58%),
    radial-gradient(820px 420px at 6% 100%, rgba(200, 50, 42, 0.16), transparent 62%);
}
/* the entry corner flips on alternate sections */
.skin-home .join,
.skin-home .e1-visit {
  background-image:
    radial-gradient(900px 460px at 18% 6%, rgba(232, 163, 58, 0.11), transparent 58%),
    radial-gradient(820px 420px at 92% 100%, rgba(200, 50, 42, 0.15), transparent 62%);
}
/* the footer keeps its own deeper ground: the page has to land somewhere */


/* ============================================================
   Director, 2026-07-28: the lower half of the page read as four
   stacked panels. Each dark section carried its OWN ground
   (#0A0A0A, #16120F, #16120F, #0A0A0A, footer #070707) and its own
   pair of glows, so every boundary was a visible edge and the
   light restarted five times.

   One ground now, on the skin, with the glow placed once. The
   sections below the menu are transparent and sit on it, so the
   dark run from the story to the footer is continuous. The cream
   menu and the ember and patty bands are opaque and still cut
   across it, which keeps the descent intact.
   ============================================================ */
.skin-home {
  background-color: #0E0B09;
  background-image:
    radial-gradient(1200px 620px at 8% calc(100% - 1780px), rgba(232, 163, 58, 0.10), rgba(0, 0, 0, 0) 60%),
    radial-gradient(1100px 640px at 94% calc(100% - 980px), rgba(200, 50, 42, 0.15), rgba(0, 0, 0, 0) 62%),
    radial-gradient(900px 520px at 20% calc(100% - 120px), rgba(232, 163, 58, 0.06), rgba(0, 0, 0, 0) 64%);
  background-repeat: no-repeat;
}
.skin-home .e1-hood,
.skin-home .join,
.skin-home .cater,
.skin-home .e1-visit,
.skin-home .e1-footer {
  background-color: transparent;
  background-image: none;
}


/* ---- Visit: the map beside the facts -------------------------------------
   The section was four stacked bands with the right half empty. Facts left,
   map right, both as die-cut stickers on the dark ground. Stacks at 720px so
   390 is unchanged. No emoji anywhere: the labels carry no pictogram rather
   than a pin, a phone and a clock the icon set does not contain. */
.skin-home .e1-visit-grid {
  display: grid;
  gap: 22px;
  align-items: stretch;
  text-align: left;
  margin-top: 26px;
}
.skin-home .e1-visit-facts {
  display: flex;
  flex-direction: column;
  gap: 16px;
  align-items: flex-start;
  justify-content: center;
}
.skin-home .e1-map {
  position: relative;
  border: var(--key) solid var(--outline);
  border-radius: 20px;
  overflow: hidden;
  background: #14100E;
  min-height: 260px;
  box-shadow: 5px 5px 0 var(--outline);
}
.skin-home .e1-map iframe {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 260px;
  border: 0;
  /* the map is a light photograph of a street grid dropped into a dark page,
     so it is knocked back to sit in the ground rather than glare out of it */
  filter: saturate(0.85) brightness(0.92) contrast(1.04);
}
@media (min-width: 721px) {
  .skin-home .e1-visit-grid {
    grid-template-columns: 0.85fr 1.15fr;
    gap: 26px;
  }
  .skin-home .e1-map,
  .skin-home .e1-map iframe { min-height: 340px; }
}


/* 🔴 THE ALLERGY LINE IS NOT A FOOTNOTE, AND IT MUST NOT BE TIDIED BACK INTO
   ONE (S133, 2026-09-13). It was 0.85rem in patty brown, under a comment that
   called it "quiet". It reads as a design choice. It is not one.

   NEW YORK PUBLIC HEALTH LAW § 1356(5), in force since May 2025, requires a
   food service establishment to display allergy notification information "in a
   CONSPICUOUS MANNER" - and it applies to a single location, with no
   chain-size threshold. $125 per violation. The statute prescribes the
   wording, which is why index.html carries it verbatim and block 214.1 pins
   the string: "If you have a food allergy or intolerance, please notify us."

   So the two properties below are LEGAL REQUIREMENTS wearing CSS, not taste:

     - font-size matches .prow-name (0.97rem), the menu region's primary
       reading line. A sentence smaller than the item names beside it is not
       conspicuous, whatever else is true of it.
     - color is var(--outline), which this project MEASURED at 14.4:1 on the
       cream ground (CLAUDE.md, "Colour law"). var(--patty) is 5.6:1 - legal
       for secondary copy, and this line is not secondary.

   Block 214.2 asserts both from getComputedStyle on every surface that carries
   the line, so shrinking it or softening it fails the suite rather than
   quietly re-committing the violation. */
.skin-home .pallergy {
  margin: 18px 0 0;
  font-family: var(--font-body);
  font-size: 0.97rem;
  line-height: 1.5;
  color: var(--outline);
  max-width: 68ch;
}


/* ---------------------------------------------------------------------------
   The global footer, matched to components/Footer.tsx so every route on the
   site closes identically. Replaces the old .e1-footer, which was E1's own.
   Dark ground: gold is legal as type here, outline black is not.
   --------------------------------------------------------------------------- */
.skin-home .footer {
  background: var(--ground, #0E0B09);
  color: #E9E4DA;
  border-top: var(--key-soft) solid rgba(233, 228, 218, 0.1);
  padding: 54px 0 0;
}
.skin-home .footgrid {
  display: grid;
  grid-template-columns: 1.1fr 1fr 1fr;
  gap: 40px;
  align-items: start;
}
.skin-home .footbrand { display: flex; flex-direction: column; gap: 18px; align-items: flex-start; }
.skin-home .footbrand .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 11px 26px 9px;
  color: #FFF8EC;
  background: var(--sign-red);
  border: 3px solid var(--outline);
  border-radius: 999px;
  /* the footer's own red button takes the same glow token as every other:
     it is a red button, and the sweep in tests/demo-glow-reviews.spec.ts
     finds red buttons by their FILL, not by a class list, so an override
     that quietly opted out would fail the suite rather than ship dim */
  box-shadow: 3px 3px 0 var(--outline), var(--glow-btn);
  text-decoration: none;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.15rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1;
}
/* the footer's ORDER NOW hovers exactly like every other red button now
   (slice 26). Its inverting override lived HERE and, identically, 2,350 lines
   earlier - which is how a per-element rule survives a cleanup: you delete the
   one you found. It is a member of the shared hover and active groups above. */
.skin-home .footbrand .logo { display: flex; align-items: center; gap: 11px; text-decoration: none; }
.skin-home .footbrand .mark { width: 40px; height: 40px; display: block; }
.skin-home .footbrand .word {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.5rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: #FFF8EC;
}
.skin-home .footbrand .word b { color: var(--sign-red); font-weight: 800; }
.skin-home .foottag {
  margin: 0;
  font-family: var(--font-body);
  font-size: 0.95rem;
  line-height: 1.55;
  color: #C6B9A6;
}
.skin-home .footh {
  margin: 8px 0 16px;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.05rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cheese-gold);
}
/* three groups, not one loose run of lines: place, hours, phone. Grouped by
   spacing so each wraps as a block instead of orphaning a word onto its own row. */
.skin-home .footaddr {
  display: flex;
  flex-direction: column;
  gap: 14px;
  font-family: var(--font-body);
  font-style: normal;
  font-size: 0.95rem;
  line-height: 1.55;
  color: #E9E4DA;
}
.skin-home .footaddr-line { display: block; }
.skin-home .footaddr-tel {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.25rem;
  letter-spacing: 0.02em;
}
.skin-home .footaddr a { color: #E9E4DA; text-decoration: none; }
.skin-home .footaddr a:hover { color: var(--cheese-gold); }
.skin-home .footlinks { display: flex; flex-direction: column; gap: 8px; }
.skin-home .footlinks a {
  font-family: var(--font-body);
  font-size: 0.95rem;
  line-height: 1.5;
  color: #E9E4DA;
  text-decoration: none;
}
.skin-home .footlinks a:hover { color: var(--cheese-gold); }
/* 🔴 THE HEALTH-GRADE LINK IS A LEGAL REQUIREMENT, NOT FOOTER FURNITURE
   (S133, 2026-09-13). NYC Administrative Code § 17-195.1 requires a food
   service establishment accepting DELIVERY orders online to post a link to the
   Health Department's inspection-grade lookup "conspicuously". $100 per
   violation.

   THREE PROPERTIES ARE LOAD-BEARING AND BLOCK 214.4 ASSERTS EACH BY NAME:

     - flex-basis 100% gives it its OWN ROW inside .footbase. As a third item in
       that space-between row it would land between the copyright and "Tell us
       how we did" and read as a third piece of small print.
     - font-size matches .footlinks a (0.95rem) - the footer's own body size,
       not .footcopy's 0.8rem small print. "Conspicuously" is the standard.
     - color #E9E4DA is the footer's body colour on its dark ground, where the
       cream palette's var(--outline) is NOT usable as type (CLAUDE.md, "Colour
       law"). The link underlines so it reads as a link without a second colour.

   ⚠️ NO display:none AT ANY BREAKPOINT, and 214.4 measures that at 320/360/390
   rather than reading the stylesheet. A responsive rule that hides it is the
   violation with extra steps. */
.skin-home .foothealth {
  flex: 1 0 100%;
  margin: 0;
  font-family: var(--font-body);
  font-size: 0.95rem;
  line-height: 1.6;
  color: #E9E4DA;
}
.skin-home .foothealth-link { color: #E9E4DA; text-decoration: underline; }
.skin-home .foothealth-link:hover { color: var(--cheese-gold); }
.skin-home .footbase {
  display: flex;
  /* ALIGN ON THE TEXT, NOT ON THE BOXES (3c, 2026-08-23). Measured on iPhone 14:
     .footcopy's line box sat at top 525.03 and .footsuggest's at 537.11 - 12.08px
     apart, with identical 12.8px/19.84px type and identical 15px line heights. So
     nothing typographic separated them; the row was `align-items: normal`, which
     stretches two boxes of different heights and lets their text land wherever.
     They read as one row and now sit on one baseline. */
  align-items: baseline;
  flex-wrap: wrap;
  gap: 10px 24px;
  justify-content: space-between;
  margin-top: 38px;
  padding: 18px 0 26px;
  border-top: var(--key-soft) solid rgba(233, 228, 218, 0.1);
}
.skin-home .footcopy {
  margin: 0;
  font-family: var(--font-body);
  font-size: 0.8rem;
  color: #8A7F70;
}
@media (max-width: 720px) {
  .skin-home .footgrid { grid-template-columns: 1fr; gap: 34px; }
  .skin-home .footbase { margin-top: 34px; }
}


.skin-home .footer .wrap {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 20px;
}


/* ---- the item sheet on a phone: a centred window, not a full screen ----

   It was anchored to the bottom at 100% width with a 88dvh ceiling, so on a
   390 screen it filled everything, squared off against both edges, and the
   build list still ran past the fold. Centred by auto margins on all four
   sides (never a transform — a transform anywhere above PriceList becomes the
   containing block for this fixed sheet and traps it), sized to its content,
   with the inner body doing the scrolling instead of the page. */
@media (max-width: 699px) {
  .skin-home .isheet {
    inset: 0;
    margin: auto;
    width: min(354px, 92vw);
    height: fit-content;
    max-height: 88dvh;
    border: var(--key) solid var(--outline);
    border-radius: 20px;
    box-shadow: 5px 5px 0 var(--outline);
    overflow: hidden;
    display: flex;
    flex-direction: column;
  }
  /* the sheet keeps its keyline and radius; the body inside it scrolls */
  .skin-home .isheet-inner {
    overflow: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 16px;
  }
  /* a shorter band so name, price, description, the build list and the CTA all
     land inside the window on a 390 screen */
  .skin-home .isheet-media { height: 116px; }
  .skin-home .isheet-media .isheet-img {
    max-height: 110px;
    max-width: 70%;
    margin-bottom: -14px;
  }
  /* Q5: the drinks and the Single Combo draw larger (index.html SHEET_ART_BIG);
     the band grows with them so nothing is cropped (block 236) */
  .skin-home .isheet-media:has(.isheet-img--big) { height: 150px; }
  .skin-home .isheet-media .isheet-img--big { max-height: 144px; }
  .skin-home .isheet-body { padding-top: 12px; }
  .skin-home .isheet-desc { margin-bottom: 8px; }
  /* 24, which is the phone's OWN old total (10 margin + 14 padding) kept
     whole. 18 was the first cut and it lost 6px of separation while the
     comment claimed the space was preserved. */
  .skin-home .isheet-build { margin-top: 24px; }
  .skin-home .isheet-build-h { margin-bottom: 4px; }
  .skin-home .isheet-build-row { padding: 5px 0; }
  .skin-home .isheet-cta { padding-top: 10px; }
}


/* ============================================================
   PART 1 punch list, measured at 390
   ============================================================ */

/* 1.1 — the Accessibility link's bottom edge and the copyright row's top edge
   were both at 9307px: a gap of zero, which reads as clipped. The rule now sits
   in its own space rather than against the last link. */
.skin-home footer .wrap.footbase {
  margin-top: 26px;
  padding-top: 20px;
  border-top: 2px solid rgba(233, 228, 218, 0.14);
}

/* 1.2 — five stacked legal links at 23px tall on a 31px pitch. The thumb floor
   on this project is 44px, and the link most likely to be mis-tapped is the
   accessibility one, which is the link a person with a motor impairment needs
   most. Grown with padding on the anchor, not with gaps between them, so the
   targets reach 44px without the column getting taller than it needs to be. */
.skin-home .footlinks { display: flex; flex-direction: column; gap: 0; }
.skin-home .footlinks a {
  display: block;
  padding: 10.5px 0;
  min-height: 44px;
  box-sizing: border-box;
}

/* 1.4 — DESIGN.md deviation B: body copy is never pure white. Pure white on
   near-black glares on a phone at night, which is when this shop is busiest.
   Button labels in white on sign red stay: that pair is 5.3:1 and is allowed. */


/* ============================================================
   PART 2a — the cookie notice
   Hard ceiling 240px at 390x844 (invariant). The two buttons are styled by ONE
   rule so they cannot drift apart: an invariant compares their computed styles,
   because a decline demoted visually is a dark pattern regardless of the copy.
   The notice never claims to be legally required.
   ============================================================ */
/* ══ ANCHORED TO THE BOTTOM, AT EVERY WIDTH (S98/2.1, OPTION A) ═════════════
   🔴 TWO MODELS WERE LIVE AT ONCE AND THEY DISAGREED. A "review round" centred
   this card - left/top 50% with a translate - but FIVE separate rules still
   reserve space for it as a BOTTOM BAR, every one of them deriving off
   --cookienote-h:

     .skin-home            padding-bottom max(cookienote-h + 12, cartbtn + 12)
     .skin-home .cartbtn   bottom: calc(cookienote-h + 18px)
     .skin-home .mobilebar a.order      (phone reserve)
     .caterform pill       (phone reserve, demo-only.css)
     .skin-home            an earlier padding-bottom, same shape

   So the notice floated mid-viewport while the cart button lifted 197px to
   clear something that was no longer down there, and parked on top of the
   "MOST POPULAR" heading. Measured live by the Director at 995x819: notice
   y=320..499 centred, cart at y=566, resting value bottom:18px.

   ⚠️ OPTION A, AND THE FIVE RESERVES ARE WHY. Making it a centred modal
   (option B) would mean unwinding five rules that are each CORRECT for a bottom
   bar and each already derived rather than typed. Anchoring the notice back to
   the bottom makes all five right again with no arithmetic changed anywhere,
   and a consent notice is a bottom bar in the first place. No rule from the
   centred model survives: left/top/transform are all reset here explicitly
   rather than left to be overridden by accident. */
.skin-home .cookienote {
  position: fixed;
  left: 50%;
  right: auto;
  top: auto;
  bottom: 0;
  /* the X centring stays; the Y centring is gone with the model */
  transform: translateX(-50%);
  /* S98/2.2: 720px is too wide for a consent notice - it spanned most of a
     995px viewport. A readable measure, and still full-bleed on a phone. */
  width: min(520px, calc(100vw - 20px));
  max-width: none;
  /* it sits ON the floor, so the corners that meet it are square */
  margin-bottom: 12px;
  z-index: 60;
  background: var(--butter);
  border: 3px solid var(--outline);
  border-radius: 18px;
  box-shadow: 4px 4px 0 var(--outline);
  /* 🔴 THE CAP EXISTED TO FIT THE COPY, NOT AS A DESIGN CONSTANT (S96/1.1).
     The note below says the fine-print move "buys about 20px, which is what
     lets the notice fit 240px" - so 240 was always sized around the body text.
     The copy has been cut to two sentences, which fits at 390 (236.1px inner)
     and 430 (216.9px), but NOT at 320, where the two buttons wrap to their own
     rows and the text reflows narrower: 311.3px measured. Everything past 240
     was CLIPPED, and elementFromPoint at "Just the basics" returned the hero's
     own button showing through.

     ⚠️ THIS IS NOT "MAKE THE BOX SCROLL" - the box already scrolled, and that
     WAS the bug: overflow:auto turns unreachable content into a dialog nobody
     can answer. Raising the cap is what stops it needing to scroll at all.
     Viewport-relative so it can never exceed the screen it sits on: on a
     568px-tall phone this resolves to 360px. It is bottom-anchored now (S98),
     so that headroom is measured up from the floor rather than either side of
     a centre line - the buttons stay reachable either way, which is what
     block 166 holds. */
  max-height: min(360px, calc(100dvh - 24px));
  overflow: auto;
}
.skin-home .cookienote-inner {
  max-width: 1100px;
  margin: 0 auto;
  padding: 12px 20px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
/* the fine-print link rides the headline instead of taking its own row. That
   one move buys about 20px, which is what lets the notice fit 240px without
   clamping the body copy. */
.skin-home .cookienote-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 14px;
}
.skin-home .cookienote-h {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.35rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--outline);
}
.skin-home .cookienote-fine {
  font-family: var(--font-body);
  font-size: 0.8rem;
  color: var(--patty);
  text-decoration: underline;
  text-underline-offset: 3px;
  padding: 4px 0;
}
.skin-home .cookienote-p {
  margin: 0;
  font-family: var(--font-body);
  font-size: 0.83rem;
  line-height: 1.45;
  color: var(--outline);
  max-width: 68ch;
}
.skin-home .cookienote-btns { display: flex; flex-wrap: wrap; gap: 10px; }
/* ONE rule, both buttons: same size, same weight, same opacity. */
.skin-home .cookienote-btn {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--outline);
  background: var(--cheese-gold);
  border: 3px solid var(--outline);
  border-radius: 999px;
  box-shadow: 2px 2px 0 var(--outline);
  padding: 6px 18px 4px;
  min-height: 44px;
  min-width: 146px;
  opacity: 1;
  cursor: pointer;
  box-sizing: border-box;
}
.skin-home .cookienote-btn:hover { background: #F2B558; }
/* S98/2.5: the fine-print link rides the ACTION row now, not the heading. It
   is centred with the buttons and takes the whole row when they wrap, so it
   never sits half-beside a button. */
.skin-home .cookienote-btns { align-items: center; }
.skin-home .cookienote-fine { margin-left: auto; }
@media (max-width: 420px) {
  .skin-home .cookienote-fine { margin-left: 0; width: 100%; }
}
.skin-home .cookienote-btns { display: flex; flex-wrap: wrap; gap: 12px; }
.skin-home .cookienote-btns .cookienote-btn { flex: 1 1 0; }

/* ============================================================
   PART 2b — the bottom bar
   Three controls in the thumb's natural arc, which is why CALL lives here
   rather than in the top strip.
   ============================================================ */
.skin-home .mobilebar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 55;
  display: none;
  gap: 8px;
  padding: 8px 12px calc(8px + env(safe-area-inset-bottom, 0px));
  background: var(--outline);
  border-top: 3px solid var(--cheese-gold);
}
.skin-home .mobilebar a {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.05rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--butter);
  background: transparent;
  border: 2.5px solid var(--art-line, #C9884A);
  border-radius: 999px;
  text-decoration: none;
}
.skin-home .mobilebar a.order {
  color: #FFF8EC;
  background: var(--sign-red);
  border-color: var(--outline);
  flex: 1.2 1 0;
  /* the phone's own sticky CTA — the same red, so the same glow. It carries
     no sticker offset by design (it sits in a flush bar), which is why the
     suite asks for a lift only where one already existed. */
  box-shadow: var(--glow-btn);
}
@media (max-width: 720px) {
  /* --mobilebar-h IS PUBLISHED BY THE BAR ITSELF (index.html, mobileBarRef).
     It used to be typed 63px, which measures exactly right in a headless
     container and cannot be trusted on a phone: the bar's own padding carries
     env(safe-area-inset-bottom), which this harness reports as 0. The measured
     rect includes that inset wherever it is real. The 0px fallback applies only
     before the ref runs, and the bar is not on screen then either. */
  .skin-home .mobilebar { display: flex; }
  /* the bar and the notice both reserve their own space so no menu row ends up
     parked underneath either of them.

     THIS RULE USED TO SAY `.skin-home footer`, AND IT NEVER ONCE APPLIED. That
     is (0,1,1) against the (0,2,0) of `.skin-home .footer { padding: 54px 0 0 }`
     340 lines above — and that shorthand sets padding-bottom to 0. The clearance
     rule lost the cascade to a rule that zeroes the exact property it sets, so
     from the day it was written the footer reserved nothing: measured 2026-08-17
     at 390x664, the base strip overlapped the bar by 390.00 x 17.30px of its
     41.83px height, and elementFromPoint at the copyright's centre returned
     div.mobilebar. Nobody noticed for as long as nothing down there had to be
     TAPPED.

     AND IT IS ON THE WRAPPER NOW, NOT THE FOOTER, which is the second half of
     the lesson. Fixing the specificity and leaving the padding inside the footer
     put 197px into the footer's own BOX, and block 55 measures that box against
     a budget slice 15 tightened it to — 872.09px against a 852.95 ceiling, red
     at all four widths. The space being reserved is below the DOCUMENT, not
     inside the footer, so it belongs on the wrapper that already reserves the
     cookie notice's height eight lines from the top of this file. The footer's
     height is then a fact about the footer again. */
  /* the mobile bar is the floor here, and the pill is lifted to sit ON that
     floor (demo-only.css lifts it to 70px + the safe area under <=780px), so
     the two are measured the same way and max() takes whichever is taller. */
  .skin-home {
    padding-bottom: max(
      /* THE 22px IS GONE (3d, Director's ruling 2026-08-23). Of the 96.97px band
         below the footer on iPhone 14, 63.00 sat under the bar, 12.00 is the
         site's own standard breathing room - the same 12 the desktop reserve
         uses, which Carlos has looked at and not complained about - and 22.00
         was a typed constant with NO stated derivation anywhere in this rule's
         comment, which explains at length why the padding moved to the wrapper
         and never says where 22 came from. Fourth instance of the reserve rule.
         Reversible in one line if it turns out to be load-bearing for something
         nobody wrote down. */
      calc(var(--cookienote-h, 0px) + 12px + var(--mobilebar-h, 0px)),
      calc(var(--cartbtn-reserve, 0px) + 12px)
    );
  }
}


/* ---- P5: the honest ending as THE TICKET ---- */
.skin-home .cart-ticket { margin-top: 18px; }
.skin-home .cart-ticket-paper {
  background: #FCF8EC;
  /* no border and no radius: both belong to a squared-off card, and the mask
     would cut through either one. The paper's own torn edge is the shape. */
  padding: 26px 16px 30px;
  text-align: center;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  /* ── ONE TORN EDGE, AT THE BOTTOM, TEETH POINTING DOWN (R1/R2) ───────────
     CORRECTED 2026-08-24, and the correction reverses half of my own earlier
     fix. That version tore BOTH ends on the reasoning that symmetry reads as
     intent. Carlos, looking at the printed thing: a receipt is torn only where
     it LEFT THE ROLL - one torn edge, not two - so a serrated top is the
     mistake, not the asymmetry. The top is flat now.

     AND THE TEETH POINT DOWN. They pointed up/inward, which is the profile of
     a strip torn OFF something above it; a strip cut from a roll hangs its
     points downward. One mask layer, at the bottom, and the paper is square
     everywhere else.

     NO KEYLINE TO SLICE, kept from the earlier pass: a border the mask cuts
     through is the clearest tell that something went wrong, and cream paper on
     the near-black checkout is a 14.4:1 edge that needs no help. */
  -webkit-mask-image:
    linear-gradient(#000 0 0),
    conic-gradient(from 135deg at 50% 0, #0000 25%, #000 0);
  -webkit-mask-size: 100% calc(100% - 11px), 22px 11px;
  -webkit-mask-position: top, bottom;
  -webkit-mask-repeat: no-repeat, repeat-x;
  mask-image:
    linear-gradient(#000 0 0),
    conic-gradient(from 135deg at 50% 0, #0000 25%, #000 0);
  mask-size: 100% calc(100% - 11px), 22px 11px;
  mask-position: top, bottom;
  mask-repeat: no-repeat, repeat-x;
}
.skin-home .cart-ticket-shop {
  margin: 0;
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--outline);
}
.skin-home .cart-ticket-addr {
  margin: 3px 0 0;
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--patty);
}
.skin-home .cart-ticket-rule {
  border-top: 2px dashed rgba(20, 16, 14, 0.35);
  margin: 12px 0;
}
.skin-home .cart-ticket .cart-next-h {
  margin: 0;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--outline);
}
.skin-home .cart-ticket .cart-next-p {
  margin: 8px auto 10px;
  max-width: 34ch;
  font-size: 0.78rem;
  line-height: 1.55;
  color: var(--outline);
}
.skin-home .cart-ticket .cart-next-call {
  display: inline-block;
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--outline);
  text-decoration: underline;
  text-underline-offset: 3px;
  padding: 8px 6px;   /* 44px reach with the line height */
}
.skin-home .cart-ticket-close {
  margin: 0;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--outline);
}

/* ---- P5: the empty cart hands you the menu ---- */
.skin-home .cart-empty { padding: 6px 0 4px; }
.skin-home .cart-empty-h {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.5rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--outline);
}
.skin-home .cart-empty-p {
  margin: 6px 0 14px;
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--patty);
}
.skin-home .cart-empty-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.skin-home .cart-empty-pick {
  display: flex;
  align-items: baseline;
  gap: 10px;
  width: 100%;
  min-height: 44px;
  padding: 10px 12px;
  background: transparent;
  border: 2px solid var(--outline);
  border-radius: 12px;
  font-family: var(--font-body);
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--outline);
  cursor: pointer;
  text-align: left;
}
.skin-home .cart-empty-pick:hover { background: var(--cheese-gold); }
.skin-home .cart-empty-pick-name { flex: none; }
.skin-home .cart-empty-pick-dots {
  flex: 1 1 auto;
  border-bottom: 2px dotted rgba(20, 16, 14, 0.4);
  transform: translateY(-3px);
}
.skin-home .cart-empty-pick-price { flex: none; font-weight: 700; }

/* ---- P5: an unconfirmed price hands you the phone ---- */
.skin-home .isheet-callnow {
  display: inline-block;
  margin: 2px 0 4px;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--patty);
  text-decoration: underline;
  text-underline-offset: 3px;
  padding: 8px 0;
}

/* ---- P5: the smash list talks back ---- */
.skin-home .join-msg {
  margin: 10px 0 0;
  font-size: 0.9rem;
  line-height: 1.5;
  font-weight: 600;
}
.skin-home .join p.join-msg--ok { color: var(--butter); }
.skin-home .join p.join-msg--err { color: var(--cheese-gold); }

/* ---- P5: the line is crossed off the pad, then moves to the ticket ---- */
.skin-home .isheet-build-line.is-leaving .isheet-build-label {
  text-decoration: line-through;
  text-decoration-thickness: 2px;
  color: var(--patty);
}
/* S141: the line is crossed off, THEN the gap closes behind it. The strike and
   the fade were already here; what was missing was the collapse, so the list
   jumped when the row unmounted. `0fr` is the transition's to-value and the row
   is unmounted on transitionend (index.html, drop()). */
.skin-home .isheet-build-line.is-leaving {
  grid-template-rows: 0fr;
  opacity: 0;
}
.skin-home .isheet-build-line.is-leaving .isheet-build-row {
  /* the clipping region exists ONLY while the row is collapsing */
  overflow: hidden;
  transition: transform 0.34s ease;
  transform: translateX(8px);
}
/* REDUCED MOTION: no transition anywhere on the row, so transitionend never
   fires - which is exactly why drop() takes the synchronous path first and
   never relies on the event here. */
@media (prefers-reduced-motion: reduce) {
  .skin-home .isheet-build-line,
  .skin-home .isheet-build-line.is-leaving .isheet-build-row { transition: none; }
}

/* A STICKY BAR PARKS ITS TARGET UNDERNEATH ITSELF unless the target says
   otherwise: #menu measured scroll-margin-top: 0px, so a nav jump put the
   heading behind 61px of bar. Every in-page anchor the nav or the page can
   jump to clears the bar plus a little air. */
.skin-home #menu,
.skin-home #visit,
.skin-home #reviews,
.skin-home #catering,
.skin-home #gallery,
/* --orderbar-h IS PUBLISHED BY THE BAR ITSELF (index.html, orderBarRef), not
   typed here. It used to be 61px with a 56px override under 768, and it was
   wrong at every width - always short, worst at 768 where a 56px token stood in
   for a 65px bar and left these anchors 3.05px of air instead of 12.

   THE 0px FALLBACK IS CORRECT, not a placeholder. It applies only in the frame
   before the ref publishes, and in that frame the bar is not on screen either:
   it starts `visibility: hidden` and slid away, and only `.is-on` brings it
   down. No bar means no clearance to reserve. */
.skin-home #about { scroll-margin-top: calc(var(--orderbar-h, 0px) + 12px); }

/* ══ APPLE PAY ════════════════════════════════════════════════════════════════
   The wallet slot. It is in the DOM on every card step and DISPLAYS NOTHING
   until a real, payable button has mounted into it - see the `hidden` hole in
   index.html and the four gates in appleMountRef.

   ⚠️ [hidden] IS DECLARED EXPLICITLY because .pay-wallet sets display:flex, and
   a display rule beats the browser's default [hidden]{display:none}. Without
   this line the slot would be laid out - an empty 44px gap and the words "or
   pay by card" above a card form, on every phone that cannot use Apple Pay.
   That is the whole defect this feature is trying not to commit, arriving
   through the back door of a shorthand. */
/* 🔴 HIDDEN IS THE DEFAULT, AND THAT IS THE SAFETY PROPERTY. The slot is
   display:none unless .is-on is added by a successful mount. If the class hole
   ever stops being delivered - a runtime change, a typo, a state that never
   arrives - the button DISAPPEARS rather than appearing as an empty box above
   the card form. For a control whose whole contract is "absent unless it can
   pay", the failure direction has to be absence.

   (The first version used hidden="{{ ... }}". Measured in the DOM: hiddenProp
   false, hiddenAttr null, display flex - the React boolean-prop trap from
   2026-08-18, reached through a hole. Do not go back to it.) */
.skin-home .pay-wallet { display: none; }
/* ⚠️ THE MOUNTED RHYTHM IS SYMMETRIC, AND IT WAS MEASURED BOTH WAYS (S91).
   Before: 12px from the button down to "or pay by card", and 32px from there
   down to the first card field. The divider sat close to the button and
   stranded from the form it introduces, so the three read as three blocks
   rather than one choice. Carlos saw it; the numbers agreed.

   Equal air above and below the divider is what makes it read as ONE group.
   The 18px bottom margin went to 0 and the spacing below now comes from the
   card block alone, so there is ONE rule setting it rather than two stacking. */
.skin-home .pay-wallet.is-on {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin: 0;
}
/* S158: while a charge is in flight (its status line is on screen) the wallet
   is a second Pay button beside "please don't pay again" - it goes, the same
   way the Pay button does (230.11, 230.14). applePaid refuses it as well. */
.skin-home .checkout:has(.checkout-paywait) .pay-wallet.is-on { display: none; }
/* C (block 242): the same rule after a charge that could not be reversed */
.skin-home .checkout:has(.checkout-paystop) .pay-wallet.is-on { display: none; }
/* Apple's own button, in Apple's own frame. We give it a height and a width and
   nothing else: its look is dictated by Apple's human interface guidelines and
   is not ours to restyle. */
/* 🔴 A DEFINITE HEIGHT, NOT A FLOOR - the same defect .paycard-slot already
   solved on 2026-08-25 and for the identical reason. min-height alone let
   Clover's mounted frame fall back to the HTML default of 150px and the slot
   grew to meet it, leaving roughly 200px of empty cream between the Apple Pay
   button and "or pay by card". Measured on production 2026-08-31.

   44px is Apple's minimum for their button and the project's tap floor, and it
   is what a wallet button should be: one row. The iframe is then told to fill
   its box rather than choose its own size - exactly the rule the card slots
   use one file over. */
/* 🔴 S96/1.2 - THE DEFINITE HEIGHT MOVES ONTO THE BUTTON, AND THE SLOT STOPS
   STRETCHING EVERYTHING IT CONTAINS.

   THE DEFECT, reproduced and measured (390x844, Clover stubbed to mount the way
   its own docs describe): the SDK appends TWO children to #apple-div - the
   button's iframe AND a div.clover-footer carrying "Secure Payments Powered by
   Clover" and a Privacy Policy link. `> *` stretched BOTH to height:100% of a
   44px box, so the footer rendered 44px tall starting exactly at the slot's
   bottom edge and ran 44px past it, straight through the 12px gap and into
   "or pay by card". Full width, immediately beneath the button. That is the
   white/cream bar Carlos photographed.

   ⚠️ THE 44px MUST NOT SIMPLY MOVE TO min-height ON THE SLOT. The comment above
   records why the definite height exists: min-height alone let Clover's frame
   fall back to the HTML default of 150px. So the definite height goes on the
   FIRST CHILD - the mounted button - which is the element that was defaulting.
   The slot keeps a 44px floor for the un-mounted case.

   ⚠️ AND THE FOOTER IS NOT HIDDEN. Suppressing a payment processor's own
   privacy disclosure is not a call to make for a cosmetic bug, and Clover's
   docs say it is added automatically. It simply stops being stretched: it now
   takes its natural height in normal flow, below the button, inside the
   wallet's flex column. The bar goes away because nothing overlaps any more,
   not because a disclosure was deleted. */
/* 🔴 S112 (2026-09-05) - THE SLAB CAME BACK, 250px TALL, AND EVERY GUARD WAS
   GREEN. Carlos, iPhone Safari, the real domain: the black button at 44px and
   an empty white rectangle roughly 250px tall directly under it, inside this
   slot, pushing "or pay by card" down the page.

   NOTHING SHIPPED BETWEEN d38cc57 AND fd574ab TOUCHED THIS BLOCK OR THE MOUNT
   MARKUP (diffed). The S96 rules above were intact. What S96 did was stop
   STRETCHING Clover's second child; it left every non-first child at its
   natural height on purpose, and block 167.1 asserted only that nothing
   OVERHANGS the slot. A flex column grows to hold its children, so a child
   that renders 250px tall on its own sits inside a 294px slot, overhangs
   nothing, and passes. The shape of that child is Clover's SDK's, which
   cannot be observed from the build container; what is certain is that a
   non-button child now has a height of its own where S96 measured 49.6px of
   footer text.

   SO THE RULE IS NOW ABOUT THE CONTAINER, NOT ABOUT WHICH CHILD IS WHICH:
   the slot IS the button's height, and no other child of it is laid out.
   Carlos's ruling on S112 states the property in those words; it overrides
   S96's choice to leave Clover's footer visible, because an empty 250px slab
   is not a disclosure and a slot that can grow is the mechanism the slab
   came back through. Block 167.4 pins the geometry: slot height equals button
   height, every other child renders 0px, the divider one gap below. */
/* 🔴 S133b (2026-09-15) - THE WHITE STRIP UNDER THE BUTTON, ON SAFARI.
   Carlos sees it on every order. MEASURED HERE FIRST, and it corrected half of
   the reported diagnosis: this container's background is ALREADY transparent
   (`rgba(0, 0, 0, 0)`, read off getComputedStyle with the wallet stubbed and
   mounted), so nothing of ours is painting white. What is wrong is the SHAPE.

   The container is `overflow: hidden` with `border-radius: 0` - a square box -
   and Apple's button is a rounded rectangle drawn inside Clover's iframe. An
   iframe paints its own document, and that document's ground is white. So the
   white that shows is the iframe's own, in the corners the rounded button does
   not cover, and a square clipping region cannot cut it away.

   Giving the container a radius makes `overflow: hidden` do the clipping it
   was already asking for. It is also applied to the mounted first child, so
   the two are equal BY CONSTRUCTION rather than by two typed numbers agreeing
   - block 224 reads both off the DOM and fails if they diverge.

   ⚠️ 44px IS UNTOUCHED. S112's ruling is that the slot IS the button's height;
   this changes the corners and nothing else - no height, no background, no new
   child laid out.

   ⚠️ WHY 4px AND NOT A GUESS THAT LOOKS BETTER. Apple's real radius cannot be
   read from here: Playwright's WebKit has no ApplePaySession, so the button
   never mounts and there is nothing to measure. 4px is chosen because the
   change is then monotone in the only unknown - if Apple's radius is LARGER,
   a hairline of white remains and we are strictly better than the square
   corner we have today; if we over-shot it, we would clip Apple's own pixels,
   which is worse than the bug. Picking the smallest plausible radius is the
   branch that cannot make anything worse. The real corner match is Carlos's
   Safari screenshot, and that is the honest limit of this fix. */
.skin-home .pay-wallet-btn {
  --wallet-radius: 4px;
  width: 100%; height: 44px; min-height: 44px; overflow: hidden;
  background: transparent;
  border-radius: var(--wallet-radius);
}
.skin-home .pay-wallet-btn > *:first-child { display: block; width: 100%; height: 44px; border: 0; border-radius: var(--wallet-radius); }
.skin-home .pay-wallet-btn > * { max-width: 100%; }
.skin-home .pay-wallet-btn > *:not(:first-child) { display: none; }
/* the separator. Not a heading: a heading would promise a section. */
.skin-home .pay-wallet-or {
  margin: 0;
  font-family: var(--font-body);
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--patty, #6B4A32);
  text-align: center;
}

/* ============================================================
   /bridges (JOB M, 2026-10-15). ONE page, two sites. The inline
   <head> script sets html[data-site="bridges"] before the body is
   parsed; these rules pick the variant. The hidden one is
   display:none, never visually-hidden: a screen reader must not
   read the other site's headline or card.
   ============================================================ */
html:not([data-site="bridges"]) .skin-home .site-bridges { display: none; }
html[data-site="bridges"] .skin-home .site-home { display: none; }

/* gold is type on the DARK hero only (8.47:1); never on cream */
.skin-home .e1-gold { color: var(--cheese-gold); }

/* card 01 on /bridges: the .e1-feat frame and art raise (both grouped above);
   "Only at Bridges" sits where the price sits on the other cards */
.skin-home .e1-bcard-name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(1.55rem * var(--type-scale));   /* red on cream: large only */
  line-height: 1;
  text-transform: uppercase;
  color: var(--sign-red);
}
.skin-home .e1-bcard-foot {
  font-family: var(--font-display);
  font-size: calc(0.95rem * var(--type-scale));
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--outline);                          /* 14.4:1 */
}

/* ============================================================
   THE BRIDGES LOCKUP (JOB Y 2026-10-15; JOB BX 2026-10-19). /bridges
   only (.site-bridges above hides it on /). Option 1 of the lockups
   page, side by side on the dark hero: our badge, a gold ×, their full
   white logo. One em scale for all three, in option 1's own units:
   badge 14, × 5.6, logo 26, gaps 2.2, about 48em in all. The font-size
   is capped at 10px and shrinks so 48em fits the 40px of gutters at any
   width (320px leaves 280px). Gold is legal type on the dark hero
   (colour law). Sized in CSS: all: unset cancels img sizes.
   ============================================================ */
.skin-home .e1-bridges {
  display: flex;
  align-items: center;
  gap: 2.2em;
  font-size: min(10px, calc((100vw - 40px) / 48));
  margin: 6px 0 18px;
}
.skin-home .e1-bridges-badge { display: block; width: 14em; height: 14em; }
.skin-home .e1-bridges-x {
  display: block;
  font-family: var(--font-display);
  font-size: 5.6em;
  line-height: 1;
  color: var(--cheese-gold);
}
.skin-home .e1-bridges-logo { display: block; width: 26em; height: auto; }
