/* Markus ir Ko — site.css
   The whole design layer. base.css is mechanism only.
   Tokens verbatim from design-direction.md §3. Every colour is declared once, here. */

:root {
  /* ---- colour: declared exactly once, semantic names only ---- */
  --color-surface:        #F9F8F3;
  --color-surface-sunk:   #F2F0E9;
  --color-ink:            #161511;
  --color-ink-muted:      #5A5248;
  --color-accent:         #224122;
  --color-accent-soft:    #417B41;
  --color-on-dark:        #F9F8F3;
  --color-hairline:       color-mix(in srgb, var(--color-ink) 12%, transparent);
  --color-hairline-accent: color-mix(in srgb, var(--color-accent) 45%, transparent);
  --color-scrim:          color-mix(in srgb, #141210 55%, transparent);
  --color-scrim-soft:     color-mix(in srgb, #141210 28%, transparent);
  --color-scrim-strong:   color-mix(in srgb, #141210 82%, transparent);
  --color-accent-wash:    color-mix(in srgb, var(--color-accent) 8%, var(--color-surface));
  --color-accent-hover:   color-mix(in srgb, var(--color-accent) 82%, var(--color-on-dark));
  --color-focus:          var(--color-accent);
  --color-nav-ink:        #F9F8F3;

  /* ---- type ---- */
  --font-display: "Jost", "Helvetica Neue", Arial, sans-serif;
  --font-body:    "Jost", "Helvetica Neue", Arial, sans-serif;
  --track-nav:    0.18em;
  --track-label:  0.14em;
  --track-mark:   0.30em;
  --track-item:   0.06em;

  /* ---- motion ----
     Built-in CSS easings are too weak to read as intentional. Strong ease-out for
     anything entering or responding; strong ease-in-out for things travelling on
     screen; the iOS sheet curve for the full-screen drawer. */
  --ease-out:    cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);
  --dur-press:   140ms;
  --dur-hover:   160ms;
  --dur-ui:      220ms;
  --dur-reveal:  520ms;
  /* The split intro. 700ms measured off the Selma capture (panel travel, 15fps);
     the reverse is faster — the system is responding, not presenting. */
  --dur-split-in:  700ms;
  --dur-split-out: 450ms;

  /* ---- space: 8px base ---- */
  --s1: 8px;  --s2: 16px; --s3: 24px; --s5: 40px;
  --s8: 64px; --s12: 96px; --s16: 128px;

  /* ---- layout ----
     The gutter is the ONLY inset. A percentage gutter on a centred fixed-width
     shell compounds: max-width:1240 + margin-inline:auto + padding-inline:12.5%
     put the content edge at (1440-1240)/2 + 155 = 17.7% of a 1440 viewport and
     narrowed the column to 64.6%, where Selma's is 12.2% / 75.2%. Cap the
     CONTENT (--content-max) instead of the container, so the error cannot scale
     with viewport width. See distinctiveness.md "Rendered geometry". */
  --measure: 68ch;
  --content-max: 1400px;
  --gutter: 12.2%;
}

/* ---------- base ---------- */

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

html { background: var(--color-surface); }

body {
  margin: 0;
  background: var(--color-surface);
  color: var(--color-ink);
  font: 400 16px/1.65 var(--font-body);
  -webkit-font-smoothing: antialiased;
}

img { display: block; max-width: 100%; }

a { color: inherit; text-decoration: none; }

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

/* The single container. Gutter until the content would exceed --content-max,
   then the inset grows instead of the content. No centred shell, no compounding. */
.masthead__row,
.hero__inner,
.section__inner,
.pagehead__inner,
.site-footer__inner {
  width: 100%;
  padding-inline: max(var(--gutter), calc((100% - var(--content-max)) / 2));
}

.u-visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
  background: var(--color-surface);
  color: var(--color-ink);
}

/* ---------- type roles ---------- */

.section-label {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(1.5rem, 2.4vw, 2rem);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  line-height: 1.15;
}

.section-sub {
  margin: var(--s2) 0 0;
  font-size: 0.9375rem;
  color: var(--color-accent);
}

.prose {
  max-width: var(--measure);
  margin: 0;
  color: var(--color-ink-muted);
}

.prose + .prose { margin-top: var(--s2); }

.lede { color: var(--color-ink); font-size: 1.0625rem; }

/* The line that used to sit in the hero. Selma's hero (f-01) carries the wordmark
   alone; this is where the page states what the restaurant is instead. */
.section-intro {
  max-width: 46ch;
  margin: 0 0 var(--s12);
  color: var(--color-ink);
  font-size: 1.0625rem;
}

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

.masthead {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 40;
  padding-block: var(--s3);
  /* Paint-only transition. `padding` is animatable but must not be animated here:
     the runtime re-measures --lv-header-h on every frame via ResizeObserver, and
     base.css feeds that into scroll-padding-top — so an anchor jump landing mid
     transition would chase a moving offset. The 8px compaction switches in one
     step at the 40px threshold; the eye reads the background fade, not the step. */
  transition: background-color var(--dur-ui) var(--ease-out), box-shadow var(--dur-ui) var(--ease-out);
}

.masthead__row {
  display: grid;
  grid-template-columns: 1fr 1fr auto 1fr 1fr;
  align-items: center;
  gap: var(--s2);
}

.masthead__link {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 0.8125rem;
  letter-spacing: var(--track-nav);
  text-transform: uppercase;
  color: var(--color-nav-ink);
  justify-self: center;
  padding-block: var(--s1);
}

.masthead__row > .masthead__link:first-child { justify-self: start; }
.masthead__row > .masthead__link:nth-child(5) { justify-self: end; }

.masthead__link.is-active,
.masthead__link[aria-current="page"] { color: var(--color-accent-soft); }

.masthead__mark {
  justify-self: center;
  display: block;
  width: 46px;
  height: 46px;
}

.masthead__mark img { width: 46px; height: 46px; }

/* Page-level (non-hero) pages sit on cream, so the bar needs ink type. */
.masthead[data-tone="light"] { --color-nav-ink: var(--color-ink); }

.masthead.is-scrolled {
  background: var(--color-surface);
  padding-block: var(--s2);
  box-shadow: 0 1px 0 var(--color-hairline);
  --color-nav-ink: var(--color-ink);
}

.masthead__burger,
.masthead__lang,
.drawer__lang { display: none; }

/* ---------- language switch ---------- */

.langbar {
  position: fixed;
  z-index: 40;
  right: var(--s3);
  bottom: var(--s3);
  display: flex;
  gap: var(--s1);
  padding: 6px 10px;
  background: var(--color-surface);
  border: 1px solid var(--color-hairline);
  border-radius: 2px;
}

.langbar button {
  appearance: none;
  border: 0;
  background: none;
  cursor: pointer;
  font-family: var(--font-display);
  font-size: 0.6875rem;
  font-weight: 400;
  letter-spacing: var(--track-nav);
  text-transform: uppercase;
  color: var(--color-ink-muted);
  padding: 2px 4px;
}

.langbar button.is-active { color: var(--color-accent); }

/* ---------- heritage badge (Selma's badge device, true content) ---------- */

.badge {
  position: fixed;
  z-index: 39;
  left: var(--s3);
  bottom: var(--s3);
  font-family: var(--font-display);
  font-size: 0.6875rem;
  font-weight: 400;
  letter-spacing: var(--track-nav);
  text-transform: uppercase;
  line-height: 1.5;
  color: var(--color-accent);
}

.badge[data-tone="on-dark"] { color: var(--color-on-dark); }

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

.hero {
  position: relative;
  min-height: 100svh;
  display: grid;
  align-items: center;
  overflow: hidden;
}

.hero__media { position: absolute; inset: 0; }

/* The <picture> needs a definite height or the img's `height: 100%` has nothing
   to resolve against and silently degrades to `auto` — which also makes
   object-fit/object-position inert, since an auto-height img already matches its
   intrinsic aspect. Measured before this rule: at 390px the img was 260px inside
   a 523px hero, so half the hero was scrim painted over the body background.
   base.css gives `picture { display: block }` and no height, by design. */
.hero__media picture { display: block; height: 100%; }

.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 62% 50%;
}

.hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    100deg,
    var(--color-scrim) 0%,
    var(--color-scrim) 34%,
    var(--color-scrim-soft) 56%,
    transparent 78%
  );
}

.hero__inner { position: relative; }

.hero__wordmark {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 200;
  font-size: clamp(2.5rem, 6.4vw, 5rem);
  line-height: 1.32;
  letter-spacing: var(--track-mark);
  text-transform: uppercase;
  color: var(--color-on-dark);
}

.hero__wordmark span { display: block; }

/* Mobile-only. Selma's hero has no CTA and desktop follows it; the playbook's
   "primary CTA in the first viewport" rule governs phones, where the reference
   (a desktop capture) says nothing. See distinctiveness.md §6. */
.hero__cta {
  display: none;
  margin-top: var(--s5);
  padding: 14px 26px;
  border: 1px solid var(--color-on-dark);
  font-family: var(--font-display);
  font-size: 0.8125rem;
  letter-spacing: var(--track-nav);
  text-transform: uppercase;
  color: var(--color-on-dark);
  transition: background-color var(--dur-hover) ease, color var(--dur-hover) ease, transform var(--dur-press) var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .hero__cta:hover { background: var(--color-on-dark); color: var(--color-ink); }
}

/* Press feedback: the control confirms it heard the tap. */
.hero__cta:active,
.masthead__burger:active,
.langbar button:active,
.drawer__lang button:active { transform: scale(0.97); }

/* ---------- page head (non-home pages) ---------- */

.pagehead {
  padding-top: calc(var(--lv-header-h, 96px) + var(--s16));
  padding-bottom: var(--s8);
}



.pagehead__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 200;
  font-size: clamp(2rem, 5vw, 3.5rem);
  letter-spacing: var(--track-mark);
  text-transform: uppercase;
  line-height: 1.25;
}

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

.section { padding-block: var(--s16); }
.section--sunk { background: var(--color-surface-sunk); }


/* ---------- Selma's asymmetric offset image pair ----------
   Measured on selma-frames/f-05: 301px and 428px wide (0.70 ratio),
   ~226px vertical offset, 183px gutter. Reproduced proportionally. */

/* Selma f-05/f-06, re-read 2026-09-10: portrait frames, and each frame carries its
   own label. MENU sits beside the small frame's top edge; A LA CARTE sits beside
   the large frame's lower half, right-aligned into it. The copy occupies the gap
   column, so no frame has a blank quadrant beside it. The first port kept the
   offset but used landscape frames and one text block below both — the geometry
   survived, the reason for it did not (human feedback: "still looks empty").
   The offset is no longer a margin: row 1 is the head's height, so the large
   frame starts where the head ends. */
.pair {
  display: grid;
  grid-template-columns: 33fr 20fr 47fr;
  column-gap: var(--s3);
  align-items: start;
}

.pair__small { grid-column: 1; grid-row: 1 / 3; }
.pair__head  { grid-column: 2 / 4; grid-row: 1; padding-bottom: var(--s8); }
.pair__large { grid-column: 3; grid-row: 2 / 4; }
.pair__body {
  grid-column: 1 / 3;
  grid-row: 3;
  align-self: end;
  justify-self: end;
  padding: var(--s8) var(--s5) 0 0;
  text-align: right;
}

.pair__head .prose { max-width: 52ch; }
.pair__body .menu-list,
.pair__body .stack { margin-top: 0; }

.pair figure { margin-block-end: 0; margin-inline: 0; position: relative; }

.pair img { width: 100%; height: auto; object-fit: cover; }
.pair__small img { aspect-ratio: 3 / 4; object-position: 38% 50%; }
.pair__large img { aspect-ratio: 4 / 5; }

/* An image pair with no copy (sales.html) has nothing to fill the offset's dead
   corners with, so it settles into two matched frames instead. */
.pair:not(:has(.pair__head)) { grid-template-columns: 1fr 1fr; gap: var(--s5); }
.pair:not(:has(.pair__head)) .pair__small,
.pair:not(:has(.pair__head)) .pair__large { grid-column: auto; grid-row: auto; }
.pair:not(:has(.pair__head)) img { aspect-ratio: 3 / 2; }

/* sales.html stacks three sections inside one container on one ground; doubled
   128px padding between them read as the page having ended. */
.section__inner > .section + .section { padding-top: 0; }

/* single-image section: text right-aligned against the image */

.split {
  display: grid;
  grid-template-columns: 47fr 6fr 47fr;
  align-items: center;
}

.split__media { grid-column: 3; }
.split__media img { width: 100%; height: auto; }

.split__text { grid-column: 1; text-align: right; }
.split__text .prose { margin-left: auto; text-align: right; }

.split--flip .split__media { grid-column: 1; }
.split--flip .split__text { grid-column: 3; text-align: left; }
.split--flip .split__text .prose { margin-left: 0; margin-right: auto; text-align: left; }

/* ---------- hand-drawn ornaments (inline SVG) ---------- */

.ornament {
  position: absolute;
  pointer-events: none;
  overflow: visible;
  color: var(--color-accent);
}

.ornament path {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.25;
  stroke-linecap: round;
}

.ornament--arc {
  left: -18%;
  top: -8%;
  width: 30%;
  height: 130%;
}

.ornament--trail {
  right: 82%;
  top: 12%;
  width: 26%;
  height: 30%;
}

/* ---------- right-aligned lists (Selma's right-aligned People list treatment) ---------- */

/* One row of three, not a column: stacked, the seat counts ran ~420px tall with
   nothing beside them. */
.stack {
  list-style: none;
  margin: var(--s5) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, auto);
  justify-content: end;
  gap: var(--s5);
  text-align: right;
}

.stack li {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(1.125rem, 2vw, 1.5rem);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  padding-top: var(--s2);
  border-top: 1px solid var(--color-hairline-accent);
}

/* Direct child only. `.stack li span` also matched the nested data-lang-content
   spans and made each one a block, which broke "40 SEATS" onto two lines. */
.stack li > span { display: block; white-space: nowrap; }

.stack li small {
  display: block;
  font-size: 0.75rem;
  letter-spacing: var(--track-nav);
  color: var(--color-ink-muted);
  margin-top: 6px;
}

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

.menu-group + .menu-group { margin-top: var(--s12); }

.menu-group__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s3);
  padding-bottom: var(--s2);
  border-bottom: 1px solid var(--color-hairline-accent);
}

.menu-list { list-style: none; margin: var(--s5) 0 0; padding: 0; }

.menu-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: var(--s3);
  padding-block: var(--s2);
}

.menu-row + .menu-row { border-top: 1px solid var(--color-hairline); }

.menu-row__name {
  font-size: 0.8125rem;
  letter-spacing: var(--track-item);
  text-transform: uppercase;
  line-height: 1.6;
}

.menu-row__price {
  font-family: var(--font-display);
  font-size: 0.875rem;
  letter-spacing: var(--track-item);
  white-space: nowrap;
  color: var(--color-accent);
}

.menu-note {
  margin-top: var(--s5);
  font-size: 0.875rem;
  color: var(--color-ink-muted);
  max-width: var(--measure);
}

.menu-cta { margin-top: var(--s8); }

.link-more {
  font-family: var(--font-display);
  font-size: 0.8125rem;
  letter-spacing: var(--track-nav);
  text-transform: uppercase;
  color: var(--color-accent);
  border-bottom: 1px solid var(--color-hairline-accent);
  padding-bottom: 4px;
  transition: color var(--dur-hover) ease, border-color var(--dur-hover) ease;
}

@media (hover: hover) and (pointer: fine) {
  .link-more:hover { color: var(--color-accent-hover); border-color: var(--color-accent); }
}

/* ---------- rooms ---------- */

.rooms { display: grid; gap: var(--s8); margin-top: var(--s8); }

/* A fixed numeral column: with `auto`, each row sized to its own number and the
   room names started at three different x positions. */
.room {
  display: grid;
  grid-template-columns: clamp(4.5rem, 8vw, 7rem) 1fr;
  gap: var(--s5);
  align-items: baseline;
  padding-top: var(--s3);
  border-top: 1px solid var(--color-hairline);
}

.room__seats {
  font-family: var(--font-display);
  font-weight: 200;
  font-size: clamp(2.5rem, 5vw, 4rem);
  line-height: 1;
  color: var(--color-accent);
}

.room__name {
  font-family: var(--font-display);
  font-size: 0.9375rem;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  margin: 0;
}

.room__note { margin: var(--s1) 0 0; color: var(--color-ink-muted); font-size: 0.9375rem; }

/* ---------- contact / details ---------- */

.details { display: grid; gap: var(--s5); margin-top: var(--s8); }

.detail__key {
  font-family: var(--font-display);
  font-size: 0.75rem;
  letter-spacing: var(--track-nav);
  text-transform: uppercase;
  color: var(--color-accent);
  margin: 0 0 var(--s1);
}

.detail__val { margin: 0; font-size: 1.0625rem; }
.detail__val a { border-bottom: 1px solid var(--color-hairline-accent); }

.hours { list-style: none; margin: 0; padding: 0; }
.hours li { display: flex; justify-content: space-between; gap: var(--s3); max-width: 34ch; padding-block: 4px; }
.hours li span:last-child { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Right-aligned contact column: the hours block hugged the left edge under
   right-aligned address and phone. */
.split__text:not(.split--flip *) .hours li { margin-left: auto; }

/* Footer columns are too narrow for day and time side by side — both wrapped
   mid-phrase. Stack them. */
.footer-col .hours li { display: grid; gap: 0; padding-block: 0 var(--s1); }

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

.site-footer {
  border-top: 1px solid var(--color-hairline-accent);
  margin-top: var(--s16);
  padding-block: var(--s12) var(--s8);
}



.footer-cols {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: var(--s5);
  align-items: start;
}

.footer-col h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 0.75rem;
  letter-spacing: var(--track-nav);
  text-transform: uppercase;
  margin: 0 0 var(--s2);
}

.footer-col p, .footer-col li { margin: 0; font-size: 0.9375rem; color: var(--color-ink-muted); }
.footer-col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.footer-col a { transition: color var(--dur-hover) ease; }
@media (hover: hover) and (pointer: fine) {
  .footer-col a:hover { color: var(--color-accent); }
}

.footer-col--end { text-align: right; }

.footer-service {
  font-size: 0.75rem;
  letter-spacing: var(--track-nav);
  text-transform: uppercase;
  color: var(--color-accent);
  margin: 0 0 4px;
}

.footer-service + .hours { margin-bottom: var(--s3); }

.footer-mark {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: 0.9375rem;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
}

.footer-legal {
  margin-top: var(--s12);
  padding-top: var(--s3);
  border-top: 1px solid var(--color-hairline);
  display: flex;
  justify-content: space-between;
  gap: var(--s3);
  font-size: 0.8125rem;
  color: var(--color-ink-muted);
}

/* ---------- drawer ---------- */

.drawer {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: var(--color-surface);
  transform: translateY(-100%);
  /* Full-screen sheet: iOS drawer curve, and out faster than in. */
  transition: transform 280ms var(--ease-drawer), visibility 280ms;
  display: grid;
  align-content: center;
  padding-inline: var(--s5);
}

.drawer[data-lv-open="true"] { transform: none; transition-duration: 400ms; }

.drawer__close {
  position: absolute;
  top: var(--s3);
  right: var(--s3);
  appearance: none;
  border: 0;
  background: none;
  cursor: pointer;
  font-family: var(--font-display);
  font-size: 0.75rem;
  letter-spacing: var(--track-nav);
  text-transform: uppercase;
  color: var(--color-ink);
}

.drawer__nav { display: grid; gap: var(--s3); }

.drawer__nav a {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(1.5rem, 7vw, 2.25rem);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
}

/* ---------- reveal ---------- */

/* Was 700ms, 20px, 80ms stagger: long enough that a fast scroller outran it and
   read the page as lagging. Short travel, strong ease-out, tight stagger — and
   the stagger index is capped so the fifth item on a page never waits 400ms. */
[data-lv-reveal] {
  transform: translateY(12px);
  transition: opacity var(--dur-reveal) var(--ease-out), transform var(--dur-reveal) var(--ease-out);
  transition-delay: calc(min(var(--lv-reveal-i, 0), 3) * 50ms);
}

[data-lv-reveal][data-lv-reveal-in] { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  [data-lv-reveal] { transition: none; transform: none; }
}

/* ---------- responsive ---------- */

@media (max-width: 900px) {
  :root { --gutter: var(--s3); }

  .masthead > .masthead__row > .masthead__link { display: none; }

  .masthead__row { grid-template-columns: auto 1fr auto; }
  .masthead__mark { justify-self: start; grid-column: 1; }

  .masthead__burger {
    display: block;
    grid-column: 3;
    justify-self: end;
    appearance: none;
    border: 0;
    background: none;
    cursor: pointer;
    font-family: var(--font-display);
    font-size: 0.75rem;
    letter-spacing: var(--track-nav);
    text-transform: uppercase;
    color: var(--color-nav-ink);
    padding: var(--s1);
  }

  .section { padding-block: var(--s8); }

  .pair { grid-template-columns: 1fr; gap: var(--s5); }
  .pair__small, .pair__large, .pair__head, .pair__body { grid-column: 1; grid-row: auto; padding: 0; }
  /* Visual order: photo, heading, photo, list — the pairing the desktop grid shows. */
  .pair__head { order: 1; }
  .pair__large { order: 2; }
  .pair__body { order: 3; justify-self: stretch; text-align: left; }
  .pair__small img, .pair__large img { aspect-ratio: 4 / 3; }
  .section-intro { margin-bottom: var(--s8); }

  .split { grid-template-columns: 1fr; gap: var(--s5); }
  .split__media, .split__text, .split--flip .split__media, .split--flip .split__text {
    grid-column: 1;
    text-align: left;
  }
  .split__text .prose { text-align: left; margin-left: 0; }
  .split__text .hours li { margin-left: 0; }

  .ornament { display: none; }

  .stack { text-align: left; justify-content: start; gap: var(--s3); }

  .footer-cols { grid-template-columns: 1fr 1fr; gap: var(--s5); }
  .footer-col--end { text-align: left; }

  /* Filled on mobile: an outlined button over a photograph depends on the scrim
     for legibility (measured 3.93:1), and darkening the whole frame to rescue it
     is what produced a flat dead field. A solid accent fill carries its own
     contrast — cream on --color-accent is 10.69:1 — so the photograph can stay
     a photograph. Selma has no hero CTA at all, so nothing is being contradicted
     here; this is the playbook-governed mobile half. */
  .hero__cta {
    display: inline-block;
    background: var(--color-accent);
    border-color: var(--color-accent);
    color: var(--color-on-dark);
  }

  .hero__cta:hover {
    background: var(--color-accent-hover);
    border-color: var(--color-accent-hover);
    color: var(--color-on-dark);
  }

  /* Sized to the content rather than the viewport: a taller box left ~230px of
     scrim below the CTA with nothing in it, which is the flat-field failure the
     no-flat-hero rule describes. */
  .hero { min-height: 62svh; }
  .hero__wordmark { letter-spacing: 0.2em; }
  /* The type block sits left; show the image's dark wood there and let the plate
     occupy the right. Measured behind the wordmark+CTA band: peak luma 183 at the
     old 72% (bright plate highlights under thin type) vs 146 here. */
  .hero__media img { object-position: 28% 50%; }

  /* Mobile stacks the copy under the plate rather than beside it, so the
     desktop horizontal gradient cannot carry it. Keep the photograph readable:
     a blanket dark field would trip the playbook's no-flat-hero rule, which is
     what an 82% scrim produced once the tagline moved out of the hero. */
  .hero__media::after {
    background: linear-gradient(
      180deg,
      transparent 0%,
      var(--color-scrim-soft) 30%,
      var(--color-scrim) 58%,
      var(--color-scrim) 100%
    );
  }

  /* Selma pins this badge bottom-left, but that is a desktop capture. At 390px a
     fixed badge and a fixed language bar eat opposite corners of every screen and
     the badge floats over whatever scrolls beneath it. The fact is not lost — the
     footer's first column already carries NUO 1995. */
  .badge { display: none; }

  /* Fixed bottom-right, it floated over whatever scrolled beneath it and ate a
     corner of every screen. Mobile navigation lives in the drawer; so does this. */
  .langbar { display: none; }

  .drawer__lang { display: flex; gap: var(--s3); margin-top: var(--s8); }

  .drawer__lang button {
    appearance: none;
    border: 0;
    background: none;
    cursor: pointer;
    font-family: var(--font-display);
    font-size: 0.8125rem;
    letter-spacing: var(--track-nav);
    text-transform: uppercase;
    color: var(--color-ink-muted);
    padding: var(--s1) 0;
  }

  .drawer__lang button.is-active { color: var(--color-accent); }
  .langbar { right: var(--s2); bottom: var(--s2); }

  .room { grid-template-columns: 1fr; gap: var(--s2); }
  .footer-legal { flex-direction: column; gap: var(--s1); }
}

@media (max-width: 560px) {
  .footer-cols { grid-template-columns: 1fr; }
  .menu-row { grid-template-columns: 1fr; gap: 4px; }
  .menu-row__price { justify-self: start; }
}

/* ---------- hero split intro (desktop; driven by assets/site.js) ----------
   Selma capture 0:02.4–0:03.1. The panel covers exactly the left half and
   travels up from below on a strong ease-in-out (slow start, fast middle, soft
   landing — the curve measured frame by frame). Its content rides with it and
   lands a beat later. Meanwhile the white wordmark fades, the scrim clears so
   the right-hand photo reads clean, and the nav turns cream. Without JS, with
   reduced motion, or under 901px, html never gets .lv-intro and the hero is
   the full photo exactly as before. */

.hero__panel { display: none; }

@media (min-width: 901px) {
  html.lv-intro .hero__panel {
    position: absolute;
    inset: 0 auto 0 0;
    width: 50%;
    z-index: 1;
    display: grid;
    align-content: center;
    justify-items: center;
    gap: var(--s5);
    padding: calc(var(--lv-header-h, 96px) + var(--s5)) var(--s8) var(--s8);
    text-align: center;
    background: var(--color-surface);
    transform: translateY(100%);
    transition: transform var(--dur-split-out) var(--ease-in-out);
  }

  html.lv-split .hero__panel {
    transform: none;
    transition-duration: var(--dur-split-in);
  }

  html.lv-intro .hero__panel > * {
    opacity: 0;
    transform: translateY(32px);
    transition: opacity 200ms var(--ease-out), transform 200ms var(--ease-out);
  }

  html.lv-split .hero__panel > * {
    opacity: 1;
    transform: none;
    transition-duration: 600ms;
    transition-delay: calc(280ms + var(--i, 0) * 60ms);
  }

  .hero__panel > :nth-child(2) { --i: 1; }
  .hero__panel > :nth-child(3) { --i: 2; }

  .hero__panel-mark {
    margin: 0;
    font-family: var(--font-display);
    font-weight: 200;
    font-size: clamp(2rem, 3.2vw, 2.75rem);
    letter-spacing: var(--track-mark);
    text-transform: uppercase;
    line-height: 1.2;
    color: var(--color-ink);
  }

  .hero__panel-intro {
    margin: 0;
    max-width: 40ch;
    color: var(--color-ink-muted);
  }

  .hero__panel-cta { margin-top: var(--s3); }

  /* The white wordmark fades while the panel climbs over it, not before: with a
     320ms ease-out it was gone by the first 120ms and the panel rose over empty
     photo. Matched to the panel's own curve so the two read as one move. */
  html.lv-intro .hero__inner,
  html.lv-intro .hero__media::after {
    transition: opacity var(--dur-split-out) var(--ease-in-out), transform var(--dur-split-out) var(--ease-in-out);
  }

  html.lv-split .hero__inner,
  html.lv-split .hero__media::after { transition-duration: 560ms; }

  html.lv-split .hero__inner { opacity: 0; transform: translateY(-16px); pointer-events: none; }
  html.lv-split .hero__media::after { opacity: 0; }

  /* The nav turns cream with the panel, not 40px later. */
  html.lv-split .masthead {
    background: var(--color-surface);
    box-shadow: 0 1px 0 var(--color-hairline);
    --color-nav-ink: var(--color-ink);
  }

  html.lv-split .badge[data-tone="on-dark"] { color: var(--color-accent); }

  /* The panel now carries the intro line; don't say it twice. */
  html.lv-intro .section-intro { display: none; }

  /* Arriving mid-page or resizing: jump straight to the end state. */
  html.lv-split-instant .hero__panel,
  html.lv-split-instant .hero__panel > *,
  html.lv-split-instant .hero__inner,
  html.lv-split-instant .hero__media::after,
  html.lv-split-instant .masthead { transition: none !important; }
}
