@charset "utf-8";

/* Display face: Anton (SIL Open Font License), self-hosted, 18.6 kB, one
   weight. Chosen to match the client's own mock-up — heavy, condensed,
   upright capitals. Body copy stays on the system stack; nothing typesets the
   brand name at all — the header carries the logo lockup as artwork. */
@font-face {
  font-family: "Anton";
  src: url("/assets/fonts/anton-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* ==========================================================================
   Pookie Chicken

   LIGHT ONLY, deliberately. The site ships one theme for now.

   Every colour is still a token on :root and nothing reads a literal, so
   restoring dark mode is adding two blocks and changing nothing else:
   @media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { ... } }
   and :root[data-theme="dark"] { ... }, each redefining the tokens below.
   The dark values that were measured for this palette are kept in
   README.md so they do not have to be derived again.

   Contrast ratios in comments were computed, not estimated.
   ========================================================================== */

:root {
  /* -- grounds ---------------------------------------------------------- */
  --paper:        #FFFFFF;   /* white, at the client's request */
  --sunken:       #FCF7F2;   /* faint warm tint, biased toward the orange
                                accent so the bands read as chosen rather
                                than as a default grey. Deliberately this
                                pale: --brand sits on it in the chapter
                                headers, and a darker band pushed that pair
                                to 4.48:1, just under AA. */
  --dark:         #141110;   /* the dark ground: hero, footer. White on it
                                is 18.4:1; --logo-orange on it is 7.1:1, so
                                the logo's own orange is text-safe here. */
  --surface:      #FFFFFF;   /* raised: menu block, cards. Equal to --paper
                                now, so the block is defined by its --rule
                                border rather than by a fill. */

  /* -- ink -------------------------------------------------------------- */
  --ink:          #1A1512;   /* 16.81:1 on paper */
  --ink-2:        #463C32;   /*  9.98:1 on paper */
  --ink-3:        #6A5C4E;   /*  5.99:1 on paper */

  /* -- brand, three layers ---------------------------------------------
     The accent is ORANGE, at the client's request. The logo's own orange
     is #FD8105, which measures 2.52:1 on white — it fails AA for body text
     (4.5:1) and even the large-text threshold (3:1). So the same three-layer
     rule as before, walked down the orange ramp until each use passes:

     logo-*   : untouched logo values. The logo, and fills that carry DARK
                text (--ink on --logo-orange is 7.17:1).
     display  : #E06E00, 3.28:1 — headings at 24px and above only.
     brand    : #B45100 — 5.10:1 on white, 4.79:1 on --sunken, and 5.10:1
                under the white text of a button fill. Body copy, links,
                small UI. Chosen as the most orange step that clears AA on
                BOTH grounds, not just the page.

     Never use --logo-orange for text. Two of the three ramp steps exist
     precisely because it cannot be.                                       */
  --logo-red:     #E12F1C;
  --logo-orange:  #FD8105;
  --logo-amber:   #FDAA04;
  --display-orange: #E06E00; /* 3.28:1 on white — large text only */
  --brand:        #B45100;   /* 5.10:1 white · 4.79:1 sunken */
  --brand-ink:    #FFFFFF;   /* on --brand fill: 5.10:1 */

  --herb:         #2E6A4A;   /* 5.95:1 — balance signal, open state */
  --honey:        #FDAA04;   /* FILL ONLY. --ink on honey = 9.70:1 */
  --honey-text:   #8A5A0E;   /* 5.49:1 — when the glaze family needs words */

  /* -- lines ------------------------------------------------------------ */
  --line:         #7E6A54;   /* borders that ARE the control. 4.78:1 */
  --rule:         #D2C0A2;   /* decorative hairlines */
  --photo-ground: #F2EDE6;   /* the ground every dish photograph is set on: a warm
                                light grey, so a white plate reads as a plate */
  --focus:        #C05C00;   /* 4.40:1 — the threshold for a focus ring is 3:1 */

  /* -- sauce families ---------------------------------------------------- */
  --sauce-chilli: #A32E17;
  --sauce-glaze:  #B5751A;
  --sauce-smoke:  #8A4520;
  --sauce-cream:  #EFDCBB;   /* 1.25:1 — invisible alone, hence the ring */

  /* -- scrim: guarantees AA over any photograph, sight unseen ------------- */
  --scrim: linear-gradient(to top, rgba(20,14,9,.86), rgba(20,14,9,.72) 45%, transparent);

  /* -- type -------------------------------------------------------------- */
  --display: "Anton", Impact, "Arial Narrow Bold", "Helvetica Neue", Arial, sans-serif;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;

  --t-xs:   0.8125rem;
  --t-sm:   0.875rem;
  --t-base: clamp(1rem, 0.96rem + 0.2vw, 1.0625rem);
  --t-md:   clamp(1.0625rem, 1rem + 0.3vw, 1.1875rem);
  --t-lg:   clamp(1.25rem, 1.14rem + 0.5vw, 1.5rem);
  --t-xl:   clamp(1.5rem, 1.3rem + 1vw, 2rem);
  --t-2xl:  clamp(1.75rem, 1.4rem + 1.5vw, 2.75rem);
  --t-3xl:  clamp(2.25rem, 1.6rem + 3.2vw, 4rem);

  --lh-tight: 1.1;
  --lh-snug:  1.25;
  --lh-base:  1.6;

  /* -- space ------------------------------------------------------------- */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 24px; --s6: 32px; --s7: 48px; --s8: 64px; --s9: 96px;

  --r-sm: 2px; --r-md: 3px; --r-lg: 6px;
  --shadow: 0 1px 2px rgba(26,21,18,.06), 0 8px 24px -12px rgba(26,21,18,.18);

  --measure: 68ch;
  --wrap: 1120px;

  color-scheme: light;
}

/* ---------------------------------------------------------------- reset */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--t-base);
  line-height: var(--lh-base);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 400;                 /* Anton has one weight */
  text-transform: uppercase;
  letter-spacing: .01em;
  line-height: .98;
  text-wrap: balance;
  margin: 0;
  /* The display face carries the brand colour; body copy stays --ink.
     Which orange depends on size, because size is what sets the contrast
     threshold: h1 and h2 are 28px and up, so they clear large-text (3:1)
     on --display-orange. h3/h4 are 20-24px, which is too close to the
     18.66px-bold boundary to rely on, so they take --brand, which clears
     4.5:1 at any size. */
  color: var(--brand);
}

h1, .sec h2, .band h2 { color: var(--display-orange); }

p, ul, ol { margin: 0; }
address { font-style: normal; }   /* an address is a fact, not an aside; nowhere on this site is it italic */
img, video { max-width: 100%; height: auto; display: block; }

a { color: var(--brand); text-underline-offset: 2px; }
a:hover { text-decoration-thickness: 2px; }

:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

.wrap { max-width: var(--wrap); margin-inline: auto; padding-inline: clamp(20px, 5vw, 48px); }
.measure { max-width: var(--measure); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--brand); color: var(--brand-ink);
  padding: var(--s3) var(--s4); border-radius: 0 0 var(--r-md) 0;
}
.skip:focus { left: 0; }

/* -------------------------------------------------------- status ribbon */

.ribbon {
  background: var(--honey);
  color: #1A1512;                  /* 9.70:1 on honey — literal, because the
                                      honey fill is the same in both themes */
  font-size: var(--t-sm);
  font-weight: 600;
  text-align: center;
  padding: var(--s2) var(--s4);
}

/* --------------------------------------------------------------- header */

.head {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--rule);
}
.head__in {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s4); padding-block: var(--s3);
}
/* The brand's own lockup, straight from the logo artwork: the rooster mark,
   then "Pookie" over "Chicken". The artwork carries the name, so nothing is
   typeset beside it and the alt text is the brand name rather than empty.
   The height is fixed and the width follows, so the 654:234 ratio holds at
   every size. */
.brandmark { display: flex; align-items: center; text-decoration: none; }
.brandmark img { height: 52px; width: auto; display: block; }

.nav { display: flex; align-items: center; gap: var(--s5); }
.nav a {
  color: var(--ink-2); text-decoration: none;
  font-size: var(--t-sm); font-weight: 600; white-space: nowrap;
}
.nav a:hover, .nav a[aria-current="page"] { color: var(--brand); }

/* ----------------------------------------------------------------- hero */

.hero { padding-block: clamp(48px, 8vw, 96px) clamp(32px, 5vw, 56px); }
.hero__eyebrow {
  display: inline-block;
  font-size: var(--t-xs); letter-spacing: .08em; text-transform: uppercase;
  font-weight: 700; margin-bottom: var(--s4);
  background: var(--logo-orange); color: #1A1512;   /* 7.17:1 */
  padding: 6px 14px; border-radius: 999px;
}
.hero h1 { font-size: var(--t-3xl); letter-spacing: -0.02em; max-width: 22ch; }
.hero h1 em { font-style: normal; color: var(--display-orange); }
.hero__lede { margin-top: var(--s5); max-width: 58ch; font-size: var(--t-md); color: var(--ink-2); }
.hero__actions { margin-top: var(--s6); display: flex; flex-wrap: wrap; gap: var(--s3); }

.btn {
  display: inline-flex; align-items: center; gap: var(--s2);
  font: inherit; font-size: var(--t-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em;
  padding: 13px 22px; border-radius: 999px;
  text-decoration: none; cursor: pointer; border: 1px solid transparent;
}
.btn--primary { background: var(--brand); color: var(--brand-ink); }
.btn--primary:hover { filter: brightness(1.08); }
.btn--ghost { border-color: var(--line); color: var(--ink); background: none; }
.btn--ghost:hover { border-color: var(--brand); color: var(--brand); }

/* -------------------------------------------------------------- section */

.sec { padding-block: clamp(40px, 6vw, 72px); border-top: 1px solid var(--rule); }
.sec__kicker {
  font-size: var(--t-xs); letter-spacing: .08em; text-transform: uppercase;
  color: var(--brand); font-weight: 700; margin-bottom: var(--s3);
}
.sec h2 { font-size: var(--t-2xl); letter-spacing: -0.014em; }
.sec__lede { margin-top: var(--s4); max-width: var(--measure); color: var(--ink-2); }

/* The three parts of a composed plate, with the weights off the brand's own
   "All in one" card. The figure is set in the display face and leads, because
   it is the one hard number on the page and the sentence under it is colour.
   .balance__amount starts at 28px so --display-orange (3.28:1) is always in
   its permitted large-text range — never let this clamp fall below 24px. */
.balance { margin-top: var(--s6); display: grid; gap: var(--s5);
           grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
           list-style: none; margin-inline: 0; padding: 0; }
.balance__item { margin: 0; padding-top: var(--s4); border-top: 2px solid var(--rule); }
.balance__item h3 {
  font-family: var(--sans); font-size: var(--t-xs); font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3);
  margin-bottom: var(--s1);
}
.balance__amount {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(1.625rem, 1.35rem + 1vw, 2.375rem);
  line-height: 1; letter-spacing: .01em; text-transform: uppercase;
  color: var(--display-orange); margin-bottom: var(--s3);
}
.balance__item p:not(.balance__amount) { color: var(--ink-2); font-size: var(--t-sm); }

/* Gated behind copy.balance.claims.verified — see data.js. Styled now so
   turning them on is a one-word edit there and nothing here. */
.claims { display: flex; flex-wrap: wrap; gap: var(--s2);
          margin-top: var(--s5); list-style: none; margin-inline: 0; padding: 0; }
.claims li {
  margin: 0; border: 1px solid var(--rule); border-radius: 999px;
  padding: 6px 14px; font-size: var(--t-xs); font-weight: 700;
  letter-spacing: .04em; color: var(--brand); background: var(--sunken);
}

/* ------------------------------------------------------------ price index */

.prices { margin-top: var(--s6); display: grid; gap: 2px;
          grid-template-columns: repeat(auto-fit, minmax(168px, 1fr)); }
.prices__cell {
  background: var(--surface); border: 1px solid var(--rule);
  padding: var(--s4); display: flex; flex-direction: column; gap: var(--s1);
}
.prices__cell dt { font-size: var(--t-sm); color: var(--ink-2); }
.prices__cell dd {
  margin: 0; font-family: var(--display); font-size: var(--t-xl);
  font-weight: 400; font-variant-numeric: tabular-nums lining;
  /* --brand, matching the card prices this index summarises: 5.10:1 on the
     white chip. The menu rows keep --ink, where a price is data in a list
     rather than a headline. */
  color: var(--brand);
}

/* ------------------------------------------------------------- statement */

/* One line of the brand's own neon-sign copy, full bleed on the dark ground,
   between the gallery and the lunch band. It is decoration, not navigation:
   the aria-label on the section repeats the line so it is announced once and
   the <p> inside is not mistaken for a heading. White here is 18.79:1 and
   --logo-amber is 9.78:1, so both pass AA at any size. */
.statement { background: var(--dark); padding-block: clamp(36px, 6vw, 72px); }
.statement p {
  font-family: var(--display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(2rem, 1.2rem + 4vw, 4.25rem);
  line-height: .95; letter-spacing: .005em; color: #FFFFFF; margin: 0;
}
.statement em { font-style: normal; color: var(--logo-amber); display: block; }

/* ------------------------------------------------------------------ band */

.band { background: var(--sunken); border-block: 1px solid var(--rule);
        padding-block: clamp(32px, 5vw, 56px); }
.band h2 { font-size: var(--t-xl); }
.band__prices { margin-top: var(--s4); font-family: var(--display);
                font-size: var(--t-2xl); font-variant-numeric: tabular-nums lining; }

/* ------------------------------------------------------------- notice */

.notice {
  margin-top: var(--s5); border: 1px solid var(--line);
  border-left: 3px solid var(--honey);
  border-radius: var(--r-sm); padding: var(--s4) var(--s5);
  background: var(--surface); font-size: var(--t-sm); color: var(--ink-2);
  max-width: var(--measure);
}
.notice strong { color: var(--ink); }

/* ------------------------------------------------------------- follow */

.follow { display: flex; flex-wrap: wrap; gap: var(--s3); margin-top: var(--s5); }

/* ------------------------------------------------------------- footer */

.foot { border-top: 1px solid var(--rule); padding-block: var(--s6) var(--s5);
        font-size: var(--t-sm); color: var(--ink-3); }
.foot__grid { display: grid; gap: var(--s5);
              grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.foot h2 { font-family: var(--sans); font-size: var(--t-xs);
           letter-spacing: .08em; text-transform: uppercase;
           color: var(--ink-2); font-weight: 700; margin-bottom: var(--s3); }
.foot a { color: var(--ink-2); }
.foot__legal { margin-top: var(--s4); padding-top: var(--s3);
               border-top: 1px solid var(--rule); font-size: var(--t-xs); }
/* The line under a neighbourhood-only "Where": quieter than the thing it
   qualifies, because it is the caveat and not the answer. */
.foot__note { font-size: var(--t-xs); opacity: .72; margin-top: var(--s2); }

/* ------------------------------------------------------- home: split */

.split { display: grid; gap: var(--s6); align-items: center;
         grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); }
.split__img { width: 100%; height: auto; }
@media (max-width: 900px) { .split { grid-template-columns: 1fr; } }

/* Two-line headline: first line ink, second the display orange — the mock-up's
   device, and legal because these run 28px and up (large-text threshold 3:1). */
.sec h2.hx, .hx { color: var(--ink); font-size: clamp(2.2rem, 1.4rem + 3.4vw, 4.5rem); }
.hx span { display: block; }
.hx em { display: block; font-style: normal; color: var(--display-orange); }

/* --------------------------------------------- former inline styles */

/* These used to be style="" attributes on the elements. The nginx CSP is
   style-src 'self' with no 'unsafe-inline', which is right — and it means an
   inline style attribute is silently dropped on the live site. Everything
   that was one is a class now, so what the build previews is what ships. */
.stack { display: flex; flex-direction: column; gap: var(--s4); }
.hero__actions--after { margin-top: var(--s6); }
.prices--after { margin-top: var(--s5); }
.prices__big { font-size: var(--t-lg); }
.foot__hours { display: grid; grid-template-columns: auto 1fr; gap: 2px 12px; margin: 0; }
.foot__hours dd { margin: 0; font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------ back to top */

/* DEFAULT = NO JAVASCRIPT. It is an ordinary link on the last line of the
   footer and it works: #top is the header, which carries tabindex="-1", so
   following it moves the keyboard's place to the top of the page and not just
   the scrollbar's. Everything below the .js-totop rules is this state, so with
   the script blocked, failed or still parsing, nothing is hidden and nothing
   is broken. */
.totop {
  display: inline-flex; align-items: center; gap: var(--s2);
  margin-top: var(--s3); text-decoration: none;
  font-size: var(--t-xs); font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
}
.totop__arrow { flex: none; }

/* JS on: out of the flow, into the corner, and hidden until it is wanted.
   .js-totop is added by main.js, so this whole block is inert without it. */
.js-totop .totop {
  position: fixed; z-index: 35;
  right: clamp(16px, 3vw, 28px); bottom: clamp(16px, 3vw, 28px);
  margin: 0; width: 48px; height: 48px;            /* 48px: clears the 44px
                                                      target-size minimum with
                                                      room for fat thumbs */
  justify-content: center; gap: 0; border-radius: 50%;
  /* PAPER, not --dark, and not --brand. It floats over two grounds: the white
     page for most of the scroll, and the dark footer at the end — which is
     exactly where someone reaches for it. A --dark button disappeared into
     that footer completely. White shows on both: the --ink arrow is 16.81:1
     on it and the --line ring is 5.15:1 on paper, well past the 3:1 a control
     boundary needs. --brand would also have worked on both grounds, but it is
     the colour of the action-bar button directly below it on a phone, and two
     orange pills stacked read as one. */
  background: var(--paper); color: var(--ink);
  border: 1px solid var(--line);
  box-shadow: 0 2px 6px rgba(26,21,18,.16), 0 14px 30px -10px rgba(26,21,18,.38);
  opacity: 0; visibility: hidden; transform: translateY(8px) scale(.9);
  transition: opacity 220ms ease, transform 220ms ease, visibility 0s linear 220ms;
}
/* visibility, not just opacity: an invisible button must also be out of the
   tab order, or a keyboard user hits a control they cannot see. */
.js-totop .totop.is-in {
  opacity: 1; visibility: visible; transform: none;
  transition: opacity 220ms ease, transform 220ms ease, visibility 0s;
}
.js-totop .totop:hover { background: var(--sunken); border-color: var(--brand); color: var(--brand); }
.js-totop .totop__label {
  /* the label still names the button for a screen reader; the arrow is the
     visible half and is aria-hidden */
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
.js-totop .totop__arrow { width: 22px; height: 22px; }

/* Clear the sticky action bar, which owns the bottom of the screen on a phone. */
@media (max-width: 640px) {
  .js-totop .totop { bottom: calc(var(--actionbar-h, 62px) + 12px); }
}

@media (prefers-reduced-motion: reduce) {
  .js-totop .totop { transition: none; transform: none; }
}

/* A floating button is a screen control. On paper it is a dark circle. */
@media print { .totop { display: none !important; } }

/* --------------------------------------------------------- where + map */

/* Address left, map right; stacked under 900px, the same breakpoint .split
   uses, so the two side-by-side blocks on the home page break together. */
.where { margin-top: var(--s6); display: grid; gap: var(--s6);
         grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); align-items: start; }
@media (max-width: 900px) { .where { grid-template-columns: 1fr; } }

.where__address {
  font-style: normal; font-family: var(--display); font-weight: 400;
  text-transform: uppercase; letter-spacing: .01em;
  font-size: var(--t-xl); line-height: 1.12; color: var(--ink);
}
.where__note { margin-top: var(--s4); color: var(--ink-2); font-size: var(--t-sm); max-width: 40ch; }

.map { margin: 0; }
/* Empty until a yes, and empty is not shown: a visitor who said no, or has
   no JavaScript, sees a plain find-us block with no hole in it. Modern
   browsers also collapse the grid to one column; older ones leave a blank
   second track, which is harmless. */
.map:empty { display: none; }
.where:has(.map:empty) { grid-template-columns: 1fr; }
/* 3:2 like every other picture on the site, so the map sits in the same
   rhythm as the plates. */
.map__frame {
  display: block; width: 100%; aspect-ratio: 3 / 2;
  border: 1px solid var(--rule); border-radius: var(--r-lg);
  background: var(--photo-ground);
}

/* ------------------------------------------------------------ consent */

/* The banner: a bar along the bottom, not a modal. It takes no focus and
   covers nothing that matters — the map it is about is a link until you
   answer. z-index above the back-to-top button, which steps aside while the
   banner is up (two things in the corner is one too many). */
.consent {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
  background: var(--paper); border-top: 1px solid var(--rule);
  box-shadow: 0 -8px 30px -12px rgba(26,21,18,.28);
  padding-block: var(--s4);
}
.consent__in { display: flex; align-items: center; justify-content: space-between;
               gap: var(--s4) var(--s6); flex-wrap: wrap; }
.consent__text { font-size: var(--t-sm); color: var(--ink-2); max-width: 64ch; margin: 0; }
.consent__text strong { color: var(--ink); }
.consent__text a { color: var(--brand); }
/* Accept and Reject: the same button, twice. Equal prominence is the rule,
   and the cheapest way to be sure of it is to give them nothing to differ by. */
.consent__actions { display: flex; gap: var(--s3); flex: none; }
.has-consent .totop { display: none; }
@media (max-width: 640px) {
  .consent { bottom: var(--actionbar-h, 62px); }    /* above the sticky action bar */
  .consent__actions { width: 100%; }
  .consent__actions .btn { flex: 1; justify-content: center; }
}

/* /cookies/: the same controls, in the flow of the page */
.consent__page { border: 1px solid var(--rule); border-radius: var(--r-lg);
                 padding: var(--s5); background: var(--sunken); }
.consent__status { margin: 0 0 var(--s4); font-weight: 600; color: var(--ink); }
.consent__page .consent__actions { flex-wrap: wrap; }
.foot__sep { margin-inline: 6px; opacity: .5; }
code { font-size: .92em; background: var(--sunken); border: 1px solid var(--rule);
       border-radius: var(--r-sm); padding: 1px 5px; }

/* --------------------------------------------------- home: artwork band */

.artwork { margin-block: clamp(24px, 4vw, 48px); }
/* Last thing on the page, flush to the dark footer under it: the artwork is a
   band in its own right, so it takes no margin at either edge. */
.artwork:last-child { margin-block: 0; }
.artwork__img { width: 100%; height: auto; display: block; }

/* ---------------------------------------------------------- home: cards */

/* ------------------------------------------------ home: the text menu */

/* The whole menu as words. A grid rather than one long column, because 32
   lines stacked is a scroll and not a summary; auto-fill means the number of
   columns follows the width instead of a breakpoint guessing at it. */
.listing { margin-top: var(--s6); display: grid; gap: var(--s6) var(--s7);
           grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.listing__ch h3 { font-size: var(--t-lg); color: var(--brand); margin-bottom: var(--s3); }
.listing__ch ul { list-style: none; margin: 0; padding: 0; }
.listing__ch li {
  display: flex; align-items: baseline; gap: var(--s4);
  padding: 7px 0; border-bottom: 1px solid var(--rule);
}
.listing__name { flex: 1; min-width: 0; font-size: var(--t-sm); color: var(--ink); }
/* The display face and the brand orange, as on the price index this replaced:
   --brand is 5.10:1 on white, so the figure stays the legible thing on a line
   even though it is no longer --ink. */
.listing__price {
  font-family: var(--display); font-size: var(--t-md); line-height: 1;
  color: var(--brand); font-variant-numeric: lining-nums; white-space: nowrap;
}

/* -------------------------------------------------- home: the gallery */

/* Photographs, each with its name held back. Every one is the same 3:2 canvas
   on --photo-ground, so the cells line up whatever shape the plate is and
   nothing needs cropping. Hover a plate and it comes forward a little and its
   name rises along the bottom edge on a paper band; a tap does the same where
   nothing can hover (main.js sets .is-open). The name is a real figcaption,
   so it is in the document whether or not it is on the screen. */
.gallery { margin-top: var(--s6); display: grid; gap: var(--s4);
           grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
           list-style: none; margin-inline: 0; padding: 0; }
.gallery li { margin: 0; }
.gallery__cell {
  position: relative; margin: 0; overflow: hidden; border-radius: 12px;
  background: var(--photo-ground);
  transition: box-shadow 260ms ease;
}
.gallery__img {
  width: 100%; aspect-ratio: 3 / 2; object-fit: contain; display: block;
  transition: transform 420ms cubic-bezier(.22, .61, .36, 1);
}
.gallery__name {
  position: absolute; inset: auto 0 0 0; margin: 0;
  padding: var(--s2) var(--s3);
  background: rgba(255, 255, 255, .92); border-top: 1px solid var(--rule);
  font-family: var(--display); font-size: var(--t-md); line-height: var(--lh-snug);
  letter-spacing: .03em; text-transform: uppercase; color: var(--brand);
  transform: translateY(100%); opacity: 0;
  transition: transform 320ms cubic-bezier(.22, .61, .36, 1), opacity 220ms ease;
}
.gallery__cell.is-open .gallery__name { transform: none; opacity: 1; }
.gallery__cell.is-open .gallery__img { transform: scale(1.06); }
.gallery__cell.is-open { box-shadow: var(--shadow); }
/* :hover only where a pointer can hover. A phone's browser holds :hover on
   whatever was last tapped, which would fight the tap-to-toggle below. */
@media (hover: hover) {
  .gallery__cell:hover .gallery__name { transform: none; opacity: 1; }
  .gallery__cell:hover .gallery__img { transform: scale(1.06); }
  .gallery__cell:hover { box-shadow: var(--shadow); }
}
/* No hover and no script to catch a tap: every name, always. Nothing is ever
   left unreachable. */
@media (hover: none) {
  html:not(.js-gallery) .gallery__name { transform: none; opacity: 1; }
}
@media print {
  .gallery__name { position: static; transform: none; opacity: 1; }
  .gallery__cell { box-shadow: none; }
}
/* On a phone auto-fill drops to one column, and twelve full-width plates is a
   very long scroll for a block whose whole job is to be glanced at. Two
   across, always: at 3:2 each cell is still tall enough to read a plate. */
@media (max-width: 600px) {
  .gallery { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s3); }
}

.prices { margin-top: var(--s5); gap: var(--s2); }
.prices__cell { border-radius: 999px; padding: var(--s2) var(--s4); flex-direction: row;
                align-items: baseline; justify-content: space-between; gap: var(--s3); }
.prices__cell dd { font-size: var(--t-md); }

/* ------------------------------------------------------------ menu page */

/* The home page's two menu devices and nothing else. The chapter photographs
   are the home gallery's own cells (.gallery__cell and friends, untouched, so
   the hover and tap name reveal come with them); the words are the home
   listing's line — the sans name, the Anton price in --brand, a --rule
   hairline closing the line — with the description beneath. No boxes, no
   tinted bands, no empty image slots.

   --head-h is the sticky site header's height and --chapter-nav-h the chapter
   bar's. main.js measures the header and sets --head-h; these are its
   measured values, for when the script has not run. */
:root { --head-h: 77px; --chapter-nav-h: 52px; }
@media (max-width: 640px) { :root { --head-h: 65px; --chapter-nav-h: 48px; } }

/* The top: the home "All in one" split — words left, one plate right. */
.menu-top { padding-block: clamp(28px, 4.5vw, 56px) clamp(24px, 3.5vw, 40px); }
.menu-top__in {
  display: grid; gap: var(--s5) var(--s7); align-items: center;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, .75fr);
}
.menu-top__title { font-size: clamp(2.25rem, 1.4rem + 2.2vw, 3rem); line-height: .98; }
.menu-top__lede { margin-top: var(--s4); color: var(--ink-2); font-size: var(--t-base); max-width: 46ch; }
.menu-top__plate { border-radius: 12px; overflow: hidden; background: var(--paper); }
.menu-top__img { display: block; width: 100%; height: auto; aspect-ratio: 1472 / 704; object-fit: cover; }
@media (max-width: 900px) {
  .menu-top__in { grid-template-columns: 1fr; }
  .menu-top__plate { max-width: 560px; }
}

/* The chapter bar: the header's own vocabulary — plain sans links, the
   current one in --brand with a 2px underline, one hairline under the bar.
   It sticks under the sticky header. */
.chapter-nav {
  position: sticky; top: var(--head-h); z-index: 30;
  background: var(--paper);                 /* where color-mix is unknown */
  background: color-mix(in srgb, var(--paper) 95%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--rule);
}
.chapter-nav__list {
  list-style: none; margin: 0; padding: 0;
  display: flex; gap: var(--s5); align-items: stretch;
  overflow-x: auto; scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.chapter-nav__list::-webkit-scrollbar { display: none; }
.chapter-nav__list li { flex: none; display: flex; }
.chapter-nav__link {
  display: inline-flex; align-items: center; min-height: calc(var(--chapter-nav-h) - 1px);
  font-size: var(--t-sm); font-weight: 500; color: var(--ink-2);
  text-decoration: none; white-space: nowrap;
  box-shadow: inset 0 -2px 0 transparent;
  transition: color 160ms ease, box-shadow 160ms ease;
}
.chapter-nav__link:hover { color: var(--brand); }
.chapter-nav__link[aria-current] { color: var(--brand); box-shadow: inset 0 -2px 0 var(--brand); }
.chapter-nav__link:focus-visible { outline-offset: -3px; }
@media (max-width: 1100px) { .chapter-nav__list { gap: var(--s4); } }
@media (max-width: 1060px) {
  /* The strip scrolls in its own box, edge to edge, and fades where it runs
     out so there is visibly more of it. The page itself never moves sideways. */
  .chapter-nav__in { padding-inline: 0; }
  .chapter-nav__list {
    gap: var(--s5);
    padding-inline: clamp(20px, 5vw, 48px);
    scroll-padding-inline: clamp(20px, 5vw, 48px);
    -webkit-mask-image: linear-gradient(to right, transparent, #000 16px, #000 calc(100% - 28px), transparent);
            mask-image: linear-gradient(to right, transparent, #000 16px, #000 calc(100% - 28px), transparent);
  }
}

/* A chapter. The link lands the chapter name just under the chapter bar:
   html's scroll-padding-top (88px, in the motion section) applies on top of
   this margin, and the section's own top padding comes off it. */
.chapter {
  --chapter-pad: clamp(36px, 5vw, 56px);
  padding-top: var(--chapter-pad);
  scroll-margin-top: calc(var(--head-h) + var(--chapter-nav-h) + 20px - 88px - var(--chapter-pad));
}
.chapter__head { margin-bottom: var(--s4); }
.chapter__name { font-size: var(--t-xl); color: var(--brand); }
.chapter__note { margin-top: var(--s1); font-size: var(--t-sm); color: var(--ink-3); max-width: 72ch; }

/* The chapter's photographs: the home gallery, one row per chapter — as many
   tracks as plates up to four, so a row fills its width. Five or more wrap
   into rows of four. .gallery.chapter__tiles outranks .gallery wherever the
   two disagree. */
.gallery.chapter__tiles { margin: var(--s2) 0 var(--s4); gap: var(--s4); grid-template-columns: repeat(4, minmax(0, 1fr)); }
.gallery.chapter__tiles--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.gallery.chapter__tiles--2 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.chapter__tiles--2 li { grid-column: span 2; }
.gallery.chapter__tiles--1 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* The dishes: the home listing's line with the description under it, two
   columns on the same two edges in every chapter. Rows align across the
   gutter, so the hairlines of a row sit level. */
.dishes {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 0 var(--s7);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.dish { margin: 0; padding: var(--s3) 0; border-bottom: 1px solid var(--rule); }
.dish__row { display: flex; align-items: baseline; gap: var(--s4); }
/* An h3 for the outline, set as the listing's plain sans name. */
.dish__name {
  flex: 1; min-width: 0;
  font-family: var(--sans); font-size: var(--t-sm); font-weight: 500;
  text-transform: none; letter-spacing: 0; line-height: var(--lh-snug);
  color: var(--ink);
}
/* The display face and --brand, as on the home listing: 5.10:1 on white. */
.dish__price {
  flex: none; font-family: var(--display); font-weight: 400;
  font-size: var(--t-md); line-height: 1; color: var(--brand);
  font-variant-numeric: lining-nums; white-space: nowrap;
}
.dish__desc {
  margin-top: var(--s1); font-size: var(--t-sm); line-height: 1.5; color: var(--ink-3);
  max-width: 60ch; font-variant-numeric: tabular-nums;
}
.dish__sep { margin-inline: 2px; color: var(--ink-3); }
.dish__facts { white-space: nowrap; }
.dish__facts .dish__sep { margin-inline: var(--s2); }
.dish__desc .heat { vertical-align: middle; }

/* Heat, on the brand's own five-chilli scale. The pips are aria-hidden and
   redundant: the line already carries "Heat 3 out of 5" for a screen reader,
   so colour is never the only carrier here. The unfilled pips keep a --line
   ring (5.15:1) so the denominator is visible, not implied. */
.heat { display: inline-block; vertical-align: -1px; }
.heat__pips { display: inline-flex; gap: 3px; }
.heat__pip {
  width: 7px; height: 7px; border-radius: 50%;
  border: 1px solid var(--line); background: none;
}
.heat__pip.is-on { background: var(--sauce-chilli); border-color: var(--sauce-chilli); }

/* Extras: a small chapter inside Sides, the chapter-name style one size down. */
.extras { margin: 0; padding-top: var(--s5); grid-column: 1 / -1; }
.extras__title { font-size: var(--t-md); color: var(--brand); margin-bottom: var(--s1); }
.extras__list {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 0 var(--s7); grid-template-columns: repeat(2, minmax(0, 1fr));
}
.extras__item {
  display: flex; align-items: baseline; gap: var(--s4);
  padding: 7px 0; border-bottom: 1px solid var(--rule);
}
.extras__name { flex: 1; min-width: 0; font-size: var(--t-sm); color: var(--ink); }
.extras__tbc { font-size: var(--t-sm); color: var(--ink-3); white-space: nowrap; }

/* The notes: the allergen notice (legally required) and the wings note, as
   plain text under one hairline rather than boxed. */
.menu-notes { padding-block: clamp(48px, 7vw, 80px) clamp(40px, 6vw, 72px); }
.menu-notes__in {
  display: grid; gap: var(--s5) var(--s7);
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  border-top: 1px solid var(--rule); padding-top: var(--s5);
}
.menu-notes .notice {
  margin: 0; border: 0; border-radius: 0; padding: 0; background: none;
  font-size: var(--t-sm); color: var(--ink-2); max-width: 60ch;
}
.menu-notes .notice strong { display: block; color: var(--ink); margin-bottom: var(--s1); }
.menu-notes .follow { grid-column: 1 / -1; margin: 0; }

@media (max-width: 900px) {
  .gallery.chapter__tiles { gap: var(--s3); }   /* four, three or two across */
  .gallery.chapter__tiles--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .chapter__tiles--2 li { grid-column: auto; }
  .dishes, .extras__list { column-gap: var(--s5); }
}

@media (max-width: 640px) {
  .menu-top { padding-top: var(--s5); }
  .menu-top .sec__kicker { font-size: var(--t-sm); }    /* 14px is the phone floor */
  .menu-top__lede { margin-top: var(--s3); }
  .chapter-nav__link { min-height: 48px; }
  .chapter { --chapter-pad: 36px; }
  .chapter__name { font-size: 1.75rem; }
  /* The plates swipe in their own strip, one and a half in view, instead of
     a column of big images. */
  .gallery.chapter__tiles {
    display: flex; gap: var(--s3);
    margin-inline: calc(-1 * clamp(20px, 5vw, 48px));
    padding-inline: clamp(20px, 5vw, 48px);
    scroll-padding-inline: clamp(20px, 5vw, 48px);
    overflow-x: auto; scroll-snap-type: x mandatory;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
  }
  .chapter__tiles::-webkit-scrollbar { display: none; }
  .chapter__tiles li { flex: 0 0 62%; scroll-snap-align: start; }
  .chapter__tiles--2 li { flex-basis: calc(50% - var(--s3) / 2); }
  .dishes, .extras__list { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  .chapter-nav__link { transition: none; }
  .chapter__tiles .gallery__img, .chapter__tiles .gallery__name, .chapter__tiles .gallery__cell { transition: none; }
  .chapter__tiles .gallery__cell:hover .gallery__img,
  .chapter__tiles .gallery__cell.is-open .gallery__img { transform: none; }
}

/* A printed menu is the words: every chapter, every line, no bars. */
@media print {
  .chapter-nav, .chapter__tiles, .menu-top__plate { display: none !important; }
  .menu-top__in { grid-template-columns: 1fr; }
  .chapter { padding-top: 20px; }
  .chapter__head { break-after: avoid; }
  .dish, .extras { break-inside: avoid; }
}

/* --------------------------------------------------------- dark footer */

.foot { background: var(--dark); color: rgba(255,255,255,.78); border-top: 0; }
.foot h2 { color: #FFFFFF; font-family: var(--sans); text-transform: none; letter-spacing: .08em; }
.foot a { color: #FFFFFF; }
.foot__legal { border-top-color: rgba(255,255,255,.14); color: rgba(255,255,255,.62); }

/* --------------------------------------------------------- header CTA */

/* `.nav a` (0,1,1) outranks `.btn--primary` (0,1,0), so the CTA was inheriting
   the nav's link colour: --ink-2 on the brand fill, 2.11:1, and on hover it
   would have been --brand on --brand. Named here, after those rules and at a
   specificity that wins, it is white on brand: 5.10:1. */
.nav__cta { padding: 9px 16px; }
.nav a.nav__cta, .nav a.nav__cta:hover { color: var(--brand-ink); }
@media (max-width: 640px) { .nav__cta { display: none; } }   /* the action bar has it */

/* -------------------------------------------------------- mobile bar */

.actionbar {
  position: sticky; bottom: 0; z-index: 30;
  background: color-mix(in srgb, var(--paper) 94%, transparent);
  backdrop-filter: blur(8px);
  border-top: 1px solid var(--rule);
  padding: var(--s3) 0;
  display: none;
}
@media (max-width: 640px) {
  .actionbar { display: block; padding: var(--s2) 0; }
  .actionbar .wrap { display: flex; gap: var(--s2); }
  .actionbar .btn {
    justify-content: center; white-space: nowrap;
    font-size: 12px; letter-spacing: .04em; padding: 12px 14px;
  }
  .actionbar .btn--ghost { flex: 0 0 auto; }    /* just the width of "Menu" */
  .actionbar .btn--primary { flex: 1; }         /* the long label takes the rest */
  .nav { gap: var(--s3); }
  .nav__link--secondary { display: none; }
  .brandmark img { height: 40px; }
  .head__in { gap: var(--s3); }
}

/* ----------------------------------------------------------- video hero */

.hero--video {
  position: relative; isolation: isolate;
  min-height: clamp(440px, 72vh, 760px);
  display: grid; align-items: end;
  padding-block: 0 clamp(32px, 6vw, 72px);
  color: #FFFFFF;
}
.hero__media { position: absolute; inset: 0; z-index: -1; overflow: hidden; background: #1A1512; }
.hero__poster, .hero__video {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}
/* Two videos alternate; the fade is an opacity crossfade over a real overlap. */
.hero__video { opacity: 0; transition: opacity 900ms ease; }
.hero__video.is-active { opacity: 1; }
/* --scrim guarantees AA over any photograph or frame, sight unseen: white on
   the worst-case composite is 7.83:1; --logo-amber is 4.03:1, so it is
   permitted for the large h1 accent only, never for body text. */
.hero__scrim { position: absolute; inset: 0; background: var(--scrim); }
.hero__text { position: relative; padding-top: clamp(96px, 20vh, 200px); }
.hero--video h1 {
  color: #FFFFFF;
  font-size: clamp(3rem, 1.8rem + 6.2vw, 7rem);
  line-height: .92; max-width: 14ch;
}
.hero--video h1 em { color: var(--logo-amber); }
.hero--video .btn--ghost { color: #FFFFFF; border-color: rgba(255,255,255,.7); }
.hero--video .btn--ghost:hover { color: #FFFFFF; border-color: #FFFFFF; }

@media (prefers-reduced-motion: reduce) {
  /* the poster is the hero; nothing moves */
  .hero__video { display: none; }
}

/* --------------------------------------------------------------- motion */

/* No global smooth scrolling. The in-page links on the site are the skip
   link and the menu's chapter bar, and a jump that glides is a jump that
   fails: a keyboard user pressing it wants to be at the content, now. scroll-padding-top is the fix
   that is actually needed here — it keeps the sticky header from covering
   whatever an anchor lands on. */
html { scroll-padding-top: 88px; }

/* Buttons: a small, fast press. Transform only, so nothing reflows and the
   hit area never moves under a finger mid-tap. */
.btn { transition: filter 160ms ease, color 160ms ease,
                   border-color 160ms ease, transform 160ms ease; }
.btn:active { transform: translateY(1px); }

/* Section reveal on scroll.
   ARMED BY JAVASCRIPT AND ONLY BY JAVASCRIPT. Both halves of it — the
   `js-reveal` class on <html> and the `reveal` class on each block — are
   added by main.js at runtime, so with JavaScript off, before the script
   runs, or if IntersectionObserver is missing, not one selector below
   matches and every section is simply visible. There is no state of this
   stylesheet in which content can be left hidden.
   Only blocks that start below the fold are armed; anything already on
   screen at load is never hidden, so the page does not flash. */
.js-reveal .reveal {
  opacity: 0; transform: translateY(16px);
  transition: opacity 620ms cubic-bezier(.22, .61, .36, 1),
              transform 620ms cubic-bezier(.22, .61, .36, 1);
  will-change: opacity, transform;
}
.js-reveal .reveal.is-in { opacity: 1; transform: none; will-change: auto; }

/* A menu printed off this page must be the whole menu. Anything the visitor
   had not scrolled to is still armed at print time, and a half-faded chapter
   on paper is a bug, not a flourish. */
@media print {
  /* transition:none too — without it the print is taken mid-fade and the
     block lands on paper at whatever opacity the animation had reached. */
  .js-reveal .reveal {
    opacity: 1 !important; transform: none !important; transition: none !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  /* Not "faster" — off. The reveal exists to add rhythm, and to a visitor who
     has asked for no motion its whole contribution is nausea. */
  .js-reveal .reveal, .js-reveal .reveal.is-in {
    opacity: 1; transform: none; transition: none;
  }
  .btn:active { transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
