/* =============================================================================
   market.com.sg — v2 "Stall Number"
   Every value derives from design.md. Do not invent outside it.
   Contrast figures in comments are measured, not estimated.
   ========================================================================== */

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

:root {
  /* ── Surfaces (design.md §3) ── */
  --signboard:       oklch(0.34 0.055 195);
  --signboard-deep:  oklch(0.26 0.045 197);
  --signboard-edge:  oklch(0.44 0.045 195);   /* dividers on dark: decorative */
  --signboard-ctl:   oklch(0.62 0.035 195);   /* control edges on dark: 3.1:1 */
  --enamel:          oklch(0.96 0.018 85);
  --enamel-sunk:     oklch(0.925 0.020 85);
  --enamel-edge:     oklch(0.82 0.020 88);   /* dividers: decorative, exempt from 3:1 */
  --enamel-edge-ctl: oklch(0.60 0.022 88);   /* control edges: 3.51:1 */

  /* ── Ink and accents ── */
  --ink:         oklch(0.24 0.040 197);
  --ember:       oklch(0.68 0.210 45);       /* the one saturated accent */
  --ember-deep:  oklch(0.48 0.170 42);       /* 6.26:1 on enamel, 5.63:1 on enamel-sunk */
  --turmeric:    oklch(0.80 0.150 85);       /* numerals and fills only, never type on light */
  --slate:       oklch(0.50 0.030 195);      /* 5.26:1 */
  --slate-light: oklch(0.74 0.025 195);      /* 5.02:1 on signboard */
  --open:        oklch(0.48 0.115 160);      /* 5.45:1 */
  --closed:      oklch(0.50 0.150 25);

  /* ── Type (§4) ── */
  --display: "Archivo", system-ui, sans-serif;
  --body:    "Public Sans", system-ui, -apple-system, "Segoe UI", sans-serif;

  --step--1: clamp(11px, 0.68rem + 0.05vw, 12px);
  --step-0:  clamp(15px, 0.90rem + 0.10vw, 16px);
  --step-1:  clamp(18px, 1.00rem + 0.50vw, 22px);
  --step-2:  clamp(26px, 1.30rem + 1.50vw, 38px);
  --step-3:  clamp(34px, 1.40rem + 3.60vw, 68px);

  /* ── Structure (§5) ── */
  --shell: 1180px;
  --gut:   clamp(18px, 4vw, 40px);
  --bar-h: 66px;

  --s1: 6px;  --s2: 10px; --s3: 16px; --s4: 26px;
  --s5: 42px; --s6: 68px; --s7: 110px;

  --ease: cubic-bezier(0.22, 0.9, 0.24, 1);
}

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

body {
  background: var(--enamel);
  color: var(--ink);
  font-family: var(--body);
  font-size: var(--step-0);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Anchors and focus-scroll must clear the fixed bar. */
[id] { scroll-margin-top: calc(var(--bar-h) + 12px); }

img { display: block; max-width: 100%; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
input  { font: inherit; color: inherit; }
a { color: inherit; }

:focus-visible { outline: 2px solid var(--ember); outline-offset: 3px; }

.shell { width: 100%; max-width: var(--shell); margin-inline: auto; padding-inline: var(--gut); }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Skip link — keyboard users shouldn't tab the header on every page. */
.skip {
  position: absolute; left: var(--gut); top: -60px; z-index: 400;
  background: var(--ember); color: var(--ink);
  padding: 12px 18px;
  transition: top 0.15s var(--ease);
}
.skip:focus { top: 12px; }

/* ── Utility type: Archivo narrow, uppercase, tracked (§4) ── */
.u {
  font-family: var(--display);
  font-variation-settings: "wdth" 66;
  font-weight: 600;
  font-size: var(--step--1);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}

/* ── Display type: Archivo wide, uppercase, tight (§4) ── */
.d {
  font-family: var(--display);
  font-variation-settings: "wdth" 120;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 0.98;
  text-transform: uppercase;
  text-wrap: balance;
}

/* ═══ FILM GRAIN ═══════════════════════════════════════════════════════════
   Static. §7 bans ambient background motion, and a crawling grain is that. */
.grain {
  position: fixed; inset: 0;
  z-index: 200;
  pointer-events: none;
  opacity: 0.09;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
}

/* ═══ CUSTOM CURSOR ════════════════════════════════════════════════════════
   Set USE_CURSOR = false at the top of assets/js/app.js to remove entirely. */
.cur-dot, .cur-ring {
  position: fixed; top: 0; left: 0;
  z-index: 300; pointer-events: none; border-radius: 50%;
  will-change: transform;
}
.cur-dot { width: 6px; height: 6px; margin: -3px 0 0 -3px; background: var(--ember); }
.cur-ring {
  width: 26px; height: 26px; margin: -13px 0 0 -13px;
  border: 1px solid color-mix(in oklch, var(--ember) 70%, transparent);
  transition: width 0.18s var(--ease), height 0.18s var(--ease),
              margin 0.18s var(--ease), border-color 0.18s var(--ease);
}
.cur-ring.on { width: 46px; height: 46px; margin: -23px 0 0 -23px; border-color: var(--ember); }
body.has-cursor,
body.has-cursor a,
body.has-cursor button,
body.has-cursor label { cursor: none; }
body.has-cursor input { cursor: text; }

/* ═══ HEADER ═══════════════════════════════════════════════════════════════ */
.hdr {
  position: fixed; top: 0; left: 0; right: 0; z-index: 90;
  min-height: var(--bar-h);
  display: flex; align-items: center; gap: var(--s4);
  padding: var(--s2) var(--gut);
  background: var(--signboard);
  border-bottom: 2px solid var(--ember);
  transition: background 0.3s var(--ease);
}
body.past-hero .hdr,
body.results-mode .hdr { background: var(--signboard-deep); }

/* The inertia rig. The header must stay outside #viewport: position:fixed
   cannot survive inside a transformed ancestor. Desktop pointers only, so
   #viewport is inert on phones and native scrolling is untouched. */
#page { padding-top: var(--bar-h); }
body.smooth #viewport {
  position: fixed; top: 0; left: 0; width: 100%;
  height: 100vh; height: 100svh;   /* vh first for Safari < 15.4 */
  overflow: hidden;
}
body.smooth #page { will-change: transform; }

/* Header search: hidden on the home hero, present everywhere else. */
.hdr-search {
  flex: 1 1 auto; min-width: 0; max-width: 420px;
  display: flex; align-items: center; gap: var(--s2);
  padding: 7px 12px;
  border: 1px solid var(--signboard-ctl);
  background: var(--signboard-deep);
  opacity: 0; visibility: hidden;
  transition: opacity 0.25s var(--ease), visibility 0.25s var(--ease);
}
body.past-hero .hdr-search,
body.results-mode .hdr-search,
body.no-hero .hdr-search { opacity: 1; visibility: visible; }
.hdr-search input {
  flex: 1; min-width: 0; border: 0; background: none; outline: none;
  color: var(--enamel); font-weight: 300;
  font-size: 16px;   /* never lower: iOS zooms the page on focus below 16 */
}
.hdr-search input::placeholder { color: var(--slate-light); }
.hdr-search .u { color: var(--ember); }
/* This is the only pointer-driven way to run a search from the header, so it
   carries a real target size, not the 17px the utility type computes to. */
.hdr-search button {
  color: var(--ember);
  display: flex; align-items: center; justify-content: center;
  flex: 0 0 auto;
  min-width: 44px; min-height: 40px;
  padding: 0 4px;
}

.hdr-nav { margin-left: auto; display: flex; align-items: center; gap: var(--s4); }
.hdr-nav a {
  color: var(--slate-light); text-decoration: none;
  padding: var(--s1) 0; border-bottom: 1px solid transparent;
  transition: color 0.15s linear, border-color 0.15s linear;
}
.hdr-nav a:hover { color: var(--enamel); border-bottom-color: var(--ember); }

@media (max-width: 760px) { .hdr-nav a.opt { display: none; } .hdr-search { max-width: none; } }

/* ── Lantern lockup (§10, carried forward unchanged) ── */
.logo {
  display: inline-flex; align-items: center; gap: 0.5em;
  text-decoration: none; line-height: 1; flex: 0 0 auto;
  --msg-h: 40px;
}
.logo__mark { height: var(--msg-h); width: auto; overflow: visible; flex: 0 0 auto; }
.logo__word {
  display: flex;
  font-family: var(--display);
  font-variation-settings: "wdth" 100;
  font-weight: 800;
  font-size: calc(var(--msg-h) * 0.52);
  letter-spacing: -0.03em;
  white-space: nowrap;
}
.logo__word span { display: inline-block; }
.logo__word .a { color: var(--enamel); }
.logo__word .b { color: var(--slate-light); font-weight: 500; }
.logo__word .c { color: var(--ember); }
@media (max-width: 620px) { .logo { --msg-h: 32px; } .logo__word { display: none; } }

/* ═══ HERO ═════════════════════════════════════════════════════════════════ */
.hero {
  position: relative; isolation: isolate;
  background: var(--signboard-deep);
  color: var(--enamel);
  padding: clamp(52px, 9vw, 104px) 0 clamp(46px, 8vw, 92px);
  border-bottom: 2px solid var(--ember);
  overflow: hidden;
}
.hero-photo {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 62%;
}
/* A 2.4:1 frame overflows horizontally on a phone, so only the X component
   applies. Shift right to keep the lit stall in shot. */
@media (max-width: 620px) { .hero-photo { object-position: 64% 50%; } }

.hero::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(90deg,
      color-mix(in oklch, var(--signboard-deep) 78%, transparent) 0%,
      color-mix(in oklch, var(--signboard-deep) 72%, transparent) 62%,
      color-mix(in oklch, var(--signboard-deep) 68%, transparent) 100%),
    color-mix(in oklch, var(--signboard-deep) 40%, transparent);
}

.hero-inner { position: relative; max-width: 940px; margin-inline: auto; padding-inline: var(--gut); }
.hero-thesis, .hero-panel { will-change: transform; }
.hero .brand { color: var(--slate-light); }

.hero h1 {
  font-family: var(--display);
  font-variation-settings: "wdth" 120;
  font-weight: 800;
  font-size: var(--step-3);
  letter-spacing: -0.02em;
  line-height: 0.96;
  text-transform: uppercase;
  text-wrap: balance;
  margin-top: var(--s4);
  max-width: 15ch;
}
/* The instruction tier. Sits between the claim and the lede, at full enamel so
   it reads before the quieter line under it. Sentence case, body face: an
   all-caps sentence this long would break §4. */
.hero-sub {
  margin-top: var(--s4);
  max-width: 40ch;
  font-weight: 500;
  font-size: clamp(17px, 1rem + 0.4vw, 21px);
  line-height: 1.32;
  color: var(--enamel);
}
.hero-lede {
  margin-top: var(--s3); max-width: 54ch;
  font-weight: 300;
  font-size: clamp(15px, 0.9rem + 0.25vw, 17px);
  line-height: 1.6;
  color: color-mix(in oklch, var(--enamel) 84%, transparent);
}
.hero-panel { margin-top: var(--s5); }

/* The lit menu panel on the signboard (§8) */
.panel {
  display: flex; align-items: stretch;
  background: var(--enamel);
  box-shadow: 5px 5px 0 oklch(0.20 0.03 197);
}
.panel:focus-within { box-shadow: 5px 5px 0 var(--ember); }
.panel label { display: flex; align-items: center; padding-left: var(--s3); color: var(--slate); }
.panel input {
  flex: 1; min-width: 0; border: 0; background: none; outline: none;
  padding: 19px var(--s3);
  font-size: var(--step-1); font-weight: 300; color: var(--ink);
}
.panel input::placeholder { color: var(--slate); }
.panel button.go {
  flex: 0 0 auto; display: flex; align-items: center;
  padding: 0 clamp(18px, 3vw, 30px);
  background: var(--ember); color: var(--ink);   /* §3 rule 3: ink on ember */
  transition: background 0.15s linear, color 0.15s linear;
}
.panel button.go:hover { background: var(--ember-deep); color: var(--enamel); }
.panel button.go:focus-visible { outline-offset: -5px; outline-color: var(--ink); }

@media (max-width: 620px) {
  .panel { flex-wrap: wrap; }
  .panel input { padding: 15px var(--s2); font-size: 17px; }
  .panel button.go { width: 100%; justify-content: center; padding: 14px; }
}

.hero-try { margin-top: var(--s3); display: flex; flex-wrap: wrap; gap: var(--s1) var(--s3); align-items: baseline; }
.hero-try .lbl { color: var(--slate-light); }
.hero-try button {
  color: color-mix(in oklch, var(--enamel) 80%, transparent);
  border-bottom: 1px solid var(--signboard-ctl);
  transition: color 0.15s linear, border-color 0.15s linear;
}
.hero-try button:hover { color: var(--turmeric); border-bottom-color: var(--turmeric); }

/* ═══ SECTION FRAME ════════════════════════════════════════════════════════ */
.sec { padding: clamp(52px, 8vw, 96px) 0; }
.sec--sunk { background: var(--enamel-sunk); }

.eyebrow { display: flex; align-items: center; gap: var(--s3); color: var(--slate); }
.eyebrow::after { content: ""; flex: 1; height: 1px; background: var(--enamel-edge); }

.sec h2 { font-size: var(--step-2); margin-top: var(--s4); max-width: 20ch; }
.sec-note { margin-top: var(--s3); max-width: 56ch; font-weight: 300; }

/* ═══ THE STALL PLATE — the signature element (§6) ═════════════════════════ */
.plates { margin-top: var(--s5); }

.plate {
  display: grid;
  grid-template-columns: 54px minmax(0, 1fr);
  background: var(--enamel);
  border: 1px solid var(--enamel-edge);
  transition: transform 0.15s ease-out;
}
.plate + .plate { margin-top: var(--s2); }
.plate:hover { transform: translateX(2px); }

.plate-no {
  display: flex; align-items: flex-start; justify-content: center;
  padding-top: 17px;
  background: color-mix(in oklch, var(--turmeric) 42%, var(--enamel));
  color: var(--ink);
  font-family: var(--display);
  font-variation-settings: "wdth" 66;
  font-weight: 700; font-size: 15px; letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums;
  transition: background 0.15s linear;
}
.plate:hover .plate-no { background: var(--turmeric); }

.plate-body { padding: var(--s3) var(--s4) var(--s3) var(--s3); min-width: 0; }
.plate-top { display: flex; gap: var(--s3); align-items: flex-start; }

.plate-thumb {
  display: block; flex: 0 0 auto;
  width: 76px; height: 76px;
  border: 1px solid var(--enamel-edge);
  background: var(--enamel-sunk);
  overflow: hidden;
}
.plate-thumb img { width: 100%; height: 100%; object-fit: cover; }

.plate-info { min-width: 0; flex: 1; }

.plate-name {
  font-family: var(--display);
  font-variation-settings: "wdth" 118;
  font-weight: 700;
  font-size: var(--step-1);
  line-height: 1.02;
  letter-spacing: -0.015em;
  text-transform: uppercase;
}
.plate-name a { text-decoration: none; }
.plate-name a:hover { color: var(--ember-deep); text-decoration: underline; text-underline-offset: 3px; }

.plate-cat { color: var(--slate); margin-top: var(--s1); display: block; }

/* Meta strip — fixed order (§8): rating · count · open · distance · price */
.plate-meta {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--s1) var(--s3);
  margin-top: var(--s2);
  color: var(--slate);
}
.plate-meta .rat { color: var(--ink); }
/* Distance is the second thing read on a "what's good near me" site, so it
   carries ink weight rather than sitting in the grey run of meta. */
.plate-meta .dist { color: var(--ink); font-weight: 700; }
/* "170 M" reads as mega-, not metres. The strip is uppercased by .u, so the
   unit opts out and keeps a hair of space in front of it. */
.plate-meta .dist .unit { text-transform: lowercase; margin-left: 3px; letter-spacing: 0.04em; }
.plate-meta .rat i { font-style: normal; color: var(--ember-deep); }
.plate-meta .open { color: var(--open); }
.plate-meta .shut { color: var(--closed); }

.plate-addr  { margin-top: var(--s2); font-size: 14px; font-weight: 300; color: var(--slate); }
.plate-desc  { margin-top: var(--s2); font-size: 14px; font-weight: 300; color: var(--slate); max-width: 62ch; }
.plate-hours { margin-top: var(--s1); color: var(--slate); }

.plate-acts { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s3); }

.btn {
  display: inline-flex; align-items: center;
  min-height: 44px;
  padding: 8px 16px;
  border: 1px solid var(--enamel-edge-ctl);
  color: var(--slate);
  text-decoration: none;
  transition: border-color 0.15s linear, color 0.15s linear, background 0.15s linear;
}
.btn:hover { border-color: var(--ink); color: var(--ink); }
.btn--go { background: var(--ember); border-color: var(--ember); color: var(--ink); }
.btn--go:hover { background: var(--ember-deep); border-color: var(--ember-deep); color: var(--enamel); }

@media (max-width: 560px) {
  .plate { grid-template-columns: 38px minmax(0, 1fr); }
  .plate-body { padding: var(--s3) var(--s3) var(--s3) var(--s2); }
  .plate-thumb { width: 60px; height: 60px; }
  .plate-name { font-size: var(--step-0); }
}

/* ═══ RESULTS VIEW ═════════════════════════════════════════════════════════ */
#view-results { display: none; }
body.results-mode #view-home { display: none; }
body.results-mode #view-results { display: block; }

.res-head { border-bottom: 1px solid var(--enamel-edge); background: var(--enamel-sunk); }
.res-head-in {
  max-width: var(--shell); margin-inline: auto;
  padding: var(--s4) var(--gut);
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--s3); flex-wrap: wrap;
}
.res-q {
  font-family: var(--display);
  font-variation-settings: "wdth" 118;
  font-weight: 700; font-size: var(--step-2);
  text-transform: uppercase; letter-spacing: -0.02em; line-height: 1;
}
.res-count { color: var(--slate); margin-top: var(--s2); }

/* Where "me" is. One line, one button, a list that stays shut until asked. */
.res-from { position: relative; margin-top: var(--s1); }
.from-lbl { color: var(--slate); }
.from-btn {
  color: var(--ink);
  border-bottom: 2px solid var(--ember);
  padding: 2px 0;
  min-height: 32px;
}
.from-btn:hover { color: var(--ember-deep); }
.from-menu {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 70;
  display: flex; flex-direction: column;
  min-width: 200px;
  background: var(--enamel);
  border: 1px solid var(--enamel-edge-ctl);
  box-shadow: 5px 5px 0 color-mix(in oklch, var(--ink) 14%, transparent);
}
.from-menu[hidden] { display: none; }
.from-opt {
  text-align: left;
  padding: var(--s2) var(--s3);
  min-height: 44px;
  color: var(--ink);
  border-bottom: 1px solid var(--enamel-edge);
}
.from-opt:last-child { border-bottom: 0; }
.from-opt:hover, .from-opt:focus-visible { background: var(--turmeric); }

.res-tools { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }

/* Required Google attribution. Sits inside the results container, not the site
   footer, because the policy requires it in the same visual container as the
   data. Do not move it, hide it, or drop its opacity. */
.gattr {
  max-width: var(--shell);
  margin-inline: auto;
  padding: 0 var(--gut) var(--s3);
  display: flex; align-items: center;
}
/* Rendered at its native 98x18. Google's brand guidance prohibits distorting,
   recolouring or shrinking the mark below its supplied size, so this carries no
   height override and no opacity. */
.gattr img { width: 98px; height: 18px; }

.photo-credit { margin-top: var(--s2); color: var(--slate); }
.photo-credit a { color: var(--slate); text-decoration: underline; text-underline-offset: 2px; }
.photo-credit a:hover { color: var(--ember-deep); }
.toggle {
  display: inline-flex; align-items: center; gap: var(--s1);
  min-height: 44px; padding: 8px 15px;
  border: 1px solid var(--enamel-edge-ctl);
  color: var(--slate);
  transition: 0.15s linear;
}
.toggle:hover { border-color: var(--open); color: var(--open); }
.toggle[aria-pressed="true"] { background: var(--open); border-color: var(--open); color: var(--enamel); }

/* Single column. The map is gone, and the sidebar's only other widget restated
   the first four results, which are already at the top of the list. A results
   list also reads better at a measure this side of the full shell width. */
.res-body {
  max-width: 880px; margin-inline: auto;
  padding: var(--s5) var(--gut) var(--s7);
}

.res-main .plates { margin-top: 0; }

.load-more {
  width: 100%; margin-top: var(--s4);
  min-height: 52px; padding: 15px;
  border: 1px solid var(--ink); color: var(--ink);
  transition: 0.15s linear;
}
.load-more:hover { background: var(--ink); color: var(--enamel); }

/* Loading: one ember sweep, no spinner, no skeletons (§8) */
.loading { display: none; padding: var(--s6) var(--gut); text-align: center; }
body.searching .loading { display: block; }
body.searching .res-body { display: none; }
.loading .bar {
  width: 200px; height: 2px; margin: 0 auto var(--s3);
  background: var(--enamel-edge); position: relative; overflow: hidden;
}
.loading .bar::after {
  content: ""; position: absolute; inset: 0; width: 40%;
  background: var(--ember); animation: sweep 1s linear infinite;
}
@keyframes sweep { from { transform: translateX(-100%); } to { transform: translateX(250%); } }
.loading p { color: var(--slate); }

/* Empty state: direction, not mood (§8) */
.empty { padding: var(--s6) 0; max-width: 46ch; }
.empty h3 { font-size: var(--step-1); }
.empty p { margin-top: var(--s2); color: var(--slate); }
.empty .btn { margin-top: var(--s4); }

/* ── Sidebar ── */
/* ═══ HOME SECTIONS ════════════════════════════════════════════════════════ */
.queries { margin-top: var(--s5); columns: 3; column-gap: var(--s5); }
@media (max-width: 860px) { .queries { columns: 2; } }
@media (max-width: 520px) { .queries { columns: 1; } }

.q {
  display: block; width: 100%; text-align: left;
  break-inside: avoid;
  min-height: 44px; padding: 11px 0;
  border-bottom: 1px solid var(--enamel-edge);
  color: var(--ink); font-weight: 300;
  transition: padding-left 0.15s var(--ease), color 0.15s linear;
}
.q::before {
  content: "\2192";
  font-family: var(--display); font-variation-settings: "wdth" 66;
  font-size: 11px; color: var(--slate); margin-right: var(--s2);
}
.q:hover { color: var(--ember-deep); padding-left: var(--s2); }

.rows { margin-top: var(--s5); border-top: 1px solid var(--enamel-edge); }
.row {
  display: grid; grid-template-columns: 168px minmax(0, 1fr);
  gap: var(--s4);
  padding: var(--s4) 0;
  border-bottom: 1px solid var(--enamel-edge);
  border-left: 2px solid transparent;
  transition: border-left-color 0.15s linear, padding-left 0.15s var(--ease);
}
.row:hover { border-left-color: var(--ember); padding-left: var(--s3); }
.row:hover .row-lbl { color: var(--ink); }
.row-lbl { color: var(--slate); padding-top: 3px; transition: color 0.15s linear; }
.row-body h3 {
  font-family: var(--display); font-variation-settings: "wdth" 116;
  font-weight: 700; font-size: var(--step-1);
  letter-spacing: -0.015em; text-transform: uppercase; line-height: 1.05;
}
.row-body p { margin-top: var(--s2); max-width: 58ch; font-weight: 300; }
@media (max-width: 700px) { .row { grid-template-columns: 1fr; gap: var(--s2); } }

/* ═══ CLOSING BAND ═════════════════════════════════════════════════════════ */
.band {
  background: var(--signboard-deep); color: var(--enamel);
  padding: clamp(52px, 8vw, 96px) 0;
  border-top: 2px solid var(--ember);
}
.band-in { max-width: 820px; margin-inline: auto; padding-inline: var(--gut); position: relative; }
.band h2 { font-size: var(--step-2); max-width: 18ch; }
.band-lede { margin-top: var(--s3); max-width: 46ch; font-weight: 300; color: color-mix(in oklch, var(--enamel) 84%, transparent); }
.band .panel-wrap { margin-top: var(--s4); }
.band-meta { margin-top: var(--s4); display: flex; flex-wrap: wrap; gap: var(--s2) var(--s5); color: var(--slate-light); }
.band-meta span { display: block; }
.band-meta b { display: block; color: var(--enamel); font-weight: inherit; margin-top: 3px; }

/* ═══ FOOTER ═══════════════════════════════════════════════════════════════ */
.ftr {
  background: var(--signboard); color: var(--slate-light);
  padding: clamp(38px, 6vw, 62px) 0 var(--s5);
  border-top: 2px solid var(--ember);
}
.ftr-top { display: flex; flex-wrap: wrap; gap: var(--s4) var(--s6); align-items: flex-start; justify-content: space-between; }
.ftr-tag {
  font-family: var(--display); font-variation-settings: "wdth" 116;
  font-weight: 700; font-size: var(--step-1);
  text-transform: uppercase; letter-spacing: -0.015em; color: var(--enamel);
}
.ftr-tag em { font-style: normal; color: var(--ember); }
.ftr-links { display: flex; flex-wrap: wrap; gap: var(--s2) var(--s4); }
.ftr-links a { color: var(--slate-light); text-decoration: none; transition: color 0.15s linear; }
.ftr-links a:hover { color: var(--turmeric); }   /* ember is only 3.68:1 here */
.ftr-fine {
  margin-top: var(--s5); padding-top: var(--s4);
  border-top: 1px solid var(--signboard-edge);
  display: flex; flex-wrap: wrap; gap: var(--s1) var(--s4);
  justify-content: space-between;
  color: var(--slate-light);
}

/* ═══ LEGAL PAGES ══════════════════════════════════════════════════════════ */
.legal { max-width: 760px; margin-inline: auto; padding: clamp(40px, 7vw, 76px) var(--gut) var(--s7); }
.legal h1 { font-size: var(--step-2); }
.legal h2 {
  font-size: var(--step-1); margin-top: var(--s5);
  padding-top: var(--s3); border-top: 1px solid var(--enamel-edge);
}
.legal p, .legal li { margin-top: var(--s2); color: var(--slate); }
.legal ul { margin-top: var(--s2); padding-left: 20px; }
.legal a { color: var(--ember-deep); }
.legal .updated { color: var(--slate); margin-top: var(--s2); }

/* Carried over from the v1 legal templates so the clause markup keeps working. */
.legal .page-badge {
  display: inline-block;
  font-family: var(--display); font-variation-settings: "wdth" 66;
  font-weight: 600; font-size: var(--step--1);
  letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--ink);
  background: var(--turmeric);
  padding: 5px 10px;
  margin-bottom: var(--s3);
}
.legal h1 { font-family: var(--display); font-variation-settings: "wdth" 118; text-transform: uppercase; }
.legal .effective-date {
  font-family: var(--display); font-variation-settings: "wdth" 66;
  font-size: var(--step--1); letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--slate); margin-top: var(--s2);
}
.legal .highlight-box,
.legal .warning-box,
.legal .contact-box {
  margin-top: var(--s4);
  padding: var(--s3) var(--s4);
  background: var(--enamel-sunk);
  border-left: 3px solid var(--ember);
  color: var(--ink);
}
.legal .warning-box { border-left-color: var(--closed); }
.legal .contact-box { border-left-color: var(--turmeric); }
.legal .highlight-box p,
.legal .warning-box p,
.legal .contact-box p { color: inherit; }
.legal strong { font-weight: 500; color: var(--ink); }

/* ═══ TOAST ════════════════════════════════════════════════════════════════ */
#toast {
  position: fixed; left: 50%; bottom: 26px;
  transform: translate(-50%, 20px);
  z-index: 310;
  padding: 12px 20px;
  background: var(--signboard-deep); color: var(--enamel);
  border-left: 3px solid var(--ember);
  opacity: 0; pointer-events: none;
  transition: opacity 0.22s, transform 0.22s;
  max-width: calc(100vw - 40px);
}
#toast.show { opacity: 1; transform: translate(-50%, 0); }

/* ═══ MOTION (§7 — Smooth & premium) ═══════════════════════════════════════ */
@keyframes settle {
  0%   { opacity: 0; transform: translateY(-14px); }
  64%  { opacity: 1; transform: translateY(3px); }
  100% { opacity: 1; transform: translateY(0); }
}
.hero-inner { animation: settle 0.6s var(--ease) both; }

.js .r {
  opacity: 0; transform: translateY(18px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
  transition-delay: var(--d, 0ms);
}
.js .r.in { opacity: 1; transform: none; }

/* ── Lantern mark: entry + idle sway, the one permitted loop ── */
@keyframes lg-wire   { from { opacity: 0; transform: translateX(-14px); } to { opacity: 1; transform: translateX(0); } }
@keyframes lg-ignite { 0% { opacity: 0; transform: scale(.82); } 55% { opacity: 1; } 100% { opacity: 1; transform: scale(1); } }
@keyframes lg-glow   { 0% { opacity: 0; } 30% { opacity: .95; } 100% { opacity: .62; } }
@keyframes lg-breathe{ 0%, 100% { opacity: .40; } 50% { opacity: .78; } }
@keyframes lg-sway1  { 0%, 100% { transform: rotate(-3.4deg); } 50% { transform: rotate(2.6deg); } }
@keyframes lg-sway2  { 0%, 100% { transform: rotate(2.9deg); }  50% { transform: rotate(-3.1deg); } }
@keyframes lg-sway3  { 0%, 100% { transform: rotate(-2.4deg); } 50% { transform: rotate(3.6deg); } }
@keyframes lg-tassel { 0%, 100% { transform: rotate(-5deg); }   50% { transform: rotate(5deg); } }
@keyframes lg-letter { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }

.lg-swing, .lg-body, .lg-tassel { transform-box: fill-box; transform-origin: 50% 0%; }
.logo__mark .lg-wire  { animation: lg-wire .52s var(--ease) both; }
.logo__mark .lg-hooks { animation: lg-wire .52s var(--ease) .07s both; }
.lg-l1 .lg-swing  { animation: lg-sway1 5.4s cubic-bezier(.44,0,.56,1) .56s infinite; }
.lg-l2 .lg-swing  { animation: lg-sway2 6.1s cubic-bezier(.44,0,.56,1) .71s infinite; }
.lg-l3 .lg-swing  { animation: lg-sway3 5.7s cubic-bezier(.44,0,.56,1) .86s infinite; }
.lg-l1 .lg-tassel { animation: lg-tassel 5.4s cubic-bezier(.44,0,.56,1) .71s infinite; }
.lg-l2 .lg-tassel { animation: lg-tassel 6.1s cubic-bezier(.44,0,.56,1) .86s infinite; }
.lg-l3 .lg-tassel { animation: lg-tassel 5.7s cubic-bezier(.44,0,.56,1) 1.01s infinite; }
.lg-l1 .lg-body   { animation: lg-ignite .79s cubic-bezier(.2,.85,.25,1) .26s both; }
.lg-l2 .lg-body   { animation: lg-ignite .79s cubic-bezier(.2,.85,.25,1) .41s both; }
.lg-l3 .lg-body   { animation: lg-ignite .79s cubic-bezier(.2,.85,.25,1) .56s both; }
.lg-l1 .lg-halo   { animation: lg-glow 1.05s ease-out .37s both, lg-breathe 4.6s ease-in-out 1.5s infinite; }
.lg-l2 .lg-halo   { animation: lg-glow 1.05s ease-out .52s both, lg-breathe 5.2s ease-in-out 1.72s infinite; }
.lg-l3 .lg-halo   { animation: lg-glow 1.05s ease-out .67s both, lg-breathe 4.9s ease-in-out 1.95s infinite; }
.logo__word span  { animation: lg-letter .45s cubic-bezier(.2,.85,.25,1) both; }
.logo__word span:nth-child(1){animation-delay:.79s}  .logo__word span:nth-child(2){animation-delay:.83s}
.logo__word span:nth-child(3){animation-delay:.88s}  .logo__word span:nth-child(4){animation-delay:.92s}
.logo__word span:nth-child(5){animation-delay:.97s}  .logo__word span:nth-child(6){animation-delay:1.01s}
.logo__word span:nth-child(7){animation-delay:1.07s} .logo__word span:nth-child(8){animation-delay:1.12s}
.logo__word span:nth-child(9){animation-delay:1.16s} .logo__word span:nth-child(10){animation-delay:1.21s}
.logo__word span:nth-child(11){animation-delay:1.27s}.logo__word span:nth-child(12){animation-delay:1.31s}
.logo__word span:nth-child(13){animation-delay:1.36s}

/* ═══ TOUCH AND REDUCED MOTION ═════════════════════════════════════════════ */

/* 44px minimum on everything tappable. Utility type with no padding computes
   to 17-33px unaided, and most visitors are on a phone. */
@media (any-pointer: coarse) {
  .cur-dot, .cur-ring { display: none; }
  .hdr-nav a,
  .ftr-links a,
  .hero-try button { padding-block: 14px; }
  .ftr-links { gap: 0 var(--s4); }
  .hero-try { gap: 0 var(--s3); }

  /* The business name is the primary click-out to Google Maps and computed to
     ~16px tall. It is a link, so pad the block rather than resize the type. */
  .plate-name a { display: inline-block; padding-block: 13px; }
  .plate-name { margin-block: -13px 0; }

  .hdr-search button { min-height: 44px; }
  .from-btn { min-height: 44px; }
  .logo { --msg-h: 40px; }
  .skip { padding: 14px 18px; }
}

/* Grain gated on hover, not pointer: a touchscreen laptop keeps the texture. */
@media (hover: none) { .grain { display: none; } }

/* Hover sticks after a tap on touch. A plate left shifted with its numeral lit
   reads as "selected", which is not what happened. */
@media (hover: none) {
  .plate:hover { transform: none; }
  .plate:hover .plate-no { background: color-mix(in oklch, var(--turmeric) 42%, var(--enamel)); }
  .q:hover { color: var(--ink); padding-left: 0; }
  .row:hover { border-left-color: transparent; padding-left: 0; }
  .row:hover .row-lbl { color: var(--slate); }
  .btn:hover { border-color: var(--enamel-edge-ctl); color: var(--slate); }
  .btn--go:hover { background: var(--ember); border-color: var(--ember); color: var(--ink); }
  .panel button.go:hover { background: var(--ember); color: var(--ink); }
  .plate-name a:hover { color: var(--ink); text-decoration: none; }
  .hdr-nav a:hover { color: var(--slate-light); border-bottom-color: transparent; }
  .ftr-links a:hover { color: var(--slate-light); }
  .hero-try button:hover { color: color-mix(in oklch, var(--enamel) 80%, transparent); border-bottom-color: var(--signboard-ctl); }
  .toggle:hover { border-color: var(--enamel-edge-ctl); color: var(--slate); }
  .load-more:hover { background: none; color: var(--ink); }
}

@media (max-width: 620px) {
  .ftr-fine { justify-content: flex-start; }
  .band-meta { gap: var(--s2) var(--s4); }

  /* The header search was measuring 112 x 25 on a phone: too short to tap and
     too narrow to read a typed query back. The nav gives up its space to it,
     since the header is a search bar first and a menu second. */
  .hdr { gap: var(--s2); padding-inline: var(--s3); }
  /* The min-height has to be on the input, not just the wrapper. Padding on the
     wrapper made the form 54px while the actual tap target stayed 25px, and
     tapping the padding focused nothing. */
  .hdr-search { padding: 0 8px 0 10px; }
  .hdr-search input { min-width: 0; min-height: 44px; }
  .hdr-search button { min-height: 44px; }
  body.results-mode .hdr-nav,
  body.past-hero .hdr-nav { display: none; }
  /* Visually hidden, still the input's accessible name. */
  .hdr-search label {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
  .js .r { transform: none; transition: opacity 0.2s linear; }
  .js .r.in { opacity: 1; }
  .logo__mark .lg-halo { opacity: .55; }
  .grain { display: none; }
  .cur-dot, .cur-ring { display: none; }
  body.has-cursor, body.has-cursor a, body.has-cursor button,
  body.has-cursor input, body.has-cursor label { cursor: auto; }
}
