/* ============================================================================
   Ten Suns — ไร้เทียมทาน — 十光
   Demo site for Optimism. Palette and type per the Ten Suns brand brief:
   braised-broth brown, warm paper, one lantern red-orange accent (sampled
   from their own logo), blue shopfront tile as a secondary note.
   ========================================================================== */

/* ---- fonts (self-hosted, variable) ---------------------------------------- */
@font-face {
  /* Source Serif 4. The brand brief names "Fraunces / Source Serif" as the
     display face; Fraunces has become the default premium-serif of every
     AI-generated site going, so this takes the brief's other option. Source
     Serif is sturdier and lower-contrast, which suits a braised-beef house
     better than a fashion-magazine face, and it holds up next to Anuphan. */
  font-family: 'Source Serif';
  src: url('assets/fonts/source-serif-var.woff2') format('woff2-variations');
  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+2000-206F, U+2122, U+2212, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Anuphan';
  src: url('assets/fonts/anuphan-latin-var.woff2') format('woff2-variations');
  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+2000-206F, U+2122, U+2212, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Anuphan';
  src: url('assets/fonts/anuphan-thai-var.woff2') format('woff2-variations');
  font-weight: 100 900; font-style: normal; font-display: swap;
  unicode-range: U+0E01-0E5B, U+200C-200D, U+25CC;
}

/* ---- tokens --------------------------------------------------------------- */
:root {
  /* sampled from the owner's logo file */
  --sun:        #F78F22;
  --ember:      #E94B23;
  /* The logo's lantern red is a graphic colour, not a text colour: white on it
     is 3.8:1 and it is 3.4:1 on paper, both under AA. These two darker steps
     carry the same hue for anything that has to be read. */
  --ember-btn:  #D63F1A;   /* 4.6:1 with white */
  --ember-text: #C93A17;   /* 4.6:1 on paper */

  --ink:        #17110C;
  --ink-2:      #2C221A;
  --broth:      #6B3A1E;
  --broth-deep: #3A1D0E;
  --night:      #120D09;
  --night-2:    #1D150F;

  --paper:      #F6F1E7;
  --paper-2:    #EDE4D3;
  --card:       #FCFAF4;
  --muted:      #736152;
  --muted-dark: #A8927C;
  --hairline:   #DCCFB9;
  --hairline-d: #3A2E24;

  --tile:       #1E4E6B;
  --tile-2:     #327FA6;

  --display: 'Source Serif', Georgia, 'Times New Roman', serif;
  --text: 'Anuphan', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;

  --gut: clamp(20px, 5vw, 64px);
  --maxw: 1240px;
  --rule: 1px solid var(--hairline);

  /* Full-bleed elements (the fixed top bar, the film's overlays) sit on the
     viewport edge, while everything in `.wrap` sits on a centred 1240px
     container. Past 1240px those are two different left edges, and on a wide
     display the logo ends up ~340px left of the headline it is meant to line up
     with. `--edge` resolves to the gutter on narrow screens and to the
     container's own edge once the container stops growing. Percentages resolve
     against the element's own box, so this must be used on a full-width one. */
  --edge: max(var(--gut), calc((100% - var(--maxw)) / 2 + var(--gut)));

  /* 4pt spacing scale. Named by role, not by pixel value, so a change of mind
     about "loose" does not mean renaming every use site. */
  --space-2xs: 4px;
  --space-xs:  8px;
  --space-sm:  12px;
  --space-md:  16px;
  --space-lg:  24px;
  --space-xl:  32px;
  --space-2xl: 48px;
  --space-3xl: 64px;
  --space-4xl: 96px;
}

/* ---- reset ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--text);
  font-size: clamp(1rem, .45vw + .92rem, 1.115rem);
  line-height: 1.68;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img, video { max-width: 100%; display: block; }
a { color: inherit; }
h1, h2, h3, h4 { margin: 0; font-weight: 600; line-height: 1.05; letter-spacing: -.02em; }
p { margin: 0; }
button { font: inherit; color: inherit; }

/* Thai sits taller than Latin; give it room without loosening English. */
:lang(th) { line-height: 1.9; letter-spacing: 0; }

/* ---- bilingual switching --------------------------------------------------
   Both languages ship in the HTML so the page stays crawlable in both.
   The root data-lang attribute decides which one is visible.            */
html[data-lang="th"] .en { display: none !important; }
html[data-lang="en"] .th { display: none !important; }

/* ---- shared -------------------------------------------------------------- */
.wrap { max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gut); }
.section { padding-block: clamp(72px, 10vw, 148px); }
.dark { background: var(--night); color: var(--paper); }
.dark h2, .dark h3 { color: var(--paper); }
.deep { background: var(--broth-deep); color: var(--paper); }

.display { font-family: var(--display); font-weight: 600; letter-spacing: -.03em; }
h2.display { font-size: clamp(2.05rem, 4.4vw, 3.5rem); line-height: 1.02; }
h2.display:lang(th) { font-family: var(--text); font-weight: 600; letter-spacing: -.01em; line-height: 1.35; }
.lede { font-size: clamp(1.06rem, 1.1vw, 1.28rem); color: var(--muted); max-width: 62ch; }
.dark .lede { color: var(--muted-dark); }
.rule { height: 1px; background: var(--hairline); border: 0; margin: 0; }
.dark .rule { background: var(--hairline-d); }

/* The logo's ten rings, reused as a section divider. */
.rings { display: block; width: 46px; height: 46px; opacity: .9; }

/* Buttons: squared and confident, never pills. */
.btn {
  display: inline-flex; align-items: center; gap: .55em;
  padding: .82em 1.35em; border-radius: 2px; border: 1px solid transparent;
  font-weight: 500; font-size: .97rem; text-decoration: none; cursor: pointer;
  transition: background .18s ease, color .18s ease, border-color .18s ease,
              transform .12s cubic-bezier(.2,.8,.3,1);
}
.btn-primary { background: var(--ember-btn); color: #fff; }
.btn-primary:hover { background: #B33111; transform: translateY(-1px); }
.btn-ghost { border-color: currentColor; background: transparent; }
.btn-ghost:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.dark .btn-ghost:hover { background: var(--paper); color: var(--ink); border-color: var(--paper); }

/* Keyboard focus. A visible ring on every interactive surface, in the accent
   so it reads as part of the design rather than a browser default. */
:focus-visible {
  outline: 2px solid var(--ember-btn); outline-offset: 3px; border-radius: 2px;
}
.dark :focus-visible, .hero :focus-visible, .film-stage :focus-visible {
  outline-color: var(--sun);
}

/* Tactile press. Buttons should feel like they take the weight. */
.btn:active { transform: translateY(1px) scale(.995); }
.app-btn:active, .langtoggle button:active, .mobilebar a:active { transform: translateY(1px); }

/* Unconfirmed content stays visibly provisional until the owner answers. */
.ph {
  color: var(--muted); background: rgba(233,75,35,.07);
  border-bottom: 1px dashed var(--ember-text); padding: 0 .25em; font-style: italic;
}
.dark .ph { color: var(--muted-dark); background: rgba(233,75,35,.14); }

/* ---- top bar -------------------------------------------------------------- */
.topbar {
  position: fixed; inset: 0 0 auto 0; z-index: 70;
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 14px var(--edge);
  transition: background .3s ease, box-shadow .3s ease, padding .3s ease;
}
.topbar.solid {
  background: rgba(18,13,9,.92);
  -webkit-backdrop-filter: saturate(140%) blur(10px);
  backdrop-filter: saturate(140%) blur(10px);
  box-shadow: 0 1px 0 rgba(255,255,255,.08);
}
.brand { display: flex; align-items: center; gap: 11px; text-decoration: none; color: var(--paper); }
.brand img { width: 38px; height: 38px; border-radius: 50%; }
.brand-txt { display: flex; flex-direction: column; line-height: 1.1; }
.brand-name { font-family: var(--display); font-size: 1.02rem; font-weight: 600; letter-spacing: .01em; }
.brand-sub { font-size: .72rem; color: var(--muted-dark); }
.topnav { display: flex; align-items: center; gap: clamp(14px, 1.8vw, 26px); }
.navlinks { display: flex; align-items: center; gap: clamp(14px, 1.8vw, 26px); }
.topnav a { color: var(--paper); text-decoration: none; font-size: .93rem; opacity: .84; }
.topnav a:hover { opacity: 1; }

.langtoggle { display: inline-flex; border: 1px solid rgba(246,241,231,.32); border-radius: 2px; overflow: hidden; }
.langtoggle button {
  background: transparent; border: 0; color: var(--paper); opacity: .62;
  padding: .34em .7em; font-size: .82rem; cursor: pointer; letter-spacing: .02em;
  min-width: 3.1em; text-align: center;
}
.langtoggle button[aria-pressed="true"] { background: var(--paper); color: var(--ink); opacity: 1; font-weight: 500; }

/* ---- hero ----------------------------------------------------------------- */
/* Content sits just above the optical centre, not pinned to the bottom. The
   extra bottom padding is what lifts it: with align-items:center the padding
   is part of what gets centred. */
.hero { position: relative; min-height: 100svh; display: flex; align-items: center; background: var(--night); overflow: hidden; }
.hero-media { position: absolute; inset: 0; }
.hero-media img { width: 100%; height: 100%; object-fit: cover; opacity: .95; }
/* Asymmetric: heavy on the left so the headline has a clean field, light on
   the right so the food actually reads instead of going to brown mud. */
.hero-scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(96deg, rgba(15,10,7,.60) 0%, rgba(15,10,7,.53) 26%, rgba(15,10,7,.30) 56%, rgba(15,10,7,.16) 78%, rgba(15,10,7,.26) 100%),
    linear-gradient(180deg, rgba(15,10,7,.36) 0%, rgba(15,10,7,.03) 24%, rgba(15,10,7,.05) 52%, rgba(15,10,7,.60) 100%),
    radial-gradient(88% 66% at 84% 32%, rgba(233,75,35,.15), transparent 66%);
}
@media (max-width: 820px) {
  /* Portrait has no room for a side-weighted scrim: go back to vertical. */
  .hero-scrim {
    background:
      linear-gradient(180deg, rgba(15,10,7,.48) 0%, rgba(15,10,7,.16) 30%, rgba(15,10,7,.38) 62%, rgba(15,10,7,.64) 100%),
      radial-gradient(110% 60% at 70% 26%, rgba(233,75,35,.16), transparent 66%);
  }
}
.hero-inner { position: relative; z-index: 2; width: 100%; padding-block: clamp(72px, 9vh, 96px) clamp(104px, 14vh, 168px); }
.hero h1 {
  font-family: var(--display); font-weight: 600; color: var(--paper);
  font-size: clamp(2.6rem, 6.6vw, 5.6rem); line-height: .99; letter-spacing: -.035em;
  max-width: 17ch; text-wrap: balance;
  /* A soft dark halo on the type, not on the whole image. It keeps the headline
     legible where it crosses a bright patch of the photo (the white plate),
     which lets the scrim stay light so the food still reads. */
  text-shadow: 0 1px 2px rgba(10,7,4,.4), 0 2px 34px rgba(10,7,4,.55);
}
.hero h1:lang(th) { font-family: var(--text); font-weight: 600; font-size: clamp(2rem, 5vw, 4.1rem); line-height: .98; letter-spacing: -.018em; }
.hero h1 .th { line-height: 1.2; }
.hero p.sub { margin-top: clamp(18px, 2.4vw, 28px); max-width: 56ch; color: #E6DCCC; font-size: clamp(1.02rem, 1.05vw, 1.22rem); line-height: 1.45; text-shadow: 0 1px 20px rgba(10,7,4,.55); }
.hero h1:lang(th) + .sub { margin-top: clamp(14px, 1.7vw, 20px); }
.hero p.sub:lang(th) { line-height: 1.3; }
.hero-cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: clamp(24px, 3vw, 36px); }

/* Badge row: hairline-separated facts, not pills. */
.badges { display: flex; flex-wrap: wrap; align-items: center; gap: 0; margin-top: clamp(26px, 3.2vw, 38px); border-top: 1px solid rgba(246,241,231,.2); padding-top: 16px; }
.badges > * { display: flex; align-items: center; gap: .5em; padding-right: clamp(16px, 2.4vw, 30px); margin-right: clamp(16px, 2.4vw, 30px); border-right: 1px solid rgba(246,241,231,.2); font-size: .9rem; color: #D9CDBB; }
.badges > *:last-child { border-right: 0; margin-right: 0; padding-right: 0; }
.badges b { color: var(--paper); font-weight: 500; }
/* The official Bib Gourmand medallion (the owner's bib.png). The image is
   already a disc with transparent corners, so it needs no rounding: rounding
   would clip the Bibendum, which is drawn right to the disc edge. */
.bib { width: 22px; height: 22px; flex: none; }
.stars { color: var(--sun); letter-spacing: .06em; }

/* Sits right, clear of the badge row on the left. */
.scrollcue { position: absolute; right: var(--gut); bottom: 24px; z-index: 3; font-size: .74rem; letter-spacing: .1em; color: rgba(246,241,231,.55); display: flex; align-items: center; gap: 9px; }
@media (max-width: 520px) { .scrollcue { display: none; } }
.scrollcue i { display: block; width: 1px; height: 26px; background: linear-gradient(var(--sun), transparent); animation: cue 2.1s ease-in-out infinite; }
@keyframes cue { 0%,100% { opacity: .25; transform: scaleY(.5); transform-origin: top; } 50% { opacity: 1; transform: scaleY(1); } }

/* ---- the story film ------------------------------------------------------- */
/* A tall section with a sticky stage. Scroll position inside the section
   scrubs a chain of clips; copy beats fade through over the top.          */
#story { position: relative; background: #0B0806; }
.film-stage {
  position: sticky; top: 0; height: 100svh; overflow: hidden;
  background: #0B0806;
}
.film-layer { position: absolute; inset: 0; }
.film-layer img, .film-layer video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; opacity: 0;
  /* No opacity transition. The engine cuts one clip to the next on a matched
     frame; a CSS fade here would animate every cut into a 0.18s cross-dissolve,
     ghosting two frames together, which is what read as flicker while scrubbing.
     translateZ promotes each layer to its own GPU surface so the swap and the
     per-frame seeks composite cleanly. */
  transform: translateZ(0);
  backface-visibility: hidden;
}
/* The clip layers are z-indexed from 10 upwards so they stack in flight order,
   which means everything drawn over them needs an explicit index too. Without
   one these are positioned elements at z-index auto and paint underneath. */
.film-vig {
  position: absolute; inset: 0; pointer-events: none; z-index: 40;
  background:
    linear-gradient(180deg, rgba(11,8,6,.72) 0%, transparent 26%, transparent 52%, rgba(11,8,6,.88) 100%),
    radial-gradient(130% 96% at 50% 46%, transparent 42%, rgba(11,8,6,.6) 100%);
}
.film-copy { position: absolute; inset: 0; z-index: 50; display: flex; align-items: flex-end; pointer-events: none; }

/* One line, held across the whole flight. It sits centred with its own soft
   pool of shadow, because it has to stay readable over nine very different
   frames, from a near-black shuttered shop to a lantern-lit street. */
.film-title {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 18px; text-align: center;
  padding-inline: var(--gut);
  opacity: 0; transform: translateY(10px) scale(.99);
  transition: opacity .9s ease, transform .9s ease;
}
.film-title::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: radial-gradient(58% 42% at 50% 50%, rgba(11,8,6,.62), transparent 72%);
}
.film-title.on { opacity: 1; transform: none; }
.film-title .mark {
  font-family: var(--display); font-size: clamp(1.5rem, 2.4vw, 2.1rem);
  color: var(--sun); letter-spacing: .12em; line-height: 1;
  border: 1.5px solid rgba(247,143,34,.5); border-radius: 2px; padding: .34em .42em .3em;
}
.film-title p {
  font-family: var(--display); font-weight: 600; letter-spacing: -.02em;
  font-size: clamp(1.5rem, 3.4vw, 2.9rem); line-height: 1.12; color: var(--paper);
  max-width: 26ch; text-wrap: balance;
  text-shadow: 0 2px 30px rgba(0,0,0,.5);
}
.film-title p:lang(th) {
  font-family: var(--text); font-size: clamp(1.15rem, 2.6vw, 2.15rem);
  line-height: 1.5; max-width: 26ch;
}
/* ---- the story timeline, under the film ----------------------------------- */
.timeline { margin-top: clamp(32px, 4vw, 52px); border-top: var(--rule); }
.beat {
  display: grid; grid-template-columns: 11rem 1fr; gap: clamp(16px, 3vw, 44px);
  padding: clamp(22px, 3vw, 34px) 0; border-bottom: var(--rule); align-items: start;
}
.beat-when {
  font-family: var(--display); font-weight: 600; font-size: clamp(1rem, 1.3vw, 1.2rem);
  color: var(--ember-text); letter-spacing: -.01em; padding-top: .15em;
}
.beat-when:lang(th) { font-family: var(--text); }
.beat-body h3 {
  font-family: var(--display); font-size: clamp(1.25rem, 2.1vw, 1.75rem);
  line-height: 1.14; letter-spacing: -.025em;
}
.beat-body h3:lang(th) { font-family: var(--text); font-size: clamp(1.1rem, 1.8vw, 1.45rem); line-height: 1.45; }
.beat-body p { margin-top: .55em; color: var(--muted); max-width: 60ch; }
@media (max-width: 720px) {
  .beat { grid-template-columns: 1fr; gap: 6px; }
}

.film-progress { position: absolute; z-index: 50; left: var(--edge); right: var(--edge); bottom: var(--space-lg); height: 1px; background: rgba(246,241,231,.18); }
.film-progress i { display: block; height: 100%; width: 0; background: var(--sun); transition: width .1s linear; }
.film-note {
  position: absolute; right: var(--edge); bottom: calc(var(--space-lg) + 18px); z-index: 50;
  font-size: .68rem; letter-spacing: .07em; color: rgba(246,241,231,.42); max-width: 22ch; text-align: right;
}

/* ---- michelin band -------------------------------------------------------- */
.years { display: grid; grid-template-columns: repeat(8, 1fr); border-top: 1px solid var(--hairline-d); border-bottom: 1px solid var(--hairline-d); margin-block: clamp(30px, 4vw, 40px); text-decoration: none; color: var(--paper); transition: border-color .2s ease; }
.years:hover { border-color: var(--muted-dark); }
.yr { display: flex; flex-direction: column; align-items: center; gap: .5em; padding: clamp(15px, 2vw, 22px) 0; border-right: 1px solid var(--hairline-d); font-family: var(--display); font-size: clamp(.92rem, 1.5vw, 1.4rem); font-weight: 600; }
.yr:last-child { border-right: 0; }
/* Complete medallion, no rounding (see .bib). Sized a little larger so the
   Bibendum reads at a glance. */
.bibmark { width: clamp(24px, 2.3vw, 30px); height: auto; aspect-ratio: 1; display: block; transition: transform .2s ease; }
.years:hover .bibmark { transform: translateY(-1px) scale(1.06); }
/* The full official medallion (with its MICHELIN BIB GOURMAND lettering), once,
   above the section heading as the authoritative award badge. */
.bib-badge { display: block; width: clamp(58px, 6.5vw, 74px); height: auto; margin-bottom: clamp(16px, 2vw, 24px); }
.yr b { font-family: var(--text); font-size: .62rem; letter-spacing: .1em; color: var(--sun); font-weight: 500; }

.mich-link { margin-top: clamp(4px, 1vw, 10px); font-size: .9rem; }
.mich-link a { display: inline-flex; align-items: center; gap: .45em; color: var(--sun); text-decoration: none; border-bottom: 1px solid rgba(247,143,34,.35); padding-bottom: 1px; transition: border-color .18s ease; }
.mich-link a:hover { border-color: var(--sun); }
blockquote.inspectors { font-family: var(--display); font-size: clamp(1.2rem, 2.2vw, 1.85rem); line-height: 1.38; color: var(--paper); max-width: 34ch; margin: 0; letter-spacing: -.02em; }
blockquote.inspectors:lang(th) { font-family: var(--text); line-height: 1.6; }
.attrib { margin-top: 1em; font-size: .84rem; color: var(--muted-dark); }
.mich-grid { display: grid; grid-template-columns: 1.05fr .95fr; gap: clamp(30px, 5vw, 72px); align-items: start; }

/* ---- the bowls ------------------------------------------------------------ */
/* Deliberately not three equal cards. The bowl a first-timer should order is
   the whole point of this section, so it gets a tall cell of its own and the
   other two sit beside it in wide ones. Hierarchy, not a row of clones. */
.bowls-feature {
  display: grid; grid-template-columns: 1.22fr 1fr;
  gap: clamp(14px, 2vw, 26px); margin-top: clamp(32px, 4vw, 52px);
}
.dish:first-child { grid-row: span 2; }
.dish:first-child img { aspect-ratio: 4/5; }
.dish:not(:first-child) img { aspect-ratio: 16/11; }
.dish figure { margin: 0; }
/* Square, and biased low. These are the shop's own phone photos: the bowl rim
   and background sit blurred across the top third, and the food is below
   centre. A portrait crop keeps the blur and loses the beef. */
/* height:auto is required, not cosmetic: these images carry width/height
   attributes for layout stability, and a specified height makes the browser
   ignore aspect-ratio entirely. */
.dish img { width: 100%; height: auto; aspect-ratio: 1/1; object-fit: cover; object-position: 50% 66%; border-radius: 2px; }
.dish figcaption { padding-top: 14px; }
.dish .th-name { font-weight: 500; font-size: 1.06rem; }
.dish .en-name { color: var(--muted); font-size: .95rem; }
.dish .price { font-family: var(--display); font-weight: 600; font-size: 1.02rem; margin-top: .35em; }
.tag { display: inline-block; font-size: .7rem; letter-spacing: .08em; color: var(--ember-text); border: 1px solid var(--ember-text); border-radius: 2px; padding: .18em .5em; margin-bottom: .5em; }

/* The rest of the menu: an editorial price list on hairlines, not cards. */
.menu-list { margin-top: clamp(40px, 5vw, 64px); border-top: var(--rule); }
.menu-row { display: grid; grid-template-columns: 1fr auto; gap: 20px; align-items: baseline; padding: clamp(15px, 1.8vw, 22px) 0; border-bottom: var(--rule); }
.menu-row .names { display: flex; flex-wrap: wrap; align-items: baseline; gap: .2em .7em; }
.menu-row .th-name { font-weight: 500; }
.menu-row .en-name { color: var(--muted); font-size: .95rem; }
.menu-row .price { font-family: var(--display); font-weight: 600; white-space: nowrap; }
.menu-foot { display: flex; flex-wrap: wrap; gap: 12px 28px; justify-content: space-between; margin-top: 20px; font-size: .87rem; color: var(--muted); }

/* A full-width rule above and the shop's own sun mark as the marker. The
   accent-stripe-down-the-left-edge version of this is the single most
   overused callout treatment there is. */
.soldout {
  margin-top: clamp(34px, 4vw, 52px); padding-top: var(--space-lg);
  border-top: 2px solid var(--ink); display: grid;
  grid-template-columns: auto 1fr; gap: var(--space-md) var(--space-lg); align-items: start;
}
.soldout::before {
  content: ""; width: 30px; height: 30px; border-radius: 50%; margin-top: .15em;
  background: radial-gradient(circle at 32% 32%, var(--sun), var(--ember) 72%);
}
.soldout > * { grid-column: 2; }
.soldout strong { font-weight: 600; }

/* ---- gallery strip -------------------------------------------------------- */
/* Full-bleed and edge to edge: a breath of the real room between the menu and
   the reviews. Scrolls sideways on a phone rather than stacking six tall images. */
.gallery { background: var(--night); }
.strip { display: grid; grid-template-columns: repeat(6, 1fr); gap: 2px; }
.strip img {
  width: 100%; height: auto; aspect-ratio: 3/4; object-fit: cover; object-position: 50% 58%;
  filter: saturate(.96);
}
@media (max-width: 900px) {
  .strip {
    grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: 62%;
    overflow-x: auto; scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch; scrollbar-width: none;
  }
  .strip::-webkit-scrollbar { display: none; }
  .strip img { scroll-snap-align: center; aspect-ratio: 4/5; }
}

/* ---- shopfront ------------------------------------------------------------ */
.frontage { margin: 0 0 clamp(18px, 2.4vw, 26px); }
/* Crop to the top of the frontage. The white TEN SUNS lettering on blue tile
   and the two lanterns are what someone is actually scanning the street for,
   and keeping high also keeps staff and customers out of the frame. */
.frontage img {
  width: 100%; height: auto; aspect-ratio: 5/4; object-fit: cover; object-position: 50% 8%;
  border-radius: 2px;
}
.frontage figcaption { margin-top: 10px; font-size: .88rem; color: var(--muted); }

/* ---- reviews -------------------------------------------------------------- */
/* Two facts, bottom-aligned on a shared rule, rather than three items
   baseline-aligned across wildly different heights. */
.rating-lockup { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-md) clamp(24px, 4vw, 52px); }
.rating-lockup > * { display: flex; flex-direction: column; justify-content: flex-end; }
.rating-lockup .big { font-family: var(--display); font-size: clamp(2.6rem, 6vw, 4.4rem); font-weight: 600; line-height: .92; letter-spacing: -.04em; }
.quotes { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0; margin-top: clamp(34px, 4vw, 54px); border-top: var(--rule); }
.quote { padding: clamp(24px, 3vw, 38px) clamp(24px, 3vw, 38px) clamp(24px, 3vw, 38px) 0; border-bottom: var(--rule); }
.quote:nth-child(even) { padding-left: clamp(24px, 3vw, 38px); padding-right: 0; border-left: var(--rule); }
.quote p { font-family: var(--display); font-size: clamp(1.1rem, 1.7vw, 1.42rem); line-height: 1.42; letter-spacing: -.015em; }
.quote p:lang(th) { font-family: var(--text); line-height: 1.68; }
.quote cite { display: block; margin-top: .9em; font-style: normal; font-size: .86rem; color: var(--muted); }

/* ---- visit ---------------------------------------------------------------- */
.visit-grid { display: grid; grid-template-columns: 1fr 1.08fr; gap: clamp(30px, 5vw, 68px); align-items: start; }
.map { width: 100%; aspect-ratio: 4/3; border: 0; border-radius: 2px; background: var(--paper-2); filter: saturate(.86) contrast(1.02); }
.facts { border-top: var(--rule); }
.fact { display: grid; grid-template-columns: 11rem 1fr; gap: 18px; padding: clamp(14px, 1.7vw, 19px) 0; border-bottom: var(--rule); align-items: start; }
.fact dt { font-size: .84rem; color: var(--muted); letter-spacing: .02em; }
.fact dd { margin: 0; }
.fact a { text-decoration: none; border-bottom: 1px solid var(--hairline); }
.fact a:hover { border-color: var(--ember-text); color: var(--ember-text); }

/* ---- delivery ------------------------------------------------------------- */
.delivery-row { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 26px; }
.app-btn {
  display: inline-flex; align-items: center; gap: .55em; padding: .42em 1.05em;
  border: 1px solid var(--hairline-d); border-radius: 2px; text-decoration: none;
  font-size: .95rem; color: var(--paper); transition: border-color .18s, background .18s;
}
.app-btn:hover { border-color: var(--sun); background: rgba(247,143,34,.09); }
.app-logo { height: 18px; width: auto; display: block; }
.platform-line .app-logo { height: 26px; width: auto; }
.platform-grab { background: transparent; border-color: var(--hairline-d); }
.platform-grab:hover { background: rgba(247,143,34,.09); border-color: var(--sun); }
.platform-grab .app-logo { height: 30px; width: 84px; max-width: none; transform: scale(1.22); transform-origin: center; }

/* ---- events / catering ---------------------------------------------------- */
#events { position: relative; overflow: hidden; }
.events-bg { position: absolute; inset: 0; }
.events-bg img { width: 100%; height: 100%; object-fit: cover; opacity: .2; }
.events-bg::after { content: ''; position: absolute; inset: 0; background: linear-gradient(105deg, rgba(58,29,14,.97) 0%, rgba(58,29,14,.9) 46%, rgba(58,29,14,.7) 100%); }
.events-grid { position: relative; z-index: 2; display: grid; grid-template-columns: .92fr 1.08fr; gap: clamp(34px, 5vw, 74px); align-items: start; }
.events-trust { display: flex; flex-wrap: wrap; gap: 10px 22px; margin-top: 26px; font-size: .88rem; color: var(--muted-dark); }
.events-alt { margin-top: 28px; padding-top: 22px; border-top: 1px solid var(--hairline-d); font-size: .93rem; color: var(--muted-dark); }
.events-alt a { color: var(--sun); text-decoration: none; border-bottom: 1px solid rgba(247,143,34,.4); }

.form-card { background: var(--card); color: var(--ink); padding: clamp(24px, 3.4vw, 40px); border-radius: 2px; }
.form-card h3 { font-family: var(--display); font-size: clamp(1.3rem, 2vw, 1.7rem); }
.field { margin-top: 18px; }
.field label { display: block; font-size: .85rem; color: var(--muted); margin-bottom: 6px; }
.field label .req { color: var(--ember-text); }
.field input, .field select, .field textarea {
  width: 100%; padding: .72em .82em; font: inherit; font-size: .98rem;
  border: 1px solid var(--hairline); border-radius: 2px; background: #fff; color: var(--ink);
  transition: border-color .16s, box-shadow .16s;
}
.field textarea { min-height: 96px; resize: vertical; }
/* Browser default placeholder grey drops under AA on this warm card. */
.field ::placeholder { color: #82705F; opacity: 1; }  /* 4.74:1 on white */
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--ember); box-shadow: 0 0 0 3px rgba(233,75,35,.13);
}
.field-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.radio-row { display: flex; gap: 20px; margin-top: 8px; }
.radio-row label { display: inline-flex; align-items: center; gap: .45em; color: var(--ink); font-size: .96rem; margin: 0; }
.radio-row input { width: auto; }
.form-card .btn { margin-top: 22px; width: 100%; justify-content: center; }
.form-note { margin-top: 14px; font-size: .8rem; color: var(--muted); line-height: 1.5; }
.form-status { margin-top: 16px; padding: 14px 16px; border-radius: 2px; font-size: .94rem; display: none; }
.form-status.ok { display: block; background: rgba(6,199,85,.12); box-shadow: inset 0 0 0 1px rgba(6,199,85,.35); }
.form-status.err { display: block; background: rgba(233,75,35,.1); box-shadow: inset 0 0 0 1px rgba(201,58,23,.4); }

/* ---- faq ------------------------------------------------------------------ */
.faq { border-top: var(--rule); margin-top: clamp(28px, 3.4vw, 44px); }
.faq details { border-bottom: var(--rule); }
.faq summary {
  list-style: none; cursor: pointer; padding: clamp(17px, 2vw, 24px) 44px clamp(17px, 2vw, 24px) 0;
  position: relative; font-size: clamp(1.02rem, 1.3vw, 1.16rem); font-weight: 500;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ''; position: absolute; right: 8px; top: 50%; width: 11px; height: 11px;
  border-right: 1.5px solid var(--muted); border-bottom: 1.5px solid var(--muted);
  transform: translateY(-70%) rotate(45deg); transition: transform .22s ease;
}
.faq details[open] summary::after { transform: translateY(-30%) rotate(-135deg); }
.faq .ans { padding: 0 clamp(30px, 8vw, 90px) clamp(20px, 2.4vw, 28px) 0; color: var(--muted); }

/* ---- footer --------------------------------------------------------------- */
.footer { background: #0A0705; color: var(--paper); padding-block: clamp(56px, 7vw, 88px) 0; }
.foot-grid { display: grid; grid-template-columns: 1.2fr 1fr 1fr; gap: clamp(28px, 4vw, 56px); }
.footer h4 { font-size: .8rem; letter-spacing: .06em; color: var(--sun); font-weight: 500; margin-bottom: 14px; }
.footer a { color: #D6CABA; text-decoration: none; }
.footer a:hover { color: var(--paper); }
.footer ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; font-size: .95rem; }
.seal {
  display: inline-flex; align-items: center; justify-content: center;
  width: 62px; height: 62px; border: 1.5px solid var(--ember); border-radius: 2px;
  font-family: var(--display); font-size: 1.5rem; color: var(--ember); letter-spacing: .04em;
}
.foot-bottom { margin-top: clamp(40px, 5vw, 64px); padding-block: 22px; border-top: 1px solid var(--hairline-d); display: flex; flex-wrap: wrap; gap: 12px 24px; justify-content: space-between; font-size: .84rem; color: var(--muted-dark); }
.foot-bottom a { color: var(--muted-dark); border-bottom: 1px solid transparent; }
.foot-bottom a:hover { color: var(--sun); border-color: var(--sun); }

/* ---- sticky mobile action bar --------------------------------------------- */
.mobilebar { display: none; }

/* ---- responsive ----------------------------------------------------------- */
@media (max-width: 1000px) {
  .mich-grid, .visit-grid, .events-grid { grid-template-columns: 1fr; }
  .bowls-feature { grid-template-columns: 1fr 1fr; }
  .dish:first-child { grid-row: auto; }
  .dish:first-child img, .dish:not(:first-child) img { aspect-ratio: 1/1; }
  .foot-grid { grid-template-columns: 1fr 1fr; }
  .years { grid-template-columns: repeat(4, 1fr); }
  .yr:nth-child(4n) { border-right: 0; }
  .yr:nth-child(-n+4) { border-bottom: 1px solid var(--hairline-d); }
}
@media (max-width: 720px) {
  .topnav .navlinks { display: none; }
  .quotes { grid-template-columns: 1fr; }
  .quote, .quote:nth-child(even) { padding-inline: 0; border-left: 0; }
  .fact { grid-template-columns: 1fr; gap: 4px; }
  .field-2 { grid-template-columns: 1fr; }
  .foot-grid { grid-template-columns: 1fr; }
  .film-note { display: none; }
  body { padding-bottom: 62px; }
  /* The hero fills the viewport, so its badge row would sit under the sticky
     action bar. Give it the bar's height back. */
  .hero-inner { padding-bottom: 84px; }

  .mobilebar {
    display: grid; grid-template-columns: repeat(4, 1fr);
    position: fixed; inset: auto 0 0 0; z-index: 80;
    background: rgba(18,13,9,.96);
    -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
    border-top: 1px solid rgba(246,241,231,.16);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .mobilebar a {
    display: flex; flex-direction: column; align-items: center; gap: 3px;
    padding: 9px 4px 10px; text-decoration: none; color: #D6CABA; font-size: .68rem;
    border-right: 1px solid rgba(246,241,231,.12);
  }
  .mobilebar a:last-child { border-right: 0; }
  .mobilebar a.accent { color: var(--sun); }
  .mobilebar svg { width: 19px; height: 19px; }
}
@media (max-width: 520px) {
  .bowls-feature { grid-template-columns: 1fr; }
  .dish img, .dish:first-child img, .dish:not(:first-child) img { aspect-ratio: 16/10; }
  .badges > * { border-right: 0; padding-right: 0; margin-right: 0; width: 100%; padding-block: 5px; }
}

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