/* ==========================================================================
   Insta.mam — Meze Bar, Λαγκαδίκια
   Design system implementation. Tokens first, then components.
   Dark-committed: the brand mark is midnight navy, the room is low-lit.
   ========================================================================== */

/* --- Fonts -----------------------------------------------------------------
   Both faces carry native Greek glyphs (verified against Google Fonts subsets).
   GFS Didot is by the Greek Font Society — Greek is the design, not an add-on.
   Commissioner is a variable humanist sans with a full Greek set.
   -------------------------------------------------------------------------- */
/* Fonts are linked from the HTML <head>, not @import-ed here.
   An @import cannot be discovered until this file has been fetched
   AND parsed, which serialises the font request behind the CSS —
   a whole extra round-trip on mobile data before any text can paint. */

/* ==========================================================================
   TOKENS
   ========================================================================== */
:root {
  /* Colour — every functional pair contrast-verified. Ratios in comments. */
  --bg:            #0F1623;  /* midnight navy, from the wordmark plate        */
  --bg-deep:       #0A0F19;  /* footer, overlays                              */
  --surface:       #161E2E;  /* cards                                         */
  --surface-hi:    #1D273A;  /* raised / hover                                */

  --text:          #F4F6FA;  /* 16.74:1 on --bg                               */
  --muted:         #AEB6C4;  /*  8.87:1 on --bg                               */
  --muted-dim:     #8E97A8;  /*  6.16:1 on --bg                               */

  --red:           #D9243C;  /*  3.68:1 — fills & rules only, NOT small text  */
  --red-deep:      #C0182E;  /*  white on it = 5.69:1                         */
  --red-text:      #F06A7E;  /*  6.10:1 — use when red must BE text           */

  --oak:           #C79A6B;  /*  7.13:1 — safe as text                        */
  --oak-hi:        #D9B48A;  /*  9.36:1                                       */

  --line:          #232E42;  /* decorative dividers only                      */
  --line-strong:   #5A6B85;  /*  3.34:1 — input borders, real boundaries      */

  --on-red:        #FFFFFF;  /*  4.92:1 on --red                              */

  /* Type */
  --font-display: 'GFS Didot', 'Didot', 'Times New Roman', serif;
  --font-body:    'Commissioner', system-ui, -apple-system, 'Segoe UI', sans-serif;

  --fs-display: clamp(2.75rem, 9vw, 6.5rem);
  --fs-h1:      clamp(2rem, 5vw, 3.25rem);
  --fs-h2:      clamp(1.5rem, 3.2vw, 2.125rem);
  --fs-h3:      clamp(1.15rem, 2vw, 1.375rem);
  --fs-lead:    clamp(1.1875rem, 1.9vw, 1.5rem);
  --fs-sub:     clamp(1.75rem, 3.4vw, 2.5rem);
  --fs-body:    1.0625rem;
  --fs-sm:      0.875rem;
  --fs-eyebrow: 0.875rem;   /* alias of --fs-sm: there are no tiny labels any more */

  /* Space — 4px base */
  --s1: 4px;   --s2: 8px;   --s3: 12px;  --s4: 16px;  --s5: 24px;
  --s6: 32px;  --s7: 48px;  --s8: 64px;  --s9: 96px;  --s10: 128px;

  --gutter: 20px;
  --container: 1180px;
  --radius: 3px;
  --radius-card: 5px;

  /* Motion — mirrors motion.csv rows 5 / 8 / 13 */
  --dur-fast:   180ms;
  --dur-base:   320ms;
  --dur-reveal: 520ms;
  --dur-exit:   220ms;
  --ease-out:  cubic-bezier(0.215, 0.61, 0.355, 1); /* ≈ power2.out */
  --ease-soft: cubic-bezier(0.33, 1, 0.68, 1);

  --header-h: 68px;
  color-scheme: dark;
}

@media (min-width: 768px) { :root { --gutter: 32px; --header-h: 76px; } }
@media (min-width: 1024px){ :root { --gutter: 48px; } }

/* Small-phone overrides live at the END of this file — see "SMALL PHONES".
   A media query adds no specificity, so placing them here would lose to the
   component rules defined further down. */

/* ==========================================================================
   RESET
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: rgba(199, 154, 107, 0.18);
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: 350;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img, picture, svg, video { display: block; max-width: 100%; height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }

/* Anchor targets must clear the sticky header — WCAG 2.2 focus-not-obscured */
section[id] { scroll-margin-top: calc(var(--header-h) + 16px); }

/* ==========================================================================
   FOCUS — never removed, visible on every interactive element
   ========================================================================== */
:focus-visible {
  outline: 2px solid var(--oak);
  outline-offset: 3px;
  border-radius: 2px;
}
:focus:not(:focus-visible) { outline: none; }

.skip-link {
  position: absolute; top: -100px; left: var(--gutter); z-index: 200;
  background: var(--oak); color: var(--bg-deep);
  padding: var(--s3) var(--s5); border-radius: var(--radius);
  font-weight: 600; font-size: var(--fs-sm);
  transition: top var(--dur-fast) var(--ease-out);
}
.skip-link:focus { top: var(--s3); }

/* ==========================================================================
   PRIMITIVES
   ========================================================================== */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--s9); position: relative; }
@media (min-width: 768px) { .section { padding-block: 104px; } }
.section--sunk { background: var(--bg-deep); }

h1, h2, h3 { font-weight: 400; line-height: 1.15; text-wrap: balance; }
h1 { font-family: var(--font-display); font-size: var(--fs-h1); }
h2 { font-family: var(--font-display); font-size: var(--fs-h1); }
h3 { font-family: var(--font-body); font-size: var(--fs-h3); font-weight: 500; line-height: 1.3; }

.lead {
  font-size: var(--fs-lead);
  color: var(--text);
  max-width: 62ch;
  font-weight: 300;
}
p { max-width: 68ch; text-wrap: pretty; }

/* --- Buttons --------------------------------------------------------------- */
.btn {
  --btn-bg: var(--surface-hi);
  --btn-fg: var(--text);
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--s2);
  min-height: 48px;                     /* ≥44px touch target */
  padding: var(--s3) var(--s6);
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 0;
  border-radius: var(--radius);
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
  touch-action: manipulation;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }

.btn--primary { --btn-bg: var(--red); --btn-fg: var(--on-red); }
.btn--primary:hover { --btn-bg: var(--red-deep); }

.btn--ghost:hover { --btn-bg: var(--line); --btn-fg: var(--oak-hi); }

.btn[disabled] { opacity: 0.45; cursor: not-allowed; transform: none; }

/* ==========================================================================
   HEADER
   ========================================================================== */
.header {
  position: fixed; inset: 0 0 auto 0; z-index: 100;
  height: var(--header-h);
  display: flex; align-items: center;
  background: transparent;
  transition: background var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}
/* Slides away while reading down, returns on the first scroll up (main.js). */
.header.is-hidden { transform: translateY(-100%); }
/* Over the hero the header is transparent, so nav text sits directly on the
   photograph. The room's ceiling is near-white and drove nav contrast down to
   2.5:1 — this gradient guarantees a dark ground for the top bar whatever the
   image behind it. It fades out once the header gets its own solid background. */
.header::before {
  content: '';
  position: absolute; inset: 0 0 auto 0; height: 168px;
  background: linear-gradient(to bottom, /* taste-skill-ignore: legibility scrim over the hero photo */
    rgba(8, 12, 20, 0.94) 0%,
    rgba(8, 12, 20, 0.72) 42%,
    rgba(8, 12, 20, 0.30) 74%,
    transparent 100%);
  pointer-events: none;
  z-index: -1;
  transition: opacity var(--dur-base) var(--ease-out);
}
.header.is-stuck::before { opacity: 0; }

/* A plain bar once it leaves the hero: one tone darker than the page, no
   blur, no rule. */
.header.is-stuck { background: var(--bg-deep); }
.header__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s5); width: 100%;
}

.brand { display: flex; align-items: center; gap: var(--s3); flex: none; min-height: 44px; }
.brand__mark { height: 32px; width: auto; }
@media (min-width: 768px) { .brand__mark { height: 40px; } }
/* Typographic fallback shown only until the real logo file is dropped in */
.brand__text {
  font-family: var(--font-display);
  font-size: 1.4rem; letter-spacing: 0.01em; line-height: 1;
}
.brand__text b { font-weight: 400; }
.brand__text i { color: var(--red-text); font-style: normal; }

.nav { display: none; }
@media (min-width: 1024px) {
  .nav { display: flex; align-items: center; gap: var(--s6); }
}
.nav a {
  font-size: var(--fs-sm); font-weight: 400; color: var(--muted);
  letter-spacing: 0.04em;
  position: relative;
  display: inline-flex; align-items: center; min-height: 44px;
  transition: color var(--dur-fast) var(--ease-out);
}
/* Anchored to the text, not the 44px hit area, or it floats well below it. */
.nav a::after {
  content: ''; position: absolute; left: 0; right: 100%; bottom: 10px; height: 2px;
  background: var(--red);
  transition: right var(--dur-base) var(--ease-out);
}
.nav a:hover, .nav a[aria-current="true"] { color: var(--text); }
.nav a:hover::after, .nav a[aria-current="true"]::after { right: 0; }

.header__actions { display: flex; align-items: center; gap: var(--s3); flex: none; }

.lang {
  display: flex; align-items: center; gap: 2px;
  background: var(--surface); border-radius: var(--radius);
  padding: 2px;
}
.lang a {
  min-width: 44px; min-height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: var(--fs-sm); font-weight: 600; letter-spacing: 0.02em;
  color: var(--muted); border-radius: 2px;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.lang a:hover { color: var(--text); }
.lang a[aria-current="page"] { background: var(--surface-hi); color: var(--oak-hi); }

.header .btn { display: none; }
@media (min-width: 640px) { .header .btn { display: inline-flex; min-height: 42px; padding-inline: var(--s5); } }

/* Mobile menu toggle */
.burger {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  background: var(--surface); border: 0; border-radius: var(--radius);
  cursor: pointer;
}
@media (min-width: 1024px) { .burger { display: none; } }
.burger span {
  display: block; width: 18px; height: 1.5px; background: var(--text);
  position: relative; transition: background var(--dur-fast) var(--ease-out);
}
.burger span::before, .burger span::after {
  content: ''; position: absolute; left: 0; width: 18px; height: 1.5px; background: var(--text);
  transition: transform var(--dur-base) var(--ease-out), top var(--dur-base) var(--ease-out);
}
.burger span::before { top: -6px; }
.burger span::after  { top: 6px; }
.burger[aria-expanded="true"] span { background: transparent; }
.burger[aria-expanded="true"] span::before { top: 0; transform: rotate(45deg); }
.burger[aria-expanded="true"] span::after  { top: 0; transform: rotate(-45deg); }

/* Mobile drawer */
.drawer {
  position: fixed; inset: var(--header-h) 0 auto 0; z-index: 99;
  background: var(--bg-deep);
  overscroll-behavior: contain;
  padding: var(--s5) 0 var(--s7);
  display: grid; gap: var(--s1);
  transform-origin: top;
  transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out),
              visibility var(--dur-base);
}
.drawer[hidden] { display: grid; opacity: 0; visibility: hidden; transform: translateY(-8px); pointer-events: none; }
.drawer:not([hidden]) { opacity: 1; visibility: visible; transform: translateY(0); }
@media (min-width: 1024px) { .drawer { display: none !important; } }
.drawer a {
  padding: var(--s4) var(--gutter);
  font-size: var(--fs-body); color: var(--muted);
  border-left: 2px solid transparent;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out),
              background var(--dur-fast) var(--ease-out);
}
.drawer a:hover, .drawer a:focus-visible { color: var(--text); border-left-color: var(--red); background: rgba(255,255,255,0.03); }
.drawer .btn { margin: var(--s4) var(--gutter) 0; }

/* ==========================================================================
   HERO
   ========================================================================== */
.hero {
  position: relative;
  min-height: 100dvh;                    /* never 100vh — mobile chrome */
  display: grid; align-items: end;
  overflow: hidden;
  isolation: isolate;
}
.hero__media {
  position: absolute; inset: 0; z-index: -2;
  overflow: hidden;
}
/* <picture> is an inline wrapper with height:auto by default. Without this
   rule the img's `height: 100%` resolves against the PICTURE rather than
   .hero__media, the box ends up matching the photo's own aspect ratio, and
   `object-fit: cover` silently never engages — you just see the top of the
   image. The wrapper has to carry the size through. */
.hero__media picture {
  display: block;
  width: 100%;
  height: 100%;
}
.hero__media img {
  /* The room shot is portrait (4:5). On a wide screen `cover` keeps the width
     and crops vertically, so bias the visible band downward — the ceiling is
     the top third and the bar is what's worth showing. */
  width: 100%; height: 100%; object-fit: cover; object-position: center 62%;
  transform: scale(1.06);
  animation: heroSettle 1400ms var(--ease-soft) forwards;
}
@keyframes heroSettle { to { transform: scale(1); } }

.hero__scrim {
  position: absolute; inset: 0; z-index: -1;
  /* Neutral black, not a tint: it darkens the photograph and holds the
     text whatever colour the scroll palette is at. */
  background: linear-gradient(to top, /* taste-skill-ignore: legibility scrim over the hero photo */
    rgba(8, 8, 8, 0.92) 0%, rgba(8, 8, 8, 0.78) 30%,
    rgba(8, 8, 8, 0.42) 62%, rgba(8, 8, 8, 0.5) 100%);
}
/* Desktop: the copy sits left and the bar sits right, so the shade is heavy
   behind the text and nearly gone over the bottles. */
@media (min-width: 860px) {
  .hero__scrim {
    background:
      linear-gradient(to right, /* taste-skill-ignore: legibility scrim */
        rgba(8, 8, 8, 0.9) 0%, rgba(8, 8, 8, 0.72) 30%,
        rgba(8, 8, 8, 0.3) 62%, rgba(8, 8, 8, 0.06) 100%),
      linear-gradient(to top, /* taste-skill-ignore: legibility scrim */
        rgba(8, 8, 8, 0.66) 0%, rgba(8, 8, 8, 0.08) 42%, rgba(8, 8, 8, 0.22) 100%);
  }
}
/* A light warm grade on the photograph itself — subtle, but it stops the
   image reading as a raw phone snapshot dropped into a designed page. */
.hero__media::after {
  content: ''; position: absolute; inset: 0;
  background: var(--bg);
  mix-blend-mode: color;
  opacity: 0.22;
  pointer-events: none;
}
.hero__media img { filter: contrast(1.06) saturate(0.92); }

.hero__inner { padding-block: var(--s9) var(--s8); position: relative; }
@media (min-width: 768px) { .hero__inner { padding-block: var(--s10) var(--s9); } }

.hero__mark { width: min(78vw, 460px); height: auto; margin-bottom: var(--s5); }
.hero__wordmark {
  font-family: var(--font-display);
  font-size: var(--fs-display);
  line-height: 0.95;
  letter-spacing: -0.01em;
  margin-bottom: var(--s3);
}
.hero__wordmark i { color: var(--red-text); font-style: normal; }
/* Where it is and whether it is open right now. Stacked on phones, so a
   wrap never strands the separator; one line from tablet up. */
.hero__meta {
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--s1);
  font-size: var(--fs-body); color: var(--text);
  margin-bottom: var(--s7);
}
@media (min-width: 768px) {
  .hero__meta { flex-direction: row; align-items: baseline; gap: var(--s3); }
  .hero__status:not([hidden])::before { content: "·"; color: var(--muted); margin-right: var(--s3); }
}
.hero__tag {
  font-size: var(--fs-lead);
  font-weight: 300; color: var(--text); max-width: 24ch;
  line-height: 1.35; margin-bottom: var(--s4);
}
.hero__cta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s3) var(--s5); }

/* ==========================================================================
   STORY
   ========================================================================== */
.story__grid {
  display: grid; gap: var(--s7);
  grid-template-columns: 1fr;
  align-items: center;
}
@media (min-width: 900px) {
  .story__grid { grid-template-columns: 1fr 1fr; gap: var(--s9); }
}
.story__copy p + p { margin-top: var(--s5); }
.story__copy .lead { margin-bottom: var(--s5); }

.story__figure { position: relative; }
/* Stacked (tablet and phone), the drawing would run the full width and fill
   a screen and a half; keep it the size it is beside the text. */
@media (max-width: 899px) { .story__figure { max-width: 440px; } }
.story__figure img {
  /* The coffee illustration is drawn at exactly this 3:4.4 shape, so `cover`
     never crops it. */
  width: 100%; aspect-ratio: 3 / 4.4; object-fit: cover;
  object-position: center;
  border-radius: var(--radius-card);
  filter: contrast(1.05) saturate(0.94);
}

/* ==========================================================================
   DAY ARC — the whole premise of the place in one line:
   coffee in the morning, drinks at two in the morning. The rail is the same
   warm→cool journey the page background makes as you scroll.
   ========================================================================== */
/* Full section width, not tucked into the text column — this line is the
   premise of the business, so it gets to be a feature rather than a footnote. */
.dayarc {
  list-style: none; margin: var(--s9) 0 0;
  padding: var(--s6) var(--s5);
  background: var(--surface); border-radius: var(--radius-card);
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: var(--s6) var(--s5);
}
@media (min-width: 700px) { .dayarc { grid-template-columns: repeat(4, 1fr); padding: var(--s7); } }

.dayarc__step { display: grid; gap: var(--s1); align-content: start; }
.dayarc__when { font-size: var(--fs-body); color: var(--muted); }
.dayarc__what {
  font-family: var(--font-display);
  font-size: var(--fs-sub);
  line-height: 1.1; color: var(--text);
}
/* The step the bar is in right now (main.js marks it, only while open). */
.dayarc__step[aria-current] .dayarc__what { color: var(--oak-hi); }
.dayarc__now {
  justify-self: start; margin-top: var(--s2);
  display: inline-flex; align-items: center; gap: var(--s2);
  font-size: var(--fs-sm); color: #7FBF8A;
}
.dayarc__now::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%; background: currentColor;
  animation: pulse 2.4s ease-in-out infinite;
}
/* ==========================================================================
   MENU
   ========================================================================== */
.menu__head {
  display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between;
  gap: var(--s5); margin-bottom: var(--s7);
}

.tabs {
  display: flex; gap: var(--s2);
  overflow-x: auto; scrollbar-width: none;
  border-bottom: 1px solid var(--line); /* taste-skill-ignore: tab rail of the (hidden) menu */
  margin-bottom: var(--s7);
  padding-bottom: 1px;
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
  flex: none;
  min-height: 46px; padding: var(--s3) var(--s5);
  background: none; border: none; border-bottom: 2px solid transparent;
  color: var(--muted-dim); cursor: pointer;
  font-size: var(--fs-sm); font-weight: 500; letter-spacing: 0.05em;
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
  touch-action: manipulation;
}
.tab:hover { color: var(--text); }
.tab[aria-selected="true"] { color: var(--oak-hi); border-bottom-color: var(--red); }

.menu__panel[hidden] { display: none; }
.menu__list { display: grid; gap: 0; grid-template-columns: 1fr; }
@media (min-width: 860px) { .menu__list { grid-template-columns: 1fr 1fr; column-gap: var(--s9); } }

.dish {
  display: grid; grid-template-columns: 1fr auto; gap: var(--s3) var(--s4);
  align-items: baseline;
  padding-block: var(--s4);
  border-bottom: 1px solid var(--line); /* taste-skill-ignore: price list rows, read like a table */
}
.dish__name { font-size: 1.0625rem; font-weight: 500; color: var(--text); }
.dish__desc {
  grid-column: 1 / -1; font-size: var(--fs-sm); color: var(--muted-dim);
  margin-top: calc(var(--s1) * -1); max-width: 52ch;
}
.dish__price {
  font-variant-numeric: tabular-nums;      /* prices never jitter */
  font-size: 1.0625rem; color: var(--oak-hi); font-weight: 500;
  white-space: nowrap;
}

.menu__fallback {
  padding: var(--s6); border: 1px dashed var(--line-strong);
  border-radius: var(--radius-card); color: var(--muted); text-align: center;
}

/* Menu arrives from JSON, so reserve height to stop the section collapsing
   and then snapping open once it loads (layout shift). */
#menu-mount { min-height: 420px; }

.menu__note {
  margin-top: var(--s7); padding: var(--s5);
  border: 1px dashed var(--line-strong); border-radius: var(--radius-card);
  color: var(--muted); font-size: var(--fs-sm);
  display: flex; gap: var(--s4); align-items: flex-start;
}
.menu__note svg { flex: none; color: var(--oak); margin-top: 2px; }

/* ==========================================================================
   GALLERY
   ========================================================================== */
.gallery {
  display: grid; gap: var(--s3);
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 768px) { .gallery { grid-template-columns: repeat(4, 1fr); gap: var(--s4); } }

.shot {
  position: relative; overflow: hidden; border-radius: var(--radius-card);
  background: var(--surface);
  aspect-ratio: 1 / 1;
  cursor: pointer; border: none; padding: 0;
  display: block; width: 100%;
}
.shot:nth-child(1) { grid-column: span 2; aspect-ratio: 1 / 1; }
@media (min-width: 768px) {
  .shot:nth-child(1) { grid-column: span 2; grid-row: span 2; aspect-ratio: 1 / 1; }
}
.shot img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform var(--dur-base) var(--ease-out), filter var(--dur-base) var(--ease-out);
}
.shot:hover img, .shot:focus-visible img { transform: scale(1.05); }
/* Lightbox
   `display: grid` below is an author rule, and author rules beat the browser's
   built-in `dialog:not([open]) { display: none }`. Without the guard on the
   next line the CLOSED dialog stays laid out — a full-viewport, z-index 300,
   pointer-events:auto sheet over the whole page that swallows every click.
   It is invisible in a DOM dump and fatal in a real browser. Keep this rule. */
.lightbox:not([open]) { display: none; }

.lightbox {
  position: fixed; inset: 0; z-index: 300;
  width: 100%; max-width: 100%; height: 100%; max-height: 100%;
  background: rgba(6, 9, 15, 0.96);
  overscroll-behavior: contain;
  display: grid; place-items: center; padding: var(--s7) var(--s5);
  border: none; overflow: hidden;
}
.lightbox::backdrop { background: rgba(6, 9, 15, 0.95); }
.lightbox[open] { animation: lbFade 240ms var(--ease-out); }
@keyframes lbFade { from { opacity: 0; } to { opacity: 1; } }

.lightbox__img {
  max-width: min(100%, 1100px); max-height: 78dvh;
  border-radius: var(--radius-card);
  box-shadow: 0 24px 70px rgba(0,0,0,0.6); /* taste-skill-ignore: floats in the photo viewer dialog */
}
@keyframes lbInNext { from { opacity: 0; transform: translateX(26px); } to { opacity: 1; transform: none; } }
@keyframes lbInPrev { from { opacity: 0; transform: translateX(-26px); } to { opacity: 1; transform: none; } }

.lightbox__close {
  position: absolute; top: var(--s4); right: var(--s4);
  width: 48px; height: 48px; border-radius: 50%;
  background: var(--surface); border: 0;
  color: var(--text); cursor: pointer;
  display: grid; place-items: center; z-index: 2;
  transition: background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.lightbox__close:hover { background: var(--surface-hi); color: var(--oak-hi); }

.lightbox__nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 52px; height: 52px; border-radius: 50%;
  background: var(--surface); border: 0;
  color: var(--text); cursor: pointer; z-index: 2;
  display: grid; place-items: center;
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              opacity var(--dur-fast) var(--ease-out);
}
.lightbox__nav:hover { background: var(--surface-hi); color: var(--oak-hi); }
.lightbox__nav[hidden] { display: none; }
.lightbox__nav--prev { left: var(--s4); }
.lightbox__nav--next { right: var(--s4); }
@media (min-width: 768px) {
  .lightbox__nav--prev { left: var(--s6); }
  .lightbox__nav--next { right: var(--s6); }
}

.lightbox__bar {
  position: absolute; left: 0; right: 0; bottom: var(--s5);
  display: flex; flex-direction: column; align-items: center; gap: var(--s2);
  padding-inline: 84px; text-align: center; pointer-events: none;
}
.lightbox__caption { color: var(--muted); font-size: var(--fs-sm); max-width: 60ch; }
.lightbox__count {
  color: var(--oak-hi); font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   SCROLL PROGRESS
   ========================================================================== */
.progress {
  position: fixed; top: 0; left: 0; right: 0; height: 2px;
  z-index: 150; pointer-events: none; background: transparent;
}
.progress__bar {
  height: 100%; width: 100%;
  background: var(--red);
  transform: scaleX(0); transform-origin: 0 50%;
}

/* ==========================================================================
   HERO HEADLINE WIPE
   ========================================================================== */
.wipe__line { display: block; overflow: hidden; }
.wipe__inner {
  display: block;
  transform: translateY(105%);
  animation: wipeUp 900ms var(--ease-soft) forwards;
}
@keyframes wipeUp { to { transform: translateY(0); } }

/* ==========================================================================
   EVENTS
   ========================================================================== */
/* The party table, drawn, beside the kinds of party. On a phone the drawing
   sits between the intro and the list; from 960px it holds the left column,
   centred against the text, and scrolls with the page like everything else. */
.events__layout { display: grid; gap: var(--s7); }
.events__head { max-width: 62ch; }
.events__head h2 { margin-bottom: var(--s4); }
.events__figure { max-width: 440px; }
.events__figure img { width: 100%; height: auto; border-radius: var(--radius-card); }
@media (min-width: 960px) {
  .events__layout {
    grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
    grid-template-areas: "fig head" "fig list" "fig cta";
    grid-template-rows: auto auto 1fr;
    column-gap: var(--s9); row-gap: var(--s7);
    align-items: start;
  }
  .events__head   { grid-area: head; }
  .occasions      { grid-area: list; }
  .events__cta    { grid-area: cta; }
  .events__figure { grid-area: fig; max-width: none; align-self: center; }
}

/* The three kinds of party: the name large, what it involves right under it. */
.occasions { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s6); }
.occasion { display: grid; gap: var(--s2); }
.occasion__name {
  font-family: var(--font-display); font-weight: 400;
  font-size: var(--fs-sub);
  line-height: 1.1; letter-spacing: -0.01em;
}
.occasion p { font-size: var(--fs-body); max-width: 46ch; }

.events__cta {
  padding: var(--s6);
  border-radius: var(--radius-card);
  background: var(--surface);
  display: grid; gap: var(--s5);
}
.events__cta p {
  font-family: var(--font-display); font-size: var(--fs-lead);
  line-height: 1.25; max-width: 30ch;
}
.events__actions { display: flex; flex-wrap: wrap; gap: var(--s3); }

/* ==========================================================================
   VISIT
   ========================================================================== */
.visit__grid { display: grid; gap: var(--s8); grid-template-columns: 1fr; }
@media (min-width: 900px) { .visit__grid { grid-template-columns: 0.85fr 1.15fr; gap: var(--s9); } }

.info { display: grid; gap: var(--s6); }
.info__block h3 { margin-bottom: var(--s3); }
.info__row {
  display: flex; gap: var(--s4); align-items: flex-start;
  padding-block: var(--s2);
}
.info__row svg { flex: none; color: var(--oak); margin-top: 3px; }
.info__row a {
  display: inline-flex; align-items: center; min-height: 44px;  /* tap target */
  text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 4px;
  transition: text-decoration-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.info__row a:hover { color: var(--oak-hi); text-decoration-color: var(--oak); }
/* The icon sits beside a 44px-tall link — line it up with the text, not the top */
.info__row:has(a) svg { margin-top: 12px; }

.hours { width: 100%; border-collapse: collapse; }
.hours th, .hours td { text-align: left; padding: var(--s3) 0; border-bottom: 1px solid var(--line); font-weight: 400; }
.hours th { color: var(--muted); font-weight: 400; }
.hours td { text-align: right; font-variant-numeric: tabular-nums; color: var(--text); }
.hours tr[data-today] th { color: var(--oak-hi); font-weight: 600; }
.hours tr[data-today] td { color: var(--oak-hi); font-weight: 600; }

/* --- Map -------------------------------------------------------------------
   Drawn from OpenStreetMap data (tools/build_map.py → assets/img/map.svg), not
   embedded from Google: no third-party request, no cookies, CSP stays 'self'.
   The SVG layers carry no colours; each <use> below paints its layer from the
   palette tokens, so the map follows the day→night journey like everything
   else. The café sits at the exact centre of the drawing, and `slice` keeps
   the centre fixed at any aspect ratio, so the pin is simply placed at 50/50.
   The "Directions" link stretches over the whole card (::after). */
.map {
  --map-zoom: 1;
  position: relative; border-radius: var(--radius-card); overflow: hidden;
  min-height: 380px; background: var(--surface);
  display: grid; grid-template: 1fr / 1fr;
  isolation: isolate;
}

.map__art {
  position: absolute; inset: 0; z-index: -1; width: 100%; height: 100%;
  transform: scale(var(--map-zoom));
  transition: transform 900ms var(--ease-out), opacity 900ms var(--ease-out);
}
.map__land      { fill: color-mix(in srgb, var(--oak) 7%, transparent); }
.map__water     { fill: none; stroke: color-mix(in srgb, var(--muted) 30%, transparent); stroke-width: 3; }
.map__buildings { fill: color-mix(in srgb, var(--line-strong) 34%, var(--surface)); }
.map__tracks,
.map__minor,
.map__major,
.map__trunk     { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.map__tracks    { stroke: color-mix(in srgb, var(--line-strong) 55%, transparent); stroke-width: 2; stroke-dasharray: 6 7; }
.map__minor     { stroke: color-mix(in srgb, var(--line-strong) 80%, var(--surface)); stroke-width: 5; }
.map__major     { stroke: color-mix(in srgb, var(--oak) 78%, var(--surface)); stroke-width: 10; }
.map__trunk     { stroke: color-mix(in srgb, var(--muted-dim) 62%, var(--surface)); stroke-width: 13; }
.map__labels {
  fill: var(--muted); font-family: var(--font-body); font-size: 21px; letter-spacing: 0.04em;
  stroke: var(--surface); stroke-width: 6px; stroke-linejoin: round; paint-order: stroke;
}
/* Phones see the drawing at ~0.5px per unit, so labels get a size bump to
   stay legible (~12px on screen). */
@media (max-width: 599px) {
  .map { --map-zoom: 1.3; }
  .map__labels { font-size: 24px; }
}

.map__pin {
  position: absolute; left: 50%; top: 50%; width: 0; height: 0;
  pointer-events: none; z-index: 1;
}
.map__dot,
.map__pulse {
  position: absolute; left: -9px; top: -9px; width: 18px; height: 18px; border-radius: 50%;
}
.map__dot {
  background: var(--red); border: 3px solid var(--text);
}
.map__pulse { background: var(--red); opacity: 0; animation: map-pulse 2.8s var(--ease-out) 1.6s infinite; }
@keyframes map-pulse {
  0%   { transform: scale(1);   opacity: 0.55; }
  80%  { transform: scale(3.4); opacity: 0; }
  100% { transform: scale(3.4); opacity: 0; }
}

.map__card {
  position: absolute; left: 50%; top: 50%; z-index: 1;
  transform: translate(-50%, calc(-100% - 22px));
  display: grid; gap: 2px; text-align: center; white-space: nowrap;
  padding: var(--s2) var(--s4);
  background: var(--bg-deep); border-radius: var(--radius-card);
  pointer-events: none;
  transition: opacity 600ms var(--ease-out), transform 600ms var(--ease-out);
}
.map__card strong { font-family: var(--font-display); font-size: var(--fs-lead); font-weight: 400; color: var(--oak-hi); line-height: 1.1; }
.map__card span { font-size: var(--fs-sm); color: var(--muted); }

.map__cta {
  align-self: end; justify-self: start; margin: var(--s4);
  display: inline-flex; align-items: center; gap: var(--s2);
  min-height: 44px; padding: 0 var(--s4);
  font-size: var(--fs-sm); font-weight: 600; color: var(--text); text-decoration: none;
  background: var(--bg-deep); border-radius: var(--radius);
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.map__cta::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.map__cta svg { transition: transform var(--dur-fast) var(--ease-out); }
.map:hover .map__cta,
.map__cta:focus-visible { background: var(--surface-hi); color: var(--oak-hi); }
.map:hover .map__cta svg { transform: translate(2px, -2px); }
.map:hover .map__art { transform: scale(calc(var(--map-zoom) * 1.03)); }

.map__credit {
  position: absolute; right: 0; bottom: 0; z-index: 2;
  display: inline-flex; align-items: center; min-height: 24px; padding: 0 var(--s2);
  font-size: var(--fs-sm); color: var(--muted); text-decoration: none;
  background: var(--bg-deep);
  border-top-left-radius: var(--radius);
}
.map__credit:hover { color: var(--text); }

/* Entrance: the drawing settles in, then the pin drops and the card follows.
   Only applies once main.js has marked the card .reveal, so with no JS the
   map is simply there. Reduced motion collapses all of it (global rule). */
.map.reveal .map__art  { opacity: 0; transform: scale(calc(var(--map-zoom) * 1.1)); }
.map.reveal .map__pin  { opacity: 0; transform: translateY(-36px); }
.map.reveal .map__card { opacity: 0; transform: translate(-50%, calc(-100% - 10px)); }
.map.reveal.is-in .map__art  { opacity: 1; transform: scale(var(--map-zoom)); transition-duration: 1600ms; }
.map.reveal.is-in .map__pin  { opacity: 1; transform: none; transition: opacity 300ms linear 700ms, transform 700ms cubic-bezier(0.34, 1.56, 0.64, 1) 700ms; }
.map.reveal.is-in .map__card { opacity: 1; transform: translate(-50%, calc(-100% - 22px)); transition-delay: 1100ms; }
.map.reveal.is-in:hover .map__art { transform: scale(calc(var(--map-zoom) * 1.03)); transition-duration: 900ms; }

/* ==========================================================================
   RESERVE — by phone or Instagram
   The booking form was removed: requests landed in the database but nothing
   told the shop, so a guest could book and never hear back. Three large tap
   targets instead — the phones open the dialler, Instagram the profile.
   ========================================================================== */
/* The phone number IS the booking, so it is set as the biggest thing in the
   section: one tap on a phone dials it. */
.reserve { display: grid; gap: var(--s5); justify-items: start; }
.reserve__lead { max-width: 52ch; font-size: var(--fs-lead); }
.reserve__number {
  font-family: var(--font-display);
  font-size: var(--fs-display);
  line-height: 1; letter-spacing: -0.02em;
  color: var(--oak-hi);
  padding-block: var(--s3);
  text-decoration: underline; text-decoration-color: transparent;
  text-decoration-thickness: 3px; text-underline-offset: 0.14em;
  transition: color var(--dur-fast) var(--ease-out), text-decoration-color var(--dur-base) var(--ease-out);
}
.reserve__number:hover { color: var(--text); text-decoration-color: var(--red); }
.reserve__alt { max-width: 60ch; line-height: 1.9; }
.reserve__alt a {
  color: var(--oak-hi); text-decoration: underline; text-underline-offset: 4px;
  padding-block: 10px;   /* inline links: a bigger hit area, same line */
}
.reserve__alt a:hover { color: var(--text); }

/* ==========================================================================
   FOOTER
   ========================================================================== */
.footer { background: var(--bg-deep); padding-block: var(--s9) var(--s6); overflow: hidden; }
/* The name returns at full width as the close of the page. */
.footer__name {
  font-family: var(--font-display); font-weight: 400;
  font-size: clamp(4rem, 20vw, 14.5rem);
  line-height: 0.9; letter-spacing: -0.03em;
  max-width: none; white-space: nowrap;
  margin-bottom: var(--s8);
}
.footer__name i { font-style: normal; color: var(--red-text); }
.footer__cols { display: grid; gap: var(--s6); grid-template-columns: 1fr; }
@media (min-width: 640px)  { .footer__cols { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .footer__cols { grid-template-columns: 1.4fr 1fr 1fr 1fr; } }
.footer__list { list-style: none; margin: 0; padding: 0; display: grid; align-content: start; }
.footer__list a {
  display: inline-flex; align-items: center; min-height: 40px;
  text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 4px;
  transition: color var(--dur-fast) var(--ease-out), text-decoration-color var(--dur-fast) var(--ease-out);
}
.footer__list a:hover { color: var(--oak-hi); text-decoration-color: var(--oak); }
.footer__base { margin-top: var(--s8); font-size: var(--fs-sm); color: var(--muted); max-width: none; }

/* ==========================================================================
   REVEAL — final state is the DEFAULT. The .reveal class removes it.
   If JS never runs, the page is fully readable. No invisible content.
   ========================================================================== */
.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity var(--dur-reveal) var(--ease-out),
              transform var(--dur-reveal) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}
.reveal.is-in { opacity: 1; transform: none; }
.reveal.is-in { will-change: auto; }

/* Parallax — decorative layers only, never text or controls */
.parallax { will-change: transform; }

/* ==========================================================================
   REDUCED MOTION — vestibular motion off, feedback retained
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .reveal { opacity: 1 !important; transform: none !important; }
  /* The wipe is JS-gated too, but if the preference flips after load these
     lines must still resolve to readable text rather than sit off-screen. */
  .wipe__inner { transform: none !important; animation: none !important; }
  .words-ready .w i { transform: none !important; }
  .words-ready .w { overflow: visible; }
  .cursor, .cursor__dot { display: none !important; }
  .lightbox[open], .lightbox__img { animation: none !important; }
  .hero__media img { animation: none; transform: scale(1); }
  .dayarc__now::before { animation: none; }
  .parallax { transform: none !important; }
  /* Colour feedback is deliberately preserved below */
  .btn { transition: background 120ms linear, color 120ms linear !important; }
  .btn:hover { transform: none; }
}

/* ==========================================================================
   ATMOSPHERE — decorative layer, see atmosphere.js
   ========================================================================== */

/* The palette travels warm→cold on scroll, so the background must not snap
   between the JS writes. Only paint properties transition, never layout. */
.has-journey body,
.has-journey .section--sunk,
.has-journey .footer,
.has-journey .dayarc,
.has-journey .events__cta,
.has-journey .map {
  transition: background-color 420ms linear, border-color 420ms linear;
}

/* --- Cursor --------------------------------------------------------------- */
.cursor, .cursor__dot {
  position: fixed; top: 0; left: 0; z-index: 500;
  pointer-events: none; opacity: 0;
  transition: opacity 220ms var(--ease-out), width 220ms var(--ease-out),
              height 220ms var(--ease-out), background 220ms var(--ease-out),
              border-color 220ms var(--ease-out);
}
.cursor {
  width: 40px; height: 40px; border-radius: 50%;
  border: 1px solid var(--oak); /* taste-skill-ignore: the cursor ring, not a box */
}
.cursor__dot {
  width: 6px; height: 6px; border-radius: 50%; background: var(--red);
}
.cursor-on .cursor, .cursor-on .cursor__dot { opacity: 1; }
.cursor.is-hot {
  width: 62px; height: 62px;
  margin: -11px 0 0 -11px;              /* keep it centred as it grows */
  background: rgba(199,154,107,0.10);
  border-color: var(--oak-hi);
}
/* The real cursor stays visible — this is an addition, never a replacement,
   so nothing is lost if the custom layer fails. */

/* --- Word reveal ---------------------------------------------------------- */
.words-ready .w { display: inline-block; overflow: hidden; vertical-align: bottom; }
.words-ready .w i {
  display: inline-block; font-style: inherit;
  transform: translateY(102%);
  transition: transform 720ms var(--ease-soft);
}
.words-in .w i { transform: translateY(0); }

/* ==========================================================================
   VIEW TRANSITIONS
   Greek ↔ English becomes a cross-fade instead of a white blink, and the
   gallery thumbnail morphs into the viewer. Native, off the main thread,
   and completely absent in browsers that don't support it — nothing to
   polyfill and nothing to break.
   ========================================================================== */
@view-transition { navigation: auto; }

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 420ms;
  animation-timing-function: var(--ease-soft);
}
::view-transition-old(root) { animation-name: vtOut; }
::view-transition-new(root) { animation-name: vtIn; }
@keyframes vtOut { to   { opacity: 0; transform: translateY(-8px); } }
@keyframes vtIn  { from { opacity: 0; transform: translateY(8px); } }

/* The morphing photo gets a longer, softer curve than the page behind it. */
::view-transition-group(shot-morph) {
  animation-duration: 520ms;
  animation-timing-function: var(--ease-soft);
}
::view-transition-old(shot-morph),
::view-transition-new(shot-morph) {
  /* Cross-fade the two crops rather than squashing one into the other. */
  mix-blend-mode: normal;
  object-fit: cover;
}

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}

/* ==========================================================================
   SCROLL-DRIVEN ANIMATION
   Where the browser supports animation-timeline, reveals run on the
   compositor instead of through IntersectionObserver + JS. The JS path
   stays as the fallback, so this is purely additive.
   ========================================================================== */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* The story image drifts a touch against the scroll — depth without
       a scroll listener, and it cannot desync because the compositor
       drives it directly from scroll position. */
    .story__figure img {
      animation: figureDrift linear both;
      animation-timeline: view();
      animation-range: entry 0% exit 100%;
    }
    @keyframes figureDrift {
      from { transform: translateY(2.5%) scale(1.04); }
      to   { transform: translateY(-2.5%) scale(1.04); }
    }
  }
}

/* ==========================================================================
   OPEN / CLOSED STATUS
   ========================================================================== */
/* Plain text with a coloured dot, not a pill: it sits inside a sentence. */
.status-pill {
  display: inline-flex; align-items: center; gap: var(--s2);
  font-weight: 500; white-space: nowrap;
}
.status-pill i { width: 8px; height: 8px; border-radius: 50%; flex: none; background: currentColor; }
.status-pill.is-open { color: #7FBF8A; }
.status-pill.is-open i { animation: pulse 2.4s ease-in-out infinite; }
.status-pill.is-shut { color: var(--muted); }
@keyframes pulse { 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) { .status-pill.is-open i { animation: none; } }

.info__status { margin-bottom: var(--s4); }

/* ==========================================================================
   MOBILE ACTION BAR
   A phone-only decision, not a shrunken desktop header. On a phone the two
   things anyone wants from a restaurant are "call them" and "book a table",
   and both should be reachable with a thumb at any scroll depth.
   ========================================================================== */
.actionbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 120;
  display: grid; grid-template-columns: auto 1fr; gap: var(--s3);
  padding: var(--s3) var(--gutter);
  padding-bottom: calc(var(--s3) + env(safe-area-inset-bottom, 0px));
  background: var(--bg-deep);
  transform: translateY(110%);
  transition: transform var(--dur-base) var(--ease-out);
}
.actionbar.is-up { transform: translateY(0); }
@media (min-width: 860px) { .actionbar { display: none; } }

.actionbar__btn {
  min-height: 48px; padding: 0 var(--s5);
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  border-radius: var(--radius);
  background: var(--surface-hi); color: var(--text);
  font-size: var(--fs-sm); font-weight: 600;
  touch-action: manipulation;
}
.actionbar__btn--primary { background: var(--red); color: var(--on-red); }

/* The bar covers the bottom of the page, so the last section needs room
   underneath it or the footer sits behind the buttons. */
@media (max-width: 859px) {
  body { padding-bottom: 76px; }
}

/* ==========================================================================
   UTILITY
   ========================================================================== */
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.no-scroll { overflow: hidden; }

/* ==========================================================================
   SMALL PHONES (320–380px: iPhone SE, older Android)
   Must be last in the file. A media query carries no extra specificity, so
   these have to come AFTER the component rules they override.

   At 320px the header row measured 363px against a 320px viewport. Because
   body has overflow-x:hidden it was clipped rather than scrolled, and the
   menu button lost 23 of its 44px off the right edge — half the navigation
   control was unreachable on the smallest common phone.
   ========================================================================== */
@media (max-width: 380px) {
  .brand__mark    { height: 26px; }
  .header__inner  { gap: var(--s2); }
  .header__actions{ gap: var(--s2); }
  .lang a         { min-width: 40px; }   /* height stays 44px for touch */
  .hero__cta .btn { width: 100%; }       /* stacked CTAs read as one column */
}

/* ==========================================================================
   SHORT VIEWPORTS (landscape phone)
   At 844×390 the hero measured 512px tall — 160px of that was padding, so
   the CTAs fell below the fold on a screen only 390px high. Tighten the
   vertical rhythm when height is scarce but width is not.
   ========================================================================== */
@media (max-height: 500px) and (orientation: landscape) {
  .hero__inner   { padding-block: var(--s6) var(--s5); }
  .hero__wordmark{ font-size: clamp(2rem, 6.5vw, 3.25rem); }
  .hero__tag     { margin-bottom: var(--s5); font-size: 1.0625rem; }
  .hero__meta    { margin-bottom: var(--s5); }
  .section       { padding-block: var(--s8); }
}

/* ==========================================================================
   UTILITIES replacing former inline style attributes.
   Every style="" in the markup forced `style-src 'unsafe-inline'` in the CSP.
   Six of them across two pages; moving them here let the policy become
   `style-src 'self'` with no exception.
   ========================================================================== */
.section__head          { margin-bottom: var(--s7); }

/* ==========================================================================
   LEGAL PAGES (privacy policy, business details)
   Long-form reading, so the measure is tight and the rhythm is generous.
   ========================================================================== */
.legal { padding-top: calc(var(--header-h) + var(--s8)); }
.legal__wrap { max-width: 78ch; }
.legal h1 { margin-bottom: var(--s4); }
.legal h2 {
  font-size: clamp(1.25rem, 2.4vw, 1.6rem);
  margin-top: var(--s8); margin-bottom: var(--s4);
}
.legal h3 { margin-top: var(--s6); margin-bottom: var(--s3); color: var(--oak-hi); }
.legal p { margin-bottom: var(--s4); color: var(--muted); }
.legal .lead { color: var(--muted); }
.legal ul { margin: 0 0 var(--s5) var(--s5); color: var(--muted); }
.legal li { margin-bottom: var(--s2); }
.legal strong { color: var(--text); font-weight: 600; }
.legal a { color: var(--oak-hi); text-decoration: underline; text-underline-offset: 3px; }
.legal a:hover { color: var(--text); }

.legal__meta { font-size: var(--fs-sm); color: var(--muted-dim); margin-bottom: var(--s7); }

.legal__notice,
.legal__highlight {
  border-radius: var(--radius-card); padding: var(--s5);
  margin-bottom: var(--s6); color: var(--text); font-size: var(--fs-sm);
}
.legal__notice   { background: rgba(217,36,60,0.12); }
.legal__highlight{ background: rgba(199,154,107,0.12); }

.legal__table {
  width: 100%; border-collapse: collapse; margin-bottom: var(--s6);
  font-size: var(--fs-sm);
}
.legal__table th, .legal__table td {
  text-align: left; vertical-align: top;
  padding: var(--s3) var(--s4) var(--s3) 0;
  border-bottom: 1px solid var(--line);
}
.legal__table thead th { color: var(--oak); font-weight: 600; letter-spacing: 0.04em; }
.legal__table tbody th { color: var(--text); font-weight: 500; width: 38%; }
.legal__table td { color: var(--muted); }

.legal__disclaimer {
  margin-top: var(--s8);
  font-size: var(--fs-sm); color: var(--muted); font-style: italic;
}

/* Wide tables must scroll inside themselves rather than push the page. */
@media (max-width: 560px) {
  .legal__table { display: block; overflow-x: auto; }
  .legal__table tbody th { width: auto; }
}

/* ==========================================================================
   DETAILS FROM THE GOOGLE BUSINESS LISTING
   ========================================================================== */

/* Landline / mobile distinction — the label has to be readable, not decorative,
   because picking the wrong number is a real cost to the caller. */
.info__tag { margin-left: var(--s3); font-size: var(--fs-sm); color: var(--muted); }

/* Dine-in / takeaway / delivery. Delivery in particular was nowhere on the
   site before, and it is the kind of thing people search for by name. */
.services {
  list-style: none; padding: 0;
  display: flex; flex-wrap: wrap; column-gap: var(--s3); row-gap: var(--s1);
}
.services li + li::before { content: "·"; color: var(--muted); margin-right: var(--s3); }

/* Google rating.
   Shown as plain linked text with attribution, NOT as aggregateRating in
   structured data: marking up ratings you did not collect yourself is
   self-serving review markup under Google's policy and risks a manual
   action. Displaying it is fine; claiming it in schema is not. */
.hero__rating {
  display: inline-flex; align-items: center; gap: var(--s2);
  min-height: 48px;
  font-size: var(--fs-sm); color: var(--muted);
  text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 4px;
  transition: color var(--dur-fast) var(--ease-out), text-decoration-color var(--dur-fast) var(--ease-out);
}
.hero__rating:hover { color: var(--text); text-decoration-color: var(--oak); }
.hero__rating svg { color: var(--oak-hi); flex: none; }
.hero__rating strong { color: var(--text); font-weight: 600; }

/* ==========================================================================
   MENU SWITCH
   <html data-menu="off"> hides the menu section AND every link that points at
   it, so nothing on the page leads to a section that is not there. The menu
   itself is untouched — markup, styles, data in Supabase, menu.json. To bring
   it back, change data-menu="off" to data-menu="on" in index.html,
   en/index.html and 404.html (and re-add "hasMenu" to the structured data).
   ========================================================================== */
[data-menu="off"] #menu,
[data-menu="off"] [data-menu-link] { display: none !important; }

/* With the darker menu band gone, the story and gallery sections would run
   together as one long stretch of the same background. Give the gallery the
   darker band so the page keeps its light/dark rhythm. */
[data-menu="off"] #choros { background: var(--bg-deep); }
