/* MENU-PUBLIC-01 — Sŏra public menu.
 *
 * Loaded as an external sheet because the CSP is `style-src 'self'` with no 'unsafe-inline':
 * a <style> block or a style="" attribute would be BLOCKED, not merely discouraged.
 *
 * BRAND COLOURS — EXACT, extracted from the two final PDFs on 2026-08-20.
 *
 * Source: /root/sora-menus/SORA-Food-Menu-Editable.pdf and SORA-Beverage-Menu-Final.pdf.
 * Every fill in both files is DeviceRGB (`rg`), there is not one CMYK operator in either
 * document, and both declare /OutputIntent sRGB IEC61966-2.1 — so these operands ARE sRGB and
 * drop straight into CSS with no colour-management conversion. Values agreed byte-for-byte
 * across three independent methods (content-stream operators, PyMuPDF's parser, and a 72dpi
 * raster sample); the raster is the one to distrust, it truncates each channel by 1.
 *
 * ⚠ Two greens and two creams exist in the PDFs. The second of each is a tone-on-tone
 * WATERMARK — the ghosted "BEVERAGE MENU" behind the cover art (#30432C) and the ghosted
 * "SŎRA" behind the inner page (#ECDABF). Neither is a brand colour; do not use them here.
 */
:root {
  --green: #3a4c34;        /* cover background; inner-page headings, rules and footer */
  --cream: #f5e4c8;        /* inner-page background; cover wordmark and subtitle */
  --coral: #ea3436;        /* category headings and the short rule beneath each */

  /* Derived from --cream (245, 228, 200). Keep these in step if --cream ever changes. */
  --cream-dim: rgba(245, 228, 200, 0.62);
  --rule: rgba(245, 228, 200, 0.16);
  --topbar-h: 3.5rem;
  --measure: 34rem;
}

/* Self-hosted (§7.3) — font-src 'self' means a Google Fonts request would be blocked.
 *
 * Jost ships from Google as a VARIABLE font: the 400 and 600 downloads are byte-identical
 * (md5 verified), so shipping one file per subset instead of one per weight halves the payload
 * with no visual difference. `font-weight: 100 900` tells the browser this single file covers the
 * whole axis, and the 600 used for headings is a real instance of it, not a synthesised bold.
 *
 * Two subsets, not one: the wordmark is "S\u014Fra" and U+014F lives in latin-ext. Loading only
 * the latin subset would render the brand's own name in a fallback face. The unicode-range pairs
 * are Google's, kept verbatim so a browser fetches latin-ext only when a page actually needs it.
 */
@font-face {
  font-family: "Jost";
  src: url("/fonts/jost-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Jost";
  src: url("/fonts/jost-latin-ext.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

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

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

body {
  margin: 0;
  padding-top: var(--topbar-h);
  background: var(--green);
  color: var(--cream);
  font-family: "Jost", "Futura", "Century Gothic", system-ui, -apple-system, sans-serif;
  font-weight: 400;
  line-height: 1.45;
  letter-spacing: 0.01em;
}

/* ── Fixed header: the brand never leaves the screen (§7.1) ─────────────────────────────────── */
.topbar {
  position: fixed;
  inset: 0 0 auto 0;
  height: var(--topbar-h);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--green);
  border-bottom: 1px solid var(--rule);
  z-index: 10;
}
.wordmark {
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--cream);
  text-decoration: none;
}

.page {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 1.75rem 1.25rem 3rem;
}

/* ── CSS-only tabs (§7.1). No JS: the radios drive the panels via :checked ~ sibling. ───────── */
.tabs__radio {
  position: absolute;
  opacity: 0;            /* kept focusable for keyboard use — never display:none */
  width: 1px;
  height: 1px;
}
.tabs__list {
  display: flex;
  gap: 0.5rem;
  border-bottom: 1px solid var(--rule);
  margin-bottom: 1.75rem;
}
.tabs__tab {
  flex: 1 1 50%;
  padding: 0.65rem 0.25rem;
  text-align: center;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--cream-dim);
  border-bottom: 2px solid transparent;
  cursor: pointer;
}
.panel { display: none; }

#tab-food:checked ~ .tabs__list .tabs__tab--food,
#tab-beverage:checked ~ .tabs__list .tabs__tab--beverage {
  color: var(--cream);
  border-bottom-color: var(--coral);
}
#tab-food:checked ~ .panel--food,
#tab-beverage:checked ~ .panel--beverage { display: block; }

/* Visible focus ring for keyboard users, since the control itself is transparent. */
.tabs__radio:focus-visible ~ .tabs__list .tabs__tab--food,
.tabs__radio:focus-visible ~ .tabs__list .tabs__tab--beverage {
  outline: 2px solid var(--coral);
  outline-offset: -2px;
}

/* ── Sections and items ─────────────────────────────────────────────────────────────────────── */
.section { margin: 0 0 2.25rem; }
.section__title {
  margin: 0 0 0.9rem;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--coral);
}

/* 0145's category `public_note` — one line qualifying a whole section ("All signature rolls are 8
 * pieces unless otherwise stated."). Sits between the heading and the first item, and is
 * deliberately NOT uppercased: it is a sentence, not a label, and .section__title's shouting caps
 * would make it read as a second heading. Muted like .item__desc so it reads as a qualifier rather
 * than competing with the items. */
.section__note {
  margin: -0.45rem 0 1rem;
  font-size: 0.85rem;
  font-style: italic;
  color: var(--cream-dim);
  max-width: 34rem;
}

.items { list-style: none; margin: 0; padding: 0; }

.item { padding: 0 0 1.1rem; }
.item + .item {
  padding-top: 1.1rem;
  border-top: 1px solid var(--rule);
}
.item__head {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
}
/* Print sets every item name in capitals ("CÎROC", "SALMON SASHIMI"). That is done HERE and not in
 * the database: casing is presentation, and storing "CÎROC" in `name` would make the till, the
 * reports and every sold-line snapshot inherit the shouting. This one declaration also covers all
 * ~60 published rows, where a data fix would only reach the handful that carry a `public_name`.
 *
 * `letter-spacing` is lighter than .section__title's 0.2em — at 1.02rem the names are set much
 * larger than the 0.78rem headings, and tracking that wide reads as a heading rather than an item.
 */
.item__name {
  margin: 0;
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  flex: 1 1 auto;
}
.item__price {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  white-space: nowrap;
}
.item__desc {
  margin: 0.3rem 0 0;
  font-size: 0.9rem;
  color: var(--cream-dim);
  max-width: 30rem;
  /* pre-line, NOT pre-wrap. Newlines in a description become line breaks; runs of spaces still
   * collapse and the text still wraps normally. pre-wrap would additionally preserve accidental
   * double spaces and indentation from whatever editor last touched the row, which is not a
   * decision anyone made.
   *
   * Exactly ONE published description carries a newline: I0050 Mochi, where print sets a dual-price
   * line above the flavour line and the two must not run together. Verified 2026-08-21 across all
   * 59 published rows — 36 have a description, 1 contains chr(10), 0 contain chr(13) or a tab, and
   * 0 contain a double space. Without this rule that newline collapses to a space and the two
   * sentences read as one.
   *
   * ⚠ This is a page-wide rule justified by a one-row scan. If a second description ever gains a
   * newline it will start breaking too, with nobody told. */
  white-space: pre-line;
}

/* ── 86'd, in service (§4.3). Section keeps its shape; the row is dimmed, not removed. ──────── */
.item--unavailable .item__name,
.item--unavailable .item__desc { opacity: 0.45; }
.item--unavailable .item__price {
  opacity: 0.45;
  text-decoration: line-through;
}
.item__flag {
  margin: 0.3rem 0 0;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--coral);
}

.empty { color: var(--cream-dim); font-size: 0.92rem; }

/* ── Landing (§9) ───────────────────────────────────────────────────────────────────────────── */
.page--landing { padding-top: 3.5rem; text-align: center; }
.lede {
  margin: 0 0 2.5rem;
  font-size: 1.05rem;
  letter-spacing: 0.05em;
  color: var(--cream-dim);
}
.doors { display: flex; flex-direction: column; gap: 0.9rem; }
.door {
  display: block;
  padding: 1.05rem 1.25rem;
  font-size: 0.86rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid var(--cream);
  color: var(--cream);
}
.door--reserve {
  background: var(--coral);
  border-color: var(--coral);
}
.door__aside { margin: 0.4rem 0 0; font-size: 0.85rem; }
.door__aside a { color: var(--cream-dim); }

.footer {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 0 1.25rem 2.5rem;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  color: var(--cream-dim);
}
.footer p { margin: 0; }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}
