/* cafeunbound.com: a spiced parchment gallery.
   A warm beige wall, whisper-weight serif headings in capitals, a firm sans for
   everything else, hairline rules between sections, square corners, and one
   saffron accent for the stars, the open dot and focus on dark surfaces.
   See DESIGN.md. */

@font-face { font-family: "Cormorant"; src: url("fonts/cormorant.woff2") format("woff2"); font-weight: 300; font-style: normal; font-display: swap; }
@font-face { font-family: "DM Sans"; src: url("fonts/dm-sans.woff2") format("woff2"); font-weight: 500 700; font-style: normal; font-display: swap; }

/* ═══ Tokens ═══════════════════════════════════════════════════════════════ */
:root {
  color-scheme: light;
  /* Primitives */
  --parchment: #D8CBB8;
  --linen: #BFB4A3;
  --stone: #B6AB9C;
  --walnut: #978E81;
  --espresso: #554F48;   /* deepened from #615B53 so small text passes 4.5:1 on parchment */
  --onyx: #2C2C2C;
  --roast: #292622;
  --saffron: #D49653;
  --veg: #2F6A47;
  --nonveg: #A8433A;

  /* Semantics, for light surfaces. Dark surfaces and the linen band re-point
     them (see "Surfaces" below). Components read these, not the primitives;
     the only exceptions are the dietary marks. */
  --bg: var(--parchment);
  --text: var(--onyx);
  --text-soft: var(--espresso);
  --rule: var(--stone);
  --focus: var(--onyx);
  --fill: var(--onyx);           /* the filled main button, the current chip */
  --on-fill: var(--parchment);
  --field: color-mix(in srgb, var(--parchment), white 28%);
  --field-border: var(--espresso);
  --on-dark: var(--parchment);
  --on-dark-soft: #ABA090;
  --rule-dark: color-mix(in srgb, var(--parchment) 25%, transparent);
  --accent: var(--saffron);
  --mark: var(--walnut);         /* quiet marks: the closed dot, marquee slashes, the draft tag, empty stars */
  --placeholder: var(--linen);   /* the map's colour while its photo loads */
  --error: #8A2F27;
  /* Scrims and tints over photographs and dark surfaces, mixed from the palette.
     The hero's holds its darkest band through the header (in % and in px, so
     phones are covered too), keeping the nav above 4.5:1 over the curtains. */
  --scrim-hero: linear-gradient(180deg, color-mix(in srgb, var(--roast) 80%, transparent) 0%, color-mix(in srgb, var(--roast) 80%, transparent) max(9%, calc(var(--head-h) + 8px)), color-mix(in srgb, var(--roast) 45%, transparent) max(15%, calc(var(--head-h) + 40px)), color-mix(in srgb, var(--roast) 12%, transparent) 30%, color-mix(in srgb, var(--roast) 62%, transparent) 52%, color-mix(in srgb, var(--roast) 90%, transparent) 72%, color-mix(in srgb, var(--roast) 96%, transparent) 100%);
  --scrim-map: linear-gradient(0deg, color-mix(in srgb, var(--roast) 90%, transparent) 0%, color-mix(in srgb, var(--roast) 78%, transparent) 26%, color-mix(in srgb, var(--roast) 0%, transparent) 58%);
  --press-dark: color-mix(in srgb, var(--parchment) 12%, transparent);

  --serif: "Cormorant", "Cormorant Garamond", Georgia, serif;
  --sans: "DM Sans", ui-sans-serif, system-ui, sans-serif;

  /* Components */
  --gutter: clamp(16px, 3.4vw, 48px);
  --section: clamp(88px, 10vw, 152px);
  --radius: 3px;
  --ease: cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);   /* presses and things that appear */
  --head-h: 76px;
  --track-label: .05em;      /* 12px capitals: captions, field labels, counts */
  --track-control: .02em;    /* 13–14px capitals: buttons, links, nav, chips */
}
/* Browsers without color-mix() get the same colours written out. */
@supports not (color: color-mix(in srgb, red, red)) {
  :root {
    --field: #E3DACC; --rule-dark: rgb(216 203 184 / .25); --press-dark: rgb(216 203 184 / .12);
    --scrim-map: linear-gradient(0deg, rgb(41 38 34 / .9) 0%, rgb(41 38 34 / .78) 26%, rgb(41 38 34 / 0) 58%);
    --scrim-hero: linear-gradient(180deg, rgb(41 38 34 / .8) 0%, rgb(41 38 34 / .8) max(9%, calc(var(--head-h) + 8px)), rgb(41 38 34 / .45) max(15%, calc(var(--head-h) + 40px)), rgb(41 38 34 / .12) 30%, rgb(41 38 34 / .62) 52%, rgb(41 38 34 / .9) 72%, rgb(41 38 34 / .96) 100%);
  }
}

/* Both fonts are trimmed to the weights the site draws: Cormorant 300, DM Sans 500–700. */

/* ═══ Surfaces ═════════════════════════════════════════════════════════════
   The dark surfaces (roast sections, footer, the header over the home
   photograph, the open phone menu, the map cover, the phone bar) and the
   linen band re-point the semantic tokens, which the components inside read. */
.dark, .page-home .site-head, .nav-open .site-head, .map-cover, .dock, .page-home .skip {
  --bg: var(--roast); --text: var(--on-dark); --text-soft: var(--on-dark-soft);
  --rule: var(--rule-dark); --focus: var(--saffron); --fill: var(--parchment); --on-fill: var(--roast);
  color: var(--text);
}
.moments { --bg: var(--linen); --text-soft: var(--onyx); --rule: var(--walnut); }   /* espresso on linen is only 3.95:1 */
::selection { background: var(--fill); color: var(--on-fill); }

/* ═══ Base ═════════════════════════════════════════════════════════════════ */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-padding-top: 24px; accent-color: var(--fill); }
html:has(.page-menu) { scroll-padding-top: calc(var(--tools-h, 152px) + 16px); }
body {
  margin: 0; background: var(--bg); color: var(--text);
  font: 500 1rem/1.5 var(--sans); letter-spacing: -0.01em;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
img { display: block; max-width: 100%; height: auto; }
[hidden] { display: none !important; }
picture { display: contents; }
/* Hidden only once site.js is running (it adds .ready), so photos never stay invisible if it fails. */
.ready img[loading="lazy"]:not(.brand img) { transition: opacity 200ms var(--ease-out); }
.ready img[loading="lazy"]:not(.in, .brand img) { opacity: 0; }
a { color: inherit; text-underline-offset: .2em; text-decoration-thickness: 1px; }
p { margin: 0; }
h1, h2, h3 { margin: 0; font-weight: 300; }
ul, ol { margin: 0; }
button, input, select, textarea { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* .page-home .skip is listed so it wins over the surface rule's colour (the skip link sits over the dark hero). */
.skip, .page-home .skip { position: absolute; left: 12px; top: 12px; z-index: 50; background: var(--fill); color: var(--on-fill); padding: 12px 16px; border-radius: var(--radius); transform: translateY(calc(-100% - 24px)); }
.skip:focus { transform: none; }
.icon { width: 1.1em; height: 1.1em; flex: none; }
.wrap { padding-inline: max(var(--gutter), env(safe-area-inset-left)) max(var(--gutter), env(safe-area-inset-right)); max-width: 1536px; margin-inline: auto; }
.dark { background: var(--bg); }
.rule { border: 0; border-top: 1px solid var(--rule); margin: 0; }

/* ═══ Voices ═══════════════════════════════════════════════════════════════ */
/* Heading steps: display, h-lg, h-sm, and a smallest step shared by the
   occasion cards, the Reserve aside and the privacy headings. Component
   headings join a step here rather than restating the serif, size and tracking. */
.display, .h-lg, .h-sm, .dish-name, h1,
.menu-group h2, .story h2, .cols4 h3, .aside-card h2, .prose h2 {
  font-family: var(--serif); font-weight: 300; text-transform: uppercase;
}
h1, h2, h3, .display, .h-lg, .h-sm { text-wrap: balance; }
main p, main li, main dd, .site-foot p, .site-foot li { text-wrap: pretty; }
figcaption { text-wrap: balance; }
a[href^="tel:"] { white-space: nowrap; }
/* A Call button may wrap after "Call" on a tiny screen with large text; the number itself never breaks. */
.btn[href^="tel:"] { white-space: normal; text-align: center; }
.intro .display { max-inline-size: 8.6em; text-wrap: pretty; }
.space .display, .celebrate .display { max-inline-size: 9em; }
.best .h-lg, .visit .h-lg { max-inline-size: 9em; }
.display, h1 { font-size: clamp(3.2rem, 1.4rem + 7.4vw, 7.2rem); line-height: .86; letter-spacing: -0.04em; }
.h-lg, .menu-group h2, .story h2 { font-size: clamp(2.7rem, 1.6rem + 4.2vw, 4.3rem); line-height: .9; letter-spacing: -0.04em; }
.h-sm { font-size: clamp(2.2rem, 1.6rem + 2.4vw, 3.1rem); line-height: .92; letter-spacing: -0.03em; }
.cols4 h3, .aside-card h2, .prose h2 { font-size: clamp(1.7rem, 1.4rem + 1vw, 2.2rem); line-height: .95; letter-spacing: -0.03em; }
/* Very large text: a long word wraps rather than pushing the page sideways. */
h1, .display, .h-lg, .h-sm, .story h2, .menu-group h2, .cols4 h3, .prose a { overflow-wrap: anywhere; }
.cap {
  font: 500 .75rem/1.35 var(--sans); text-transform: uppercase; letter-spacing: var(--track-label);
  color: var(--text-soft);
}
.lead { font-size: 1.0625rem; line-height: 1.5; max-width: 36rem; }
.soft { color: var(--text-soft); }

/* ═══ Controls: ghost, filled onyx for the main action, or text ═══════════ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .6em;
  min-height: 52px; padding: 0 22px; border: 1px solid currentColor; border-radius: var(--radius);
  font: 500 .875rem/1 var(--sans); text-transform: uppercase; letter-spacing: var(--track-control);
  text-decoration: none; background: transparent; color: var(--text); cursor: pointer;
}
.btn:disabled, .btn[aria-disabled="true"] { opacity: .6; cursor: progress; }
.btn-act { background: var(--fill); color: var(--on-fill); border-color: var(--fill); }
html { -webkit-tap-highlight-color: transparent; }
/* Colour fades follow the reference (0.4s); a press lands fast on its own curve. */
.btn, .dock a, .chips a, .social a, .marquee-toggle, .menu-toggle {
  transition: background-color .4s var(--ease), color .4s var(--ease), border-color .4s var(--ease), transform 160ms var(--ease-out), filter 120ms ease, opacity 120ms ease;
}
/* The menu tabs change as you scroll, so their highlight has to keep up. */
.chips a { transition: background-color 150ms ease, color 150ms ease, border-color 150ms ease, transform 160ms var(--ease-out); }
/* A label being swapped blurs for a moment, so it reads as one button changing. */
.btn.swap { filter: blur(2px); opacity: .7; }
.btn:active, .dock a:active, .chips a:active, .social a:active, .marquee-toggle:active, .menu-toggle:active { transform: scale(.98); }
/* Text-only controls: with the grey tap flash gone, a dip in opacity confirms the tap. */
.tlink, .nav a, .faq summary, .site-foot li a { transition: opacity .2s ease; }
.tlink:active, .nav a:active, .faq summary:active, .site-foot li a:active { opacity: .6; }
.dock a:active { background: var(--press-dark); }
.tlink {
  display: inline-flex; align-items: center; gap: .5em; min-height: 44px;
  font: 500 .8125rem/1 var(--sans); text-transform: uppercase; letter-spacing: var(--track-control); text-decoration: none;
  background: linear-gradient(currentColor, currentColor) 0 calc(100% - 12px) / 100% 1px no-repeat;
}
.btns { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.cta-row { margin-top: 28px; }

/* ═══ Header ═══════════════════════════════════════════════════════════════ */
.site-head { position: relative; z-index: 20; border-bottom: 1px solid var(--rule); }
.site-head .wrap { display: flex; flex-wrap: wrap; align-items: center; gap: 0 28px; min-height: var(--head-h); padding-block: 8px; }
.brand { display: flex; flex: none; align-items: center; min-height: 48px; }
.brand img { height: 46px; width: auto; }
.brand .logo-on-dark { display: none; }
.nav { display: flex; gap: 26px; }
.nav a { font: 500 .875rem/1 var(--sans); text-transform: uppercase; letter-spacing: var(--track-control); text-decoration: none; padding: 16px 0; }
.nav a[aria-current] { text-decoration: underline; text-decoration-color: currentColor; text-decoration-thickness: 2px; text-underline-offset: 6px; }
.head-right { margin-left: auto; display: flex; align-items: center; gap: 20px; }
.head-cta { min-height: 44px; padding: 0 18px; }
.nav a, .head-right a { white-space: nowrap; }
/* Narrow laptops: the header keeps Call and Reserve; Directions stays one tap away under Visit. */
@media (max-width: 1180px) { .head-right .head-dir { display: none; } }
.nav-act { display: none; }
.menu-toggle { display: none; background: none; border: 0; width: 48px; height: 48px; padding: 0; place-items: center; cursor: pointer; }
.menu-toggle .icon { width: 26px; height: 26px; }
.menu-toggle > span { grid-area: 1 / 1; display: grid; transition: opacity 150ms ease, filter 150ms ease; }
.menu-toggle .i-close, .nav-open .menu-toggle .i-open { opacity: 0; filter: blur(2px); }
.nav-open .menu-toggle .i-close { opacity: 1; filter: none; }
/* Home: the header floats over the photograph. */
.page-home .site-head { position: absolute; inset: 0 0 auto; border: 0; }
.page-home .brand .logo-on-light { display: none; }
.page-home .brand .logo-on-dark { display: block; }

/* ═══ Home: hero ═══════════════════════════════════════════════════════════ */
.hero { position: relative; isolation: isolate; min-height: min(100svh, 980px); display: flex; flex-direction: column; }
.hero-photo { position: absolute; inset: 0; z-index: -1; }
.hero-photo img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; }
/* Laptops: a little of the dark ceiling goes under the header, so the rating line clears the diners' faces. */
@media (min-width: 721px) { .hero-photo { overflow: hidden; } .hero-photo img { height: calc(100% + 48px); margin-top: -48px; } }
.hero-photo::after {
  content: ""; position: absolute; inset: 0;
  background: var(--scrim-hero);
}
.hero-body { margin-top: auto; padding-bottom: 28px; width: 100%; }
.flank { display: flex; justify-content: space-between; gap: 6px 16px; flex-wrap: wrap; padding-bottom: 14px; }
.hero .flank .cap { color: var(--text); text-decoration: none; }
/* A 44px tap target drawn by ::before, so the focus ring hugs the text. */
.hero .flank a.cap { display: inline-flex; align-items: center; align-self: flex-start; position: relative; }
.hero .flank a.cap::before { content: ""; position: absolute; inset: calc(50% - 22px) -4px; }
.flank .stars { color: var(--accent); margin-right: 8px; display: inline-flex; }
.flank .stars .icon { width: 14px; height: 14px; }
.wordmark {
  /* Capped at 21vw (where it just fits a 320px phone), so a larger browser
     font size can't push it past the screen. */
  font: 500 min(max(4.2rem, 18.4vw), 21vw, 12.45rem)/.8 var(--sans); letter-spacing: -0.016em;
  text-transform: uppercase; margin: 0 0 0 -.04em; color: var(--text); white-space: nowrap;
}
.hero-foot {
  display: grid; grid-template-columns: 1fr 1fr auto; gap: 16px 32px; align-items: end;
  margin-top: 26px; padding-top: 18px; border-top: 1px solid var(--rule);
}
.hero-foot .cap { color: var(--text); max-width: 24rem; }
.open::before {
  content: ""; display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  background: var(--mark); margin-right: 9px; vertical-align: 1px;
}
.open.is-open::before { background: var(--accent); }

/* ═══ Home: intro, marquee, bestsellers ═══════════════════════════════════ */
.intro { padding-block: var(--section) calc(var(--section) * .8); display: grid; grid-template-columns: 1.25fr 1fr; gap: 48px var(--gutter); align-items: end; }
.intro > div > .cap { display: block; margin-bottom: 26px; }
.intro .side { display: grid; gap: 26px; padding-bottom: 6px; }
.intro .day { margin: 0 0 6px; }
.intro .day img { width: 100%; aspect-ratio: 900 / 794; object-fit: cover; }
.intro .day figcaption { margin-top: 10px; }
/* Desktop: the heading sits level with the middle of the photo; the words and
   buttons run on beneath the photo. */
@media (min-width: 961px) {
  .intro { grid-template-rows: auto auto auto; row-gap: 0; align-items: start; }
  .intro .side { display: contents; }
  /* The bottom margin matches the caption under the photo, so the centring is on the photo itself. */
  .intro > div:first-child { grid-row: 1; align-self: center; margin-bottom: calc(1.35 * .75rem + 16px); }
  .intro .day { grid-column: 2; grid-row: 1; }
  .intro .side > .lead, .intro .side > .btns { grid-column: 2; margin-top: 26px; }
}

.marquee-wrap { position: relative; border-block: 1px solid var(--rule); }
.marquee { overflow: hidden; padding-block: 22px; clip-path: inset(0 calc(max(var(--gutter), env(safe-area-inset-right)) + 56px) 0 0); }
.marquee-toggle { position: absolute; right: max(var(--gutter), env(safe-area-inset-right)); top: 50%; translate: 0 -50%; width: 44px; height: 44px; display: grid; place-items: center; border: 1px solid var(--text); border-radius: var(--radius); background: var(--bg); cursor: pointer; }
.marquee-toggle .icon { width: 16px; height: 16px; }
.marquee-toggle .i-play { display: none; }
.marquee-wrap.paused .marquee-toggle .i-play { display: block; }
.marquee-wrap.paused .marquee-toggle .i-pause { display: none; }
.marquee-wrap.paused .marquee-track, .marquee-wrap.offscreen .marquee-track { animation-play-state: paused; }
.marquee-track { display: flex; width: max-content; animation: marquee 27s linear infinite; }
.marquee span { font: 300 clamp(2rem, 1.3rem + 2.6vw, 3.1rem)/1 var(--serif); text-transform: uppercase; letter-spacing: -0.03em; white-space: nowrap; padding-inline: 28px; }
.marquee span::after { content: "/"; color: var(--mark); margin-left: 56px; }
@keyframes marquee { to { transform: translateX(-50%); } }

.best { padding-block: var(--section); display: grid; grid-template-columns: 5fr 7fr; gap: var(--gutter); }
.best figure { margin: 0; position: sticky; top: 24px; align-self: start; }
.best figure img { width: 100%; aspect-ratio: 1066 / 1254; object-fit: cover; }
.best header { display: grid; gap: 22px; margin-bottom: 44px; }
.dishes { list-style: none; padding: 0; border-top: 1px solid var(--rule); }
.dishes li { display: grid; gap: 6px; padding: 22px 0 24px; border-bottom: 1px solid var(--rule); }
.dish-name { font-size: 1.625rem; line-height: 1.05; letter-spacing: -0.006em; }
.dishes p { color: var(--text-soft); max-width: 34rem; font-size: .9375rem; }
.diet { display: flex; align-items: center; gap: 8px; font-size: .75rem; text-transform: uppercase; letter-spacing: var(--track-label); color: var(--text-soft); }
.draft { justify-self: start; font-size: .75rem; text-transform: uppercase; border: 1px dashed var(--mark); padding: 4px 8px; border-radius: var(--radius); }
.best .more { margin-top: 32px; }

/* Veg / non-veg marks: the Indian convention, square with a dot or a triangle. */
.mark { width: 13px; height: 13px; border: 1.5px solid var(--veg); display: inline-grid; place-items: center; flex: none; vertical-align: -1px; }
.mark::after { content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--veg); }
.mark.nv { border-color: var(--nonveg); }
.mark.nv::after { border-radius: 0; width: 0; height: 0; background: none; border-left: 3.5px solid transparent; border-right: 3.5px solid transparent; border-bottom: 6px solid var(--nonveg); }

/* ═══ Home: the space ══════════════════════════════════════════════════════ */
.space { padding-block: var(--section); }
.space .top { margin-bottom: 56px; display: grid; gap: 24px; }
.photos { display: grid; gap: 14px; }
.photos .group { color: var(--text); border-top: 1px solid var(--rule); padding-top: 14px; margin-top: 18px; }
.photos .group:first-child { margin-top: 0; }
.photos .row { display: grid; gap: 12px; align-items: start; }
.photos .row.in { grid-template-columns: 1fr 1fr; }
.photos .row.out { grid-template-columns: 1.3fr 1fr 1fr; }
.photos figure { margin: 0; }
.photos img { width: 100%; object-fit: cover; }
/* The two interior photos are portraits: a 3:4 frame keeps both floors in view,
   capped so a wide screen never gets a photo taller than itself. */
.photos .row.in img { aspect-ratio: 3 / 4; max-height: 84svh; }
.photos .row.out img { aspect-ratio: 4 / 5; }
.photos .row.out figure:first-child img { aspect-ratio: 1.04; }
/* Crop focus belongs to the photo, not to its place in a row. */
img.focus-high { object-position: 50% 35%; }
img.focus-top { object-position: 50% 0; }    /* the dusk front: the lit sign and the courtyard tables */
img.focus-table { object-position: 42% 50%; }   /* the long table with the chandelier beside it */
.photos figcaption { margin-top: 10px; }

/* ═══ Home: moments, reviews, questions, visit, celebrations ══════════════ */
.moments { background: var(--bg); padding-block: var(--section); }
.moments header { display: grid; gap: 16px; margin-bottom: 48px; }
.cols4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); column-gap: 48px; border-top: 1px solid var(--rule); }
.cols4 article { padding: 22px 0 8px; position: relative; }
.cols4 article + article::before { content: ""; position: absolute; top: 0; bottom: 0; left: -24px; border-left: 1px solid var(--rule); }
.cols4 figure { margin: 0 0 20px; }
.cols4 figure img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }
.cols4 h3 { margin: 12px 0 14px; }
.moments .more { margin-top: 36px; }
.cols4 p { max-width: 22rem; font-size: .9375rem; }

.reviews { padding-block: var(--section); display: grid; grid-template-columns: 300px 1fr; gap: var(--gutter); }
.score { border: 1px solid var(--rule); padding: 28px; align-self: start; display: grid; gap: 8px; justify-items: start; }
.score .num { font: 700 4rem/1 var(--sans); letter-spacing: -0.04em; }
.score .num span { font-size: 1.375rem; font-weight: 500; color: var(--text-soft); }
.score .stars { display: flex; gap: 4px; margin: 6px 0 4px; }
.score .stars { color: var(--accent); }
.score .stars .icon { width: 15px; height: 15px; }
.star-part { display: inline-grid; }
.star-part > .icon { grid-area: 1 / 1; }
.star-part > .icon:first-child { color: var(--mark); }
.quotes { display: grid; grid-template-columns: repeat(2, 1fr); border-top: 1px solid var(--rule); }
.quotes blockquote { margin: 0; padding: 32px 28px 32px 0; border-bottom: 1px solid var(--rule); position: relative; display: flex; flex-direction: column; gap: 28px; }
.quotes blockquote:nth-child(even) { border-left: 1px solid var(--rule); padding-left: 28px; padding-right: 0; }
.quotes p { font: 300 clamp(1.45rem, 1.2rem + .8vw, 1.75rem)/1.25 var(--serif); letter-spacing: -0.01em; }
.quotes footer { margin-top: auto; }

.home-faq { padding-block: 0 var(--section); display: grid; grid-template-columns: 1fr 1.6fr; gap: 32px var(--gutter); align-items: start; }
.faq { border-top: 1px solid var(--rule); }
.faq details { border-bottom: 1px solid var(--rule); }
.faq summary {
  list-style: none; cursor: pointer; display: flex; justify-content: space-between; align-items: center; gap: 16px;
  min-height: 60px; padding: 14px 0; font-size: 1.0625rem;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; content: "+" / ""; font: 300 1.75rem/1 var(--serif); color: var(--text-soft); transition: transform .4s var(--ease); }
.faq details[open] summary::after { transform: rotate(45deg); }
.faq details > div { padding: 0 0 20px; max-width: 34rem; color: var(--text-soft); }
.faq details[open] > div { animation: fade-in 200ms var(--ease-out); }
@keyframes fade-in { from { opacity: 0; } }
.faq details > div a { color: var(--text); }
.faq .more { padding-top: 10px; }
.faq-groups { display: grid; gap: clamp(48px, 6vw, 80px); }
.faq-group { display: grid; grid-template-columns: 1fr 1.6fr; gap: 20px var(--gutter); align-items: start; }
@media (max-width: 960px) { .faq-group { grid-template-columns: 1fr; } }

.visit { padding-block: var(--section); display: grid; grid-template-columns: 1fr 1fr; gap: var(--gutter); }
.visit dl { margin: 34px 0 32px; border-top: 1px solid var(--rule); }
.visit dl div { display: grid; grid-template-columns: 160px 1fr; gap: 16px; padding: 16px 0; border-bottom: 1px solid var(--rule); }
.visit dt { padding-top: 3px; }
.visit dd { margin: 0; }
/* The phone number is a standalone target: 44px tall (drawn by ::before) without
   moving the row, while its focus ring hugs the text. */
.visit dd a { position: relative; }
.visit dd a::before { content: ""; position: absolute; inset: -12px -4px; }
.visit .note { margin-top: 18px; max-width: 34rem; }
.map { position: relative; min-height: 360px; align-self: stretch; background: var(--placeholder); }
.map img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* The controls sit at the foot of the photo on a dark fade, so the shopfront
   stays in view and the text is always on dark. */
.map-cover { position: absolute; inset: 0; z-index: 1; display: flex; align-items: flex-end; background: var(--scrim-map); }
.map-plate { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 22px; padding: 20px; }
.map iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; opacity: 0; transition: opacity 200ms var(--ease-out); }
.map iframe.ready { opacity: 1; }

.celebrate { padding-block: var(--section) calc(var(--section) * .75); }
.celebrate .grid { display: grid; gap: 28px; }
.celebrate .grid > * { max-width: 52rem; }
.celebrate .cap { display: block; margin-bottom: 24px; }
.celebrate .lead { margin-bottom: 28px; max-width: 40rem; }

/* ═══ Inner pages ══════════════════════════════════════════════════════════ */
.page-head { padding-block: clamp(56px, 7vw, 104px) clamp(36px, 4vw, 56px); }
.page-head h1 + .cap { margin-top: 22px; }
.page-head .lead { margin-top: 22px; color: var(--text-soft); }
.page-head .lead a { color: var(--text); }
.page-head .btns { margin-top: 32px; }
.section { padding-block: 0 var(--section); }
.page-end { height: calc(var(--section) * .6); }

/* Menu */
.menu-tools { position: sticky; top: 0; z-index: 10; background: var(--bg); border-block: 1px solid var(--rule); }
.menu-tools .wrap { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; padding-block: 12px; }
.menu-search { flex: 1 1 150px; min-width: 0; max-width: 360px; }
.vegonly { flex: none; }
.menu-search input, .form input, .form select, .form textarea {
  width: 100%; min-height: 48px; padding: 12px 14px; border: 1px solid var(--field-border); border-radius: var(--radius);
  background: var(--field); font-size: 1rem;
}
.menu-search input:focus, .form input:focus, .form select:focus, .form textarea:focus { outline: 2px solid var(--focus); outline-offset: 1px; border-color: var(--text); }
.vegonly { display: inline-flex; align-items: center; gap: 10px; min-height: 48px; font: 500 .8125rem/1 var(--sans); text-transform: uppercase; letter-spacing: var(--track-control); cursor: pointer; }
.vegonly input { width: 20px; height: 20px; accent-color: var(--veg); }
.chips { flex: 1 0 100%; display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; scroll-padding-inline: 8px; padding: 6px 6px 8px; margin: -6px -6px -8px; }
.chips::-webkit-scrollbar { display: none; }
.chips a {
  flex: none; display: inline-flex; align-items: center; min-height: 44px; padding: 0 14px;
  border: 1px solid var(--rule); border-radius: var(--radius); text-decoration: none;
  font: 500 .8125rem/1 var(--sans); text-transform: uppercase; letter-spacing: var(--track-control); white-space: nowrap;
}
.chips a.on { background: var(--fill); color: var(--on-fill); border-color: var(--fill); }
/* Laptops: the ten sections as a 5 by 2 index, so none hides past the edge.
   From 1440px they fit on one line. */
/* em queries, so larger text moves the breakpoints with it; columns shrink and
   chip labels wrap rather than run off the edge. */
/* A mouse can't swipe, so below the grid the strip wraps instead of scrolling. */
@media (max-width: 60em) and (hover: hover) and (pointer: fine) { .chips { flex-wrap: wrap; overflow-x: visible; } }
@media (min-width: 60.0625em) and (max-width: 89.9375em) {
  .chips { display: grid; grid-template-columns: repeat(5, minmax(0, max-content)); }
  .chips a { justify-content: center; text-align: center; white-space: normal; }
}
@media (max-height: 500px) { .menu-tools { position: static; } html:has(.page-menu) { scroll-padding-top: 24px; } }
.menu-group { padding-top: clamp(48px, 6vw, 80px); scroll-margin-top: calc(8px - clamp(48px, 6vw, 80px)); }
.menu-group > header { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 10px 16px; padding-bottom: 18px; border-bottom: 1px solid var(--text); }
.menu-group h2 { flex: 1 1 0; min-width: 0; }
.menu-group header span { white-space: nowrap; margin-left: auto; font: 500 .75rem/1 var(--sans); text-transform: uppercase; letter-spacing: var(--track-label); color: var(--text-soft); }
.menu-cats { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr)); gap: 0 var(--gutter); }
.menu-cat { padding-top: 26px; }
.menu-cat h3 { font: 500 .75rem/1.3 var(--sans); text-transform: uppercase; letter-spacing: var(--track-label); color: var(--text-soft); padding-bottom: 10px; border-bottom: 1px solid var(--rule); }
.menu-cat ul { list-style: none; padding: 6px 0 0; }
.menu-cat .nm, .site-foot li { overflow-wrap: anywhere; }
.menu-cat li { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: baseline; gap: 12px; padding: 8px 0; }
.menu-cat li .mark { align-self: center; }
.menu-cat .pr { font-weight: 700; font-variant-numeric: tabular-nums; }
.menu-empty { padding: 48px 0; font-size: 1.0625rem; display: grid; gap: 18px; justify-items: start; }
.menu-note { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 20px; margin-top: 48px; padding-top: 22px; border-top: 1px solid var(--rule); }
.legend { display: flex; flex-wrap: wrap; gap: 8px 22px; font-size: .8125rem; color: var(--text-soft); }
.legend > span { display: inline-flex; align-items: center; gap: 8px; }

/* Reserve */
.reserve { display: grid; grid-template-columns: 1.5fr 1fr; gap: var(--gutter); align-items: start; }
.form { display: grid; grid-template-columns: 1fr 1fr; gap: 22px 18px; border-top: 1px solid var(--text); padding-top: 28px; }
.field { display: grid; gap: 8px; align-content: start; min-width: 0; }
.field.full, .submit { grid-column: 1 / -1; }
.field label { font: 500 .75rem/1.3 var(--sans); text-transform: uppercase; letter-spacing: var(--track-label); }
.hint { text-transform: none; letter-spacing: 0; color: var(--text-soft); }
.form textarea { min-height: 110px; resize: vertical; }
.menu-search input::placeholder, .form ::placeholder { color: var(--text-soft); opacity: 1; }
.form [aria-invalid="true"] { border-color: var(--error); }
.err { color: var(--error); font-size: .875rem; }
.err:empty { display: none; }
.err:not(:empty) { animation: fade-in 150ms var(--ease-out); }
.submit { display: grid; gap: 14px; justify-items: start; padding-top: 8px; }
.submit p { color: var(--text-soft); font-size: .9375rem; max-width: 38rem; }
.submit p a { color: var(--text); }
.aside-card { display: grid; gap: 26px; border-top: 1px solid var(--rule); padding-top: 28px; }
.aside-card .ph img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.aside-card h2 { margin-bottom: 10px; }
.aside-card p + p { margin-top: 12px; }

/* The space */
.gallery { display: grid; grid-template-columns: repeat(6, 1fr); gap: 12px; margin-top: 48px; }
.gallery figure { margin: 0; }
.gallery img { width: 100%; height: 100%; object-fit: cover; }
.gallery .g1 { grid-column: span 4; aspect-ratio: 16 / 10; }
.gallery .g2 { grid-column: span 2; position: relative; }
.gallery .g2 img { position: absolute; inset: 0; object-position: 50% 0; }   /* keeps the lit sign in frame */
.gallery .g3, .gallery .g4, .gallery .g5 { grid-column: span 2; aspect-ratio: 4 / 5; }
.story { display: grid; grid-template-columns: 1fr 1.4fr; gap: 32px var(--gutter); padding-top: var(--section); }
.story p + p { margin-top: 16px; }
.story p { max-width: 34rem; }

/* Long reading (privacy): the contents sit on the title's left edge, the
   numbered clauses beside them; on a phone the contents come first. */
.policy { display: grid; gap: 48px; align-items: start; }
.policy-toc { border-block: 1px solid var(--rule); padding-block: 18px 12px; }
.policy-toc ol { list-style: none; padding: 0; margin: 10px 0 0; counter-reset: toc; }
.policy-toc li { counter-increment: toc; }
.policy-toc a { display: flex; align-items: baseline; gap: 14px; padding-block: 10px; color: var(--text); text-decoration: none; }
.policy-toc a::before, .clause h2::before {
  content: counter(toc, decimal-leading-zero); font: 500 .75rem/1.35 var(--sans); letter-spacing: var(--track-label);
  font-variant-numeric: tabular-nums; color: var(--text-soft);
}
.policy-toc a::before { min-width: 1.6em; }
.policy-toc a:hover { text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
/* The clause being read: heavier name, its number in full text colour. */
.policy-toc a[aria-current] { font-weight: 600; }
.policy-toc a[aria-current]::before { color: var(--text); }
@media (min-width: 60.0625em) {
  .policy { grid-template-columns: 15rem minmax(0, 34rem); column-gap: clamp(48px, 7vw, 120px); }
  .policy-toc { position: sticky; top: 32px; }
}
.prose { max-width: 34rem; counter-reset: clause; }   /* about 72 characters a line, 75 at most */
.policy-intro { font-size: 1.0625rem; line-height: 1.6; }
.prose p + p { margin-top: 14px; }
.clause { counter-increment: clause; margin-top: 56px; padding-top: 24px; border-top: 1px solid var(--rule); }
.clause h2 { margin-bottom: 20px; }
.clause h2::before { content: counter(clause, decimal-leading-zero); display: block; margin-bottom: 14px; }
.clause ul { padding-left: 1.1em; display: grid; gap: 12px; margin: 0; }
.clause li { padding-left: .35em; }
.clause li::marker { color: var(--text-soft); }
.clause ul + p, .clause p + ul, .clause p + dl, .clause dl + p { margin-top: 20px; }
.officer { margin: 0; border-block: 1px solid var(--rule); }
.officer > div { display: grid; grid-template-columns: 10rem minmax(0, 1fr); gap: 4px 16px; padding-block: 14px; }
.officer > div + div { border-top: 1px solid var(--rule); }
.officer dt { font: 500 .75rem/1.35 var(--sans); text-transform: uppercase; letter-spacing: var(--track-label); color: var(--text-soft); padding-top: .3em; }
.officer dd { margin: 0; }
@media (max-width: 30em) { .officer > div { grid-template-columns: minmax(0, 1fr); } }

/* ═══ Footer and phone bar ═════════════════════════════════════════════════ */
.site-foot { padding-block: 64px 40px; }
.foot-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 40px var(--gutter); padding-bottom: 40px; border-bottom: 1px solid var(--rule); }
.foot-logo { height: 52px; width: auto; }
.foot-brand .cap { margin-top: 18px; }
.social { display: flex; gap: 6px; margin-top: 16px; }
.social a { display: grid; place-items: center; width: 44px; height: 44px; border: 1px solid var(--rule); border-radius: var(--radius); }
.site-foot h2 { margin-bottom: 14px; }
.site-foot ul { list-style: none; padding: 0; display: grid; gap: 4px; }
.site-foot li a { display: inline-flex; min-height: 32px; align-items: center; text-decoration: none; }
/* Touch laptops and tablets in landscape: nav links get 44px of width without moving. */
@media (pointer: coarse) and (min-width: 961px) { .nav a { padding-inline: 8px; margin-inline: -8px; } }
@media (pointer: coarse), (max-width: 720px) {
  .site-foot li a { display: flex; min-height: 44px; }
  .site-foot ul { gap: 0; }
}
.legal { padding-top: 24px; display: grid; gap: 8px; color: var(--text-soft); font-size: .8125rem; }
.legal a { color: var(--text); }
.dock { display: none; }
/* Without JavaScript: no booking form (plain links instead), no pause button,
   and the phone navigation stays visible as a row of links. */
html:not(.js) [data-reserve], html:not(.js) .marquee-toggle { display: none; }
html:not(.js) .marquee { clip-path: none; }
.nojs-book { display: grid; gap: 22px; border-top: 1px solid var(--text); padding-top: 28px; }
.page-reserve .head-cta, .page-reserve .dock .go, .page-reserve .nav-act .btn-act { display: none; }
.site-foot { border-top: 1px solid var(--rule); }

/* ═══ Phones and tablets ═══════════════════════════════════════════════════ */
@media (max-width: 960px) {
  .nav, .head-phone { display: none; }
  html:not(.js) .site-head .wrap { flex-wrap: wrap; }
  html:not(.js) .nav { display: flex; flex-wrap: wrap; gap: 0 18px; order: 3; width: 100%; padding-bottom: 6px; }
  html:not(.js) .menu-toggle { display: none; }
  .menu-toggle { display: grid; }
  /* The open menu scrolls on its own, so every item is reachable on a short
     or zoomed screen; the header bar stays opaque above it. */
  .nav-open .nav {
    display: flex; flex-direction: column; position: fixed; inset: 0; z-index: -1;
    background: var(--bg); gap: 0; overflow-y: auto; overscroll-behavior: contain;
    scroll-padding-block: calc(var(--head-h) + 8px) calc(8px + env(safe-area-inset-bottom));   /* focus never lands under the bar */
    padding: calc(var(--head-h) + 24px) max(var(--gutter), env(safe-area-inset-right)) calc(24px + env(safe-area-inset-bottom)) max(var(--gutter), env(safe-area-inset-left));
    transition: opacity 200ms var(--ease-out);
  }
  .nav-open .site-head .wrap { background: var(--bg); }
  /* The menu fades in (no movement); it closes instantly. */
  @starting-style { .nav-open .nav { opacity: 0; } }
  .nav-open .nav > a, .nav-open .nav-act { animation: fade-in 140ms var(--ease-out) both; }
  .nav-open .nav > :nth-child(2) { animation-delay: 25ms; }
  .nav-open .nav > :nth-child(3) { animation-delay: 50ms; }
  .nav-open .nav > :nth-child(4) { animation-delay: 75ms; }
  .nav-open .nav > :nth-child(5) { animation-delay: 100ms; }
  .nav-open .nav > :nth-child(6) { animation-delay: 125ms; }
  .nav-open .nav-act { display: grid; gap: 10px; margin-top: 28px; }
  .nav-open .nav-act .btn { min-height: 52px; }
  .nav-open .nav > a { font: 300 2.6rem/1 var(--serif); text-transform: uppercase; letter-spacing: -0.03em; padding: 14px 0; border-bottom: 1px solid var(--rule); }
  .nav-open .site-head { border-color: transparent; }
  .nav-open .brand .logo-on-light { display: none; }
  .nav-open .brand .logo-on-dark { display: block; }
  .nav-open { overflow: hidden; }
  .intro, .best, .reviews, .visit, .celebrate .grid, .home-faq, .reserve, .story { grid-template-columns: 1fr; }
  .best figure { position: static; order: 2; }
  .best figure img { aspect-ratio: 4 / 3; object-position: 50% 62%; }
  .reviews .score { max-width: 420px; }
  .map { min-height: 300px; }
  .hero-foot { grid-template-columns: 1fr auto; }
  .hero-foot .btns { grid-column: 2; grid-row: 1 / span 2; }
}
@media (max-width: 720px) {
  :root { --head-h: 64px; }
  .head-cta { display: none; }
  .brand img { height: 40px; }
  .hero { min-height: 0; }
  .hero-photo { position: relative; inset: auto; height: 58svh; min-height: min(340px, 70svh); }   /* landscape phones still see the wordmark */
  .hero-photo img { object-position: 46% 40%; }
  .hero-body { margin-top: -84px; position: relative; }
  .flank { flex-direction: column; }
  .hero-foot { grid-template-columns: 1fr; }
  .hero-foot .btns { grid-column: auto; grid-row: auto; }
  .hero-foot .btns .btn { flex: 1; }
  .photos .row.in, .photos .row.out { grid-template-columns: 1fr 1fr; }
  .photos .row.out figure:first-child { grid-column: 1 / -1; }
  .photos .row.out figure:first-child img { aspect-ratio: 900 / 794; }
  .photos .row.in img, .photos .row.out img { aspect-ratio: 3 / 4; }
  .quotes { grid-template-columns: 1fr; }
  .quotes blockquote, .quotes blockquote:nth-child(even) { border-left: 0; padding: 28px 0; }
  .visit dl div { grid-template-columns: 1fr; gap: 4px; }
  .form { grid-template-columns: 1fr; }
  .gallery { grid-template-columns: 1fr 1fr; }
  .gallery .g1 { grid-column: 1 / -1; aspect-ratio: 4 / 3; }
  .gallery .g2, .gallery .g3, .gallery .g4, .gallery .g5 { grid-column: span 1; aspect-ratio: 3 / 4; }
  .foot-grid { grid-template-columns: 1fr; }
  .site-foot { padding-bottom: calc(var(--dock-h, calc(64px + env(safe-area-inset-bottom))) + 46px); }
  .dock {
    display: flex; flex-wrap: wrap; position: fixed; inset: auto 0 0; z-index: 30;
    background: var(--bg); border-top: 1px solid var(--rule); gap: 8px;
    padding: 8px max(8px, env(safe-area-inset-right)) calc(8px + env(safe-area-inset-bottom)) max(8px, env(safe-area-inset-left));
  }
  .dock a { flex: 1 1 0; min-width: max-content; display: flex; align-items: center; justify-content: center; gap: 8px; min-height: 48px; text-decoration: none; font: 500 .8125rem/1 var(--sans); text-transform: uppercase; letter-spacing: var(--track-control); border-radius: var(--radius); }
  .dock a.go { flex-grow: 1.2; border: 1px solid var(--text); }
  .nav-open .dock { display: none; }
  html { scroll-padding-bottom: calc(var(--dock-h, calc(64px + env(safe-area-inset-bottom))) + 32px); }
  html:has(.page-menu) { scroll-padding-top: calc(var(--tools-h, 132px) + 16px); }
}
/* The occasion cards follow the text size too: two columns, then one. */
@media (max-width: 60em) {
  .cols4 { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 32px; border-top: 0; }
  .cols4 article { border-top: 1px solid var(--rule); padding: 20px 0 16px; }
  .cols4 article + article::before { display: none; }
  .cols4 article:nth-child(even)::before { display: block; left: -16px; }
}
@media (max-width: 45em) {
  .cols4 { grid-template-columns: minmax(0, 1fr); }
  .cols4 article:nth-child(even)::before { display: none; }
  /* Each card follows its photo: a portrait stays tall, a near-square photo
     square, so the chandelier and the cup aren't cut to a strip. */
  .cols4 figure img { aspect-ratio: 3 / 2; }
  .cols4 figure img.tall { aspect-ratio: 4 / 5; }
  .cols4 figure img.squarish { aspect-ratio: 1; }
}
/* Very short screens: the phone bar sits at the end of the page instead of taking a third of it. */
@media (max-width: 720px) and (max-height: 420px) { .dock { position: static; } }
/* Landscape phones and zoomed screens: the open menu tightens so it all fits. */
@media (max-width: 960px) and (max-height: 500px) {
  .nav-open .nav { padding-top: calc(var(--head-h) + 8px); }
  .nav-open .nav > a { font-size: 1.8rem; padding: 10px 0; }
  .nav-open .nav-act { margin-top: 16px; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); }
}

@media (max-width: 389px) {
  .hero-foot .btns .btn { padding: 0 10px; font-size: .8125rem; }
}

@media (prefers-reduced-motion: no-preference) {
  html:has(.page-home) { scroll-behavior: smooth; }
}

/* Hover effects only for a mouse or trackpad, so taps don't leave them stuck on. */
@media (hover: hover) and (pointer: fine) {
  .btn:hover { background: var(--fill); color: var(--on-fill); border-color: var(--fill); }
  .btn-act:hover { background: transparent; color: var(--text); border-color: var(--text); }
  .tlink:hover { opacity: .7; }
  .marquee:hover .marquee-track { animation-play-state: paused; }
  .chips a:hover { border-color: var(--text); }
  .social a:hover { border-color: var(--text); }
  .site-foot li a:hover { text-decoration: underline; }
  .nav a:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 6px; }
}

/* ═══ Motion: the marquee, presses and fades. With reduced motion nothing
   moves; colour and opacity fades stay, because they help and don't move.
   The marquee is left out (it only repeats the bestseller list below it); its
   top rule stays. */
@media (prefers-reduced-motion: reduce) {
  .marquee-wrap { border-bottom: 0; }
  .marquee-wrap > * { display: none; }   /* its top hairline still divides the intro from the bestsellers */
  .btn:active, .dock a:active, .chips a:active, .social a:active, .marquee-toggle:active, .menu-toggle:active { transform: none; }
  .faq summary::after { transition: none; }
}

/* ═══ Home motion: the lights come on, then each section arrives once ═══════
   The head script adds .motion unless the visitor asked for reduced motion;
   site.js adds .lit when the hero photo is in, and marks the scroll pieces
   (.rise, .print, .drawn, .counting) itself, so without it they never hide.
   The scroll pieces are scroll-linked; only the review stars run on a clock.
   If site.js fails, the hero shows itself after 4s. */
:root { --m-out: cubic-bezier(0.16, 1, 0.3, 1); --m-draw: cubic-bezier(0.65, 0, 0.35, 1); }
@keyframes m-safe-show { to { opacity: 1; transform: none; filter: none; } }
@keyframes m-safe-hide { to { opacity: 0; } }

/* The room starts dim and the lamps come on. */
.motion .hero-photo { overflow: hidden; }
.motion .hero-photo::before {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: var(--roast); opacity: .78;
  transition: opacity 1400ms var(--m-out) 150ms; animation: m-safe-hide 1ms 4s forwards;
}
/* Only opacity and transform move here; a filter on a full-screen photo is costly to draw. */
.motion .hero-photo img {
  transform: scale(1.06);
  transition: transform 2400ms var(--m-out); animation: m-safe-show 1ms 4s forwards;
}
.motion.lit .hero-photo::before { opacity: 0; }
.motion.lit .hero-photo img { transform: none; }
/* Laptops keep the hero photo's own crop and offset. */
@media (min-width: 721px) { .motion .hero-photo img { transform-origin: 50% 40%; } }

/* The name rises letter by letter from behind its baseline. */
.motion .wordmark > [aria-hidden] { display: inline-flex; clip-path: inset(0 -0.1em -0.02em 0); }
.motion .wordmark .ch { display: inline-block; transform: translateY(105%); transition: transform 900ms var(--m-out); transition-delay: calc(450ms + var(--i, 0) * 55ms); animation: m-safe-show 1ms 4s forwards; }
.motion.lit .wordmark .ch { transform: none; }

/* The details settle after the name; the rule above them draws across. */
.motion .hero .flank > *, .motion .hero-foot > * { opacity: 0; transform: translateY(10px); transition: opacity 600ms var(--m-out), transform 600ms var(--m-out); animation: m-safe-show 1ms 4s forwards; }
.motion.lit .hero .flank > * { opacity: 1; transform: none; transition-delay: 1000ms; }
.motion.lit .hero-foot > * { opacity: 1; transform: none; transition-delay: calc(1150ms + var(--i, 0) * 90ms); }
/* The buttons never wait for the show (or for the photo to download): a guest
   who came to book can act from the first frame. */
.motion .hero-foot > .btns { opacity: 1; transform: none; transition: none; animation: none; }
.motion .hero-foot { border-top-color: transparent; position: relative; }
.motion .hero-foot::before { content: ""; position: absolute; left: 0; right: 0; top: -1px; height: 1px; background: var(--rule); transform: scaleX(0); transform-origin: left; transition: transform 1100ms var(--m-draw) 900ms; animation: m-safe-show 1ms 4s forwards; }
.motion.lit .hero-foot::before { transform: none; }
/* "Open now": the saffron dot catches once, like a lamp. */
.motion .open { position: relative; }
.motion .open::after { content: ""; position: absolute; left: 0; top: 50%; width: 7px; height: 7px; margin-top: -3.5px; border-radius: 50%; background: var(--accent); opacity: 0; pointer-events: none; }
.motion.lit .open.is-open::after { animation: m-glow 1200ms var(--m-out) 1700ms 1 both; }
@keyframes m-glow { from { opacity: .6; transform: none; } to { opacity: 0; transform: scale(2.8); } }

/* Back on home in the same session: the lights simply come up (0.5s), with
   nothing held back. The head script adds .quick. */
.motion.quick .hero-photo::before { opacity: .5; transition: opacity 500ms var(--m-out); animation: none; }
.motion.quick.lit .hero-photo::before { opacity: 0; }
.motion.quick .hero-photo img, .motion.quick .wordmark .ch, .motion.quick .hero .flank > *, .motion.quick .hero-foot > * { opacity: 1; transform: none; transition: none; animation: none; }
.motion.quick .hero-foot { border-top-color: var(--rule); }
.motion.quick .hero-foot::before, .motion.quick .open::after { display: none; }

/* Scroll-linked arrivals: each piece moves with the scroll itself, so a fast
   flick reveals it just as fast, scrolling back rewinds it, and anything
   scrolled past is always complete. Ranges are in screen heights, so every
   piece is done by the time it is about 40% of the way up the screen,
   whatever its size. Browsers without scroll-driven
   animation hide nothing. */
@keyframes m-rise { from { transform: translateY(102%); } }
@keyframes m-uncover { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0); } }
@keyframes m-settle { from { transform: scale(1.05); } }
@keyframes m-draw-x { from { transform: scaleX(0); } }
@keyframes m-arrive { from { opacity: 0; transform: translateY(12px); } }
@supports (animation-timeline: view()) {
  /* Headings rise word by word. */
  .motion .rise { view-timeline: --rise block; }
  .motion .rise .w { display: inline-block; clip-path: inset(-0.1em -0.05em 0 -0.05em); vertical-align: top; }
  .motion .rise .w > span {
    display: inline-block; animation: m-rise linear both; animation-timeline: --rise;
    animation-range: cover calc(var(--i, 0) * 2vh) cover calc(26vh + var(--i, 0) * 2vh);
  }
  /* Photos are uncovered like prints from a sleeve. */
  .motion .print {
    overflow: hidden; animation: m-uncover linear both; animation-timeline: view();
    animation-range: cover calc(var(--i, 0) * 3vh) cover calc(36vh + var(--i, 0) * 3vh);
  }
  .motion .print img {
    animation: m-settle linear both; animation-timeline: view();
    animation-range: cover calc(var(--i, 0) * 3vh) cover calc(50vh + var(--i, 0) * 3vh);
  }
  /* Stacked occasion cards each arrive on their own; the stagger is for side by side. */
  @media (max-width: 45em) { .motion .cols4 .print, .motion .cols4 .print img { --i: 0 !important; } }
  /* The bestseller list draws its rules as each dish arrives. */
  .motion .dishes.drawn { border-top-color: transparent; position: relative; view-timeline: --dishes block; }
  .motion .dishes.drawn::before, .motion .dishes.drawn li::after {
    content: ""; position: absolute; left: 0; right: 0; height: 1px; background: var(--rule);
    transform-origin: left; animation: m-draw-x linear both;
  }
  .motion .dishes.drawn::before { top: -1px; animation-timeline: --dishes; animation-range: cover 0vh cover 16vh; }
  .motion .dishes.drawn li { position: relative; border-bottom-color: transparent; view-timeline: --dish block; }
  .motion .dishes.drawn li::after { bottom: -1px; animation-timeline: --dish; animation-range: cover 4vh cover 32vh; }
  .motion .dishes.drawn li > * { animation: m-arrive linear both; animation-timeline: --dish; animation-range: cover 0vh cover 26vh; }
}

/* Reviews: the stars fill one by one while the score counts up. */
.motion .score.counting .stars > * { opacity: 0; transform: scale(.88); transition: opacity 400ms var(--m-out), transform 500ms var(--m-out); transition-delay: calc(var(--i, 0) * 90ms); }
.motion .score.counting.in .stars > * { opacity: 1; transform: none; }

/* ═══ Continuity: page changes, FAQ answers, the menu chip highlight ═══════
   All of this moves only when the visitor hasn't asked for reduced motion. */
.chips.pilled { position: relative; }
.chips.pilled a { position: relative; z-index: 1; }
.chips.pilled a.on { background: transparent; border-color: transparent; }
.chip-pill { position: absolute; left: 0; top: 0; z-index: 0; border-radius: var(--radius); background: var(--fill); pointer-events: none; }
@media (prefers-reduced-motion: no-preference) {
  /* Page changes glide; the header stays put. */
  @view-transition { navigation: auto; }
  .site-head { view-transition-name: site-head; }
  ::view-transition-old(root) { animation: 120ms var(--ease-out) both m-page-out; }
  ::view-transition-new(root) { animation: 200ms var(--ease-out) both m-page-in; }
  ::view-transition-group(site-head) { animation-duration: 200ms; }
  /* FAQ answers slide open and closed. */
  :root { interpolate-size: allow-keywords; }
  .faq details::details-content { height: 0; overflow: clip; transition: height 160ms var(--ease-out), content-visibility 160ms allow-discrete; }
  .faq details[open]::details-content { height: auto; transition-duration: 220ms; }
  /* The chip highlight slides to the current section. */
  .chip-pill { transition: transform 220ms var(--ease-out), width 220ms var(--ease-out), height 220ms var(--ease-out); }
  /* The label changes colour on the highlight's timing, so it is never light on light mid-slide. */
  .chips.pilled a { transition: color 220ms var(--ease-out), border-color 150ms ease, transform 160ms var(--ease-out); }
  .chip-pill.jump { transition: none; }
}
@keyframes m-page-out { to { opacity: 0; } }
@keyframes m-page-in { from { opacity: 0; } }

/* A day at UnBound: in "Find your moment" a saffron line draws with the
   scroll from the first coffee to the last table, lighting each card's
   marker as it passes. Narrower screens draw each card's own rule instead. */
@keyframes m-light { from { background: var(--mark); transform: none; } to { background: var(--saffron); transform: scale(1.35); } }
@supports (animation-timeline: view()) {
  .motion .moments .cols4 { position: relative; view-timeline: --day block; }
  @media (min-width: 60.0625em) {
    .motion .moments .cols4::after {
      content: ""; position: absolute; left: 0; right: 0; top: -1px; height: 2px; background: var(--saffron);
      transform-origin: left; animation: m-draw-x linear both; animation-timeline: --day; animation-range: cover 12vh cover 68vh;
    }
    .motion .moments .cols4 article::after {
      content: ""; position: absolute; top: -4px; left: 0; width: 7px; height: 7px; border-radius: 50%;
      background: var(--mark); animation: m-light linear both; animation-timeline: --day;
      animation-range: cover calc(10vh + var(--i, 0) * 14vh) cover calc(15vh + var(--i, 0) * 14vh);
    }
  }
  @media (max-width: 60em) {
    .motion .moments .cols4 article { view-timeline: --card block; }
    .motion .moments .cols4 article::after {
      content: ""; position: absolute; left: 0; right: 0; top: -1px; height: 2px; background: var(--saffron);
      transform-origin: left; animation: m-draw-x linear both; animation-timeline: --card; animation-range: cover 0vh cover 34vh;
    }
  }
}
