/* ==================================================================
   TRATTORIA SORRENTO
   Editorial Italian — maiolica blue, Sorrento lemon, porcelain white
   ================================================================== */

/* ------------------------------------------------------------------
   1. TOKENS
   ------------------------------------------------------------------ */
:root {
  /* Type families */
  --font-display: 'Cormorant Garamond', 'Cormorant', Georgia, 'Times New Roman', serif;
  --font-body: 'DM Sans', system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;
  /* The working face: the same DM Sans, named for the places that ask for
     sans on purpose rather than by inheritance — the time chips and the whole
     reservations desk. Undefined, it only ever looked right by accident. */
  --font-sans: var(--font-body);

  /* Core palette — fixed across themes */
  --notte: #0a1a31;
  --notte-deep: #061223;
  --blu: #12386b;
  --blu-lift: #1b4d8f;
  --porcellana: #faf9f5;
  --lino: #f0ece2;
  --limone: #e9b824;
  --limone-soft: #f3d379;

  /* Semantic — light theme */
  --canvas: var(--porcellana);
  --canvas-alt: var(--lino);
  --surface: var(--porcellana);
  --ink: #10233d;
  --ink-soft: #4e5b70;
  --ink-faint: #616a7d;
  --rule: #d9d3c5;
  --rule-strong: #bdb5a3;

  /* Desk signals. Chosen so white sits above 5:1 on the filled pills and
     the tint stays legible behind body text in both themes. */
  --good: #14743a;
  --alert: #a3271c;
  --flag-bg: rgba(233, 184, 36, 0.16);
  --accent: var(--limone);
  --accent-ink: var(--notte);
  --link: var(--blu);
  --link-hover: var(--notte);
  --price: var(--blu);
  --focus: var(--blu);
  --error: #a32117;

  /* Inverted band (hero, footer, dark sections) */
  --band: var(--notte);
  --band-ink: #f3f1ea;
  --band-soft: #a9b6c9;
  --band-rule: rgba(243, 241, 234, 0.22);

  /* Shape */
  --radius-card: 0px;
  --radius-input: 2px;
  --radius-pill: 999px;

  /* Rhythm */
  --gap-section: clamp(4.5rem, 9vw, 9.5rem);
  --pad-card: clamp(1.5rem, 3vw, 2.25rem);
  --shell: 1600px;

  /* Motion */
  --ease: cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --dur: 0.45s;

  /* Maiolica tile — light */
  --tile: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='56' height='56' viewBox='0 0 56 56'%3E%3Cg fill='none' stroke='%2312386b' stroke-width='1'%3E%3Crect x='0.5' y='0.5' width='55' height='55'/%3E%3Crect x='11' y='11' width='34' height='34'/%3E%3Cpath d='M28 4 L52 28 L28 52 L4 28 Z'/%3E%3C/g%3E%3Ccircle cx='28' cy='28' r='3.2' fill='%23e9b824'/%3E%3C/svg%3E");
}

[data-theme="dark"] {
  --canvas: var(--notte);
  --canvas-alt: #0d2340;
  --surface: #0d2340;
  --ink: #f3f1ea;
  --ink-soft: #b3c0d2;
  --ink-faint: #7f8da0;
  --rule: #1f3557;
  --rule-strong: #8fa3c0;

  --good: #14743a;
  --alert: #b3312a;
  --flag-bg: rgba(233, 184, 36, 0.14);
  --link: var(--limone-soft);
  --link-hover: var(--limone);
  --price: var(--limone);
  --focus: var(--limone);
  --error: #ff9c92;

  --band: var(--notte-deep);
  --band-ink: #f3f1ea;
  --band-soft: #a9b6c9;
  --band-rule: rgba(243, 241, 234, 0.18);

  --tile: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='56' height='56' viewBox='0 0 56 56'%3E%3Cg fill='none' stroke='%236f8fbd' stroke-width='1'%3E%3Crect x='0.5' y='0.5' width='55' height='55'/%3E%3Crect x='11' y='11' width='34' height='34'/%3E%3Cpath d='M28 4 L52 28 L28 52 L4 28 Z'/%3E%3C/g%3E%3Ccircle cx='28' cy='28' r='3.2' fill='%23e9b824'/%3E%3C/svg%3E");
}

/* ------------------------------------------------------------------
   2. BASE
   ------------------------------------------------------------------ */
*,
::before,
::after { box-sizing: border-box; }

[hidden] { display: none !important; }

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

body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.62;
  letter-spacing: -0.01em;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

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

p { margin: 0 0 1.1rem; }
p:last-child { margin-bottom: 0; }

a {
  color: var(--link);
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  transition: color 0.25s var(--ease);
}
a:hover { color: var(--link-hover); }

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

::selection {
  background: var(--limone);
  color: var(--notte);
}

/* ------------------------------------------------------------------
   3. TYPE SCALE
   ------------------------------------------------------------------ */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 300;
  line-height: 0.95;
  letter-spacing: -0.03em;
  margin: 0 0 0.5em;
  text-wrap: balance;
}

.display {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(3.4rem, 12.5vw, 10.5rem);
  line-height: 0.82;
  letter-spacing: -0.045em;
  text-transform: uppercase;
  margin: 0;
}

.page-title {
  font-size: clamp(2.9rem, 8vw, 6.4rem);
  line-height: 0.88;
  letter-spacing: -0.04em;
  margin: 0;
}

.section-title {
  font-size: clamp(2.1rem, 4.6vw, 4.2rem);
  line-height: 0.92;
  letter-spacing: -0.035em;
  margin: 0 0 0.45em;
}

.section-intro {
  font-size: clamp(1rem, 1.35vw, 1.125rem);
  color: var(--ink-soft);
  max-width: 62ch;
  margin: 0;
}

.lede {
  font-family: var(--font-display);
  font-weight: 300;
  font-style: italic;
  font-size: clamp(1.35rem, 2.5vw, 1.9rem);
  line-height: 1.32;
  letter-spacing: -0.015em;
  color: var(--ink);
  max-width: 34ch;
}

/* Small meta label — used sparingly, only where it carries information */
.meta {
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 1.1rem;
  display: block;
}

.meta-dot::before {
  content: "";
  display: inline-block;
  width: 5px;
  height: 5px;
  background: var(--accent);
  margin-right: 0.6em;
  vertical-align: 0.15em;
  transform: rotate(45deg);
}

.italic-note {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: 1.2rem;
  color: var(--ink-soft);
}

/* ------------------------------------------------------------------
   4. LAYOUT SHELL
   ------------------------------------------------------------------ */
.container {
  width: min(100% - 2.5rem, var(--shell));
  margin-inline: auto;
}

.site-main { display: block; }

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

.section-alt {
  background: var(--canvas-alt);
  border-block: 1px solid var(--rule);
}

.section-band {
  background: var(--band);
  color: var(--band-ink);
  --price: var(--limone);
  --link: var(--limone-soft);
  --link-hover: var(--limone);
}
.section-band .section-title,
.section-band h2,
.section-band h3 { color: var(--band-ink); }
.section-band .section-intro,
.section-band p { color: var(--band-soft); }
.section-band .meta { color: var(--band-soft); }

.section-header { margin-bottom: clamp(2.5rem, 5vw, 4rem); }

.skip-link {
  position: absolute;
  left: 1rem;
  top: -120px;
  z-index: 200;
  background: var(--notte);
  color: #fff;
  padding: 0.8rem 1.4rem;
  border-radius: var(--radius-pill);
  font-size: 0.85rem;
  font-weight: 500;
  transition: top 0.2s var(--ease);
}
.skip-link:focus { top: 1rem; }

/* ------------------------------------------------------------------
   5. ORNAMENTS — maiolica band, hairline rules, lemon
   ------------------------------------------------------------------ */
.tile-band {
  height: 40px;
  background-image: var(--tile);
  background-repeat: repeat-x;
  background-position: center;
  background-size: auto 100%;
  opacity: 0.38;
  border-block: 1px solid var(--rule);
}

.section-band .tile-band,
.footer .tile-band { border-block-color: var(--band-rule); }

.rule {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  margin-block: clamp(2.5rem, 5vw, 4rem);
}
.rule::before,
.rule::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--rule);
}
.rule svg { flex: none; width: 26px; height: 26px; }
.rule svg .star-line { stroke: var(--rule-strong); }
.rule svg .star-dot { fill: var(--accent); }

.section-band .rule::before,
.section-band .rule::after,
.page-header .rule::before,
.page-header .rule::after { background: var(--band-rule); }

.section-band .rule svg .star-line,
.page-header .rule svg .star-line { stroke: var(--band-soft); }

.hairline {
  height: 1px;
  background: var(--rule);
  border: 0;
  margin: 0;
}

.section-band .hairline { background: var(--band-rule); }

/* ------------------------------------------------------------------
   6. BUTTONS — pill geometry against sharp cards
   ------------------------------------------------------------------ */
.btn {
  --btn-fg: var(--ink);
  --btn-line: var(--ink);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.95rem 1.9rem;
  border: 1px solid var(--btn-line);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--btn-fg);
  font-family: var(--font-body);
  font-size: 0.86rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  transition: color 0.35s var(--ease), border-color 0.35s var(--ease);
}

.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--btn-line);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.45s var(--ease);
}.btn:focus-visible::before { transform: scaleX(1); }

.btn-primary {
  --btn-line: var(--blu);
  --btn-fg: var(--blu);
}.btn-primary:focus-visible { color: var(--porcellana); }

.btn-accent {
  --btn-line: var(--limone);
  --btn-fg: var(--ink);
  background: var(--limone);
  color: var(--notte);
}
.btn-accent::before { background: var(--notte); }.btn-accent:focus-visible { color: var(--limone); border-color: var(--notte); }

.btn-ghost {
  --btn-line: currentColor;
  --btn-fg: inherit;
  border-color: currentColor;
  opacity: 0.92;
}
.btn-ghost::before { background: currentColor; }.btn-ghost:focus-visible { opacity: 1; }

.section-band .btn,
.hero .btn {
  --btn-fg: var(--band-ink);
  --btn-line: var(--band-ink);
  color: var(--band-ink);
  border-color: var(--band-ink);
}
.section-band .btn::before,
.hero .btn::before { background: var(--band-ink); }.section-band .btn:focus-visible,
.hero .btn:focus-visible { color: var(--notte); }

.hero .btn-accent,
.section-band .btn-accent {
  background: var(--limone);
  border-color: var(--limone);
  color: var(--notte);
}
.hero .btn-accent::before,
.section-band .btn-accent::before { background: var(--porcellana); }

[data-theme="dark"] .btn-primary {
  --btn-line: var(--limone-soft);
  --btn-fg: var(--limone-soft);
}[data-theme="dark"] .btn-primary:focus-visible { color: var(--notte); }


/* Hover belongs to mice and trackpads. iOS keeps :hover on whatever was
   touched last, so a button touched while scrolling would stay filled. */
@media (hover: hover) {
  .btn:hover::before { transform: scaleX(1); }
  .btn-primary:hover { color: var(--porcellana); }
  .btn-accent:hover { color: var(--limone); border-color: var(--notte); }
  .btn-ghost:hover { opacity: 1; }
  .section-band .btn:hover,
  .hero .btn:hover { color: var(--notte); }
  .hero .btn-accent:hover,
  .section-band .btn-accent:hover { color: var(--notte); border-color: var(--porcellana); }
  [data-theme="dark"] .btn-primary:hover { color: var(--notte); }
}

.text-link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--link);
  padding-bottom: 3px;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 1px;
  background-position: left bottom;
  background-repeat: no-repeat;
  transition: background-size 0.4s var(--ease), color 0.3s var(--ease);
}
.text-link:hover,
.text-link:focus-visible { background-size: 100% 1px; }

/* ------------------------------------------------------------------
   7. HEADER + NAVIGATION
   ------------------------------------------------------------------ */
/* The header is written in by site.js. Its slot holds the same height
   until then, so the page doesn't jump down as it arrives. */
.js [data-site-header] { height: 80.6px; }
@media (max-width: 767px) { .js [data-site-header] { height: 78.6px; } }

.header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: transparent;
  color: var(--band-ink);
  transition:
    background-color 0.4s var(--ease),
    border-color 0.4s var(--ease),
    color 0.4s var(--ease),
    transform 0.45s var(--ease);
  border-bottom: 1px solid transparent;
}

/* Retract on scroll-down, return on scroll-up. */
.header.is-hidden { transform: translateY(-100%); }
body.nav-open .header.is-hidden { transform: none; }

/* Pages without a photographic hero get an opaque bar immediately */
.header.header-solid,
.header.is-scrolled {
  background: var(--canvas);
  background: color-mix(in srgb, var(--canvas) 92%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  color: var(--ink);
  border-bottom-color: var(--rule);
}

/* The header floats above the open drawer so its close button stays usable —
   drop the solid bar so it reads against the dark drawer. */
body.nav-open .header {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  color: var(--ink);
  border-bottom-color: transparent;
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding-block: 1.05rem;
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  text-decoration: none;
  color: inherit;
  flex: none;
}
/* A full wordmark lockup at roughly 2.4:1, so it is sized by height and
   left to find its own width rather than squeezed into a square. */
.brand img {
  width: auto;
  height: 46px;
  flex: none;
  object-fit: contain;
  transition: transform 0.5s var(--ease);
}
.brand:hover img { transform: rotate(-6deg) scale(1.06); }

/* The supplied wordmark is white artwork on transparency, so it vanished
   against the light header and the light drawer. brightness(0) renders it
   as a solid silhouette wherever it sits on a pale ground. */
[data-theme="light"] .header.is-scrolled .brand img,
[data-theme="light"] .header.header-solid .brand img,
[data-theme="light"] body.nav-open .brand img { filter: brightness(0); }

.brand-text {
  display: block;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.28rem;
  line-height: 1;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}
.brand-small {
  display: block;
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.19em;
  text-transform: uppercase;
  opacity: 0.7;
  margin-top: 4px;
}

.nav {
  display: flex;
  align-items: center;
  gap: 1.9rem;
}
.nav a {
  position: relative;
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  text-decoration: none;
  color: inherit;
  padding-block: 0.4rem;
  opacity: 0.82;
  transition: opacity 0.3s var(--ease);
}
.nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.4s var(--ease);
}
.nav a:hover,
.nav a:focus-visible { opacity: 1; }
.nav a:hover::after,
.nav a:focus-visible::after { transform: scaleX(1); }
.nav a.active { opacity: 1; }
.nav a.active::after { transform: scaleX(1); }

.header-actions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex: none;
}

.header-actions .btn {
  padding: 0.7rem 1.35rem;
  font-size: 0.74rem;
}

.header-phone {
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-decoration: none;
  color: inherit;
  white-space: nowrap;
  opacity: 0.85;
}
.header-phone:hover { opacity: 1; color: var(--accent); }

.theme-toggle {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border: 1px solid currentColor;
  border-radius: var(--radius-pill);
  background: transparent;
  color: inherit;
  cursor: pointer;
  padding: 0;
  opacity: 0.85;
  transition: opacity 0.3s var(--ease), transform 0.5s var(--ease);
}
.theme-toggle:hover { opacity: 1; transform: rotate(25deg); }
.theme-toggle svg { width: 17px; height: 17px; }
.theme-toggle .icon-moon { display: none; }
[data-theme="dark"] .theme-toggle .icon-sun { display: none; }
[data-theme="dark"] .theme-toggle .icon-moon { display: block; }

/* Flex column rather than grid: the three bars then centre as a group
   with an even gap, instead of being spread across implicit rows. */
.nav-toggle {
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  border: 1px solid currentColor;
  border-radius: var(--radius-pill);
  background: transparent;
  color: inherit;
  cursor: pointer;
  padding: 0;
  transition: background-color 0.3s var(--ease), border-color 0.3s var(--ease);
}
.nav-toggle:hover,
.nav-toggle:focus-visible { background: color-mix(in srgb, currentColor 12%, transparent); }

.nav-toggle span {
  display: block;
  width: 19px;
  height: 2px;
  border-radius: 1px;
  background: currentColor;
  transition: transform 0.4s var(--ease), opacity 0.2s var(--ease);
}
/* Bars sit 7px apart centre to centre (2px bar + 5px gap). */
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Mobile drawer */
.nav-drawer {
  position: fixed;
  inset: 0;
  z-index: 95;
  /* The drawer takes the theme's own ground. It was pinned to --notte,
     which is what left a dark menu sitting over the light theme. */
  background: var(--canvas);
  color: var(--ink);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 5rem 2rem 3rem;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-1.5rem);
  transition: opacity 0.4s var(--ease), transform 0.5s var(--ease), visibility 0.4s;
}
.nav-drawer.is-open {
  opacity: 1;
  visibility: visible;
  transform: none;
}
/* The links are inline <a>s, so without this they flow and wrap as a
   paragraph rather than stacking as a menu. */
.nav-drawer nav {
  display: flex;
  flex-direction: column;
}

.nav-drawer nav a {
  display: block;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(2rem, 9vw, 3.2rem);
  line-height: 1.15;
  letter-spacing: -0.03em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink);
  padding-block: 0.28rem;
  border-bottom: 1px solid var(--rule);
  opacity: 0;
  transform: translateY(14px);
}
.nav-drawer.is-open nav a {
  animation: drawer-in 0.55s var(--ease) forwards;
  animation-delay: calc(var(--i, 0) * 55ms + 100ms);
}
/* Lemon is 1.0:1 on porcellana — the active mark uses --link, which is
   blue in light and lemon-soft in dark. */
.nav-drawer nav a.active { color: var(--link); }
.nav-drawer-foot {
  margin-top: 2.5rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

@keyframes drawer-in {
  to { opacity: 1; transform: none; }
}

/* ------------------------------------------------------------------
   8. HERO
   ------------------------------------------------------------------ */
.hero {
  position: relative;
  min-height: clamp(600px, 92vh, 900px);
  min-height: clamp(600px, 92svh, 900px);
  margin-top: -84px;
  padding-top: 84px;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  background: var(--notte);
  color: var(--band-ink);
  isolation: isolate;
}

.hero-media {
  position: absolute;
  inset: 0;
  z-index: -2;
  overflow: hidden;
}
.hero-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* The branzino platter sits dead centre of the frame, so a centred crop
     keeps it in view at every viewport. */
  object-position: 50% 50%;
  filter: saturate(0.62) contrast(1.06) brightness(0.62);
  transform: scale(1.08);
  animation: hero-drift 26s var(--ease) forwards;
}
.hero-media::after {
  content: "";
  position: absolute;
  inset: 0;
  /* The old scrim thinned to 0.42 across the middle of the frame, which
     put the tagline at 2.0:1 over any bright part of the photograph.
     No stop now falls below 0.68, so copy holds >5:1 anywhere. */
  background:
    linear-gradient(180deg, rgba(10, 26, 49, 0.82) 0%, rgba(10, 26, 49, 0.68) 38%, rgba(10, 26, 49, 0.95) 100%),
    linear-gradient(90deg, rgba(18, 56, 107, 0.5), rgba(6, 18, 35, 0.32));
}

@keyframes hero-drift {
  to { transform: scale(1); }
}

.hero-content {
  position: relative;
  padding-bottom: clamp(3rem, 7vw, 6rem);
  padding-top: clamp(4rem, 10vw, 8rem);
  width: min(100% - 2.5rem, var(--shell));
  margin-inline: auto;
}

.hero-meta {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding-bottom: 1.4rem;
  margin-bottom: clamp(1.5rem, 4vw, 3rem);
  border-bottom: 1px solid var(--band-rule);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--band-ink);
}

.hero-title { color: var(--band-ink); }
.hero-title .line {
  display: block;
  overflow: hidden;
  padding-bottom: 0.24em;
  margin-bottom: -0.24em;
}
.hero-title .line > span {
  display: block;
}
.js .hero-title .line > span {
  transform: translateY(102%);
  animation: line-rise 1.05s var(--ease) forwards;
  animation-delay: calc(var(--i, 0) * 110ms + 180ms + var(--intro-delay, 0ms));
}

@keyframes line-rise {
  to { transform: none; }
}

.hero-lower {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: end;
  margin-top: clamp(1.75rem, 4vw, 3rem);
}

.hero-tagline {
  color: var(--band-ink);
  font-size: 1.06rem;
  line-height: 1.6;
  max-width: 52ch;
  margin: 0;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: flex-start;
}

.js .hero-fade {
  opacity: 0;
  animation: fade-up 0.9s var(--ease) forwards;
  animation-delay: calc(var(--i, 0) * 110ms + 620ms + var(--intro-delay, 0ms));
}

@keyframes fade-up {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: none; }
}

/* Sorrento lemon watermark — the single figurative ornament */
.hero-lemon {
  position: absolute;
  right: clamp(-40px, -2vw, 0px);
  top: 22%;
  width: clamp(150px, 22vw, 320px);
  opacity: 0.16;
  z-index: -1;
  pointer-events: none;
  animation: lemon-float 14s ease-in-out infinite;
}
.hero-lemon .peel { fill: var(--limone); }
.hero-lemon .leaf { fill: none; stroke: var(--limone); stroke-width: 2; }

@keyframes lemon-float {
  0%, 100% { transform: translateY(0) rotate(-4deg); }
  50% { transform: translateY(-22px) rotate(3deg); }
}

/* ------------------------------------------------------------------
   9. PAGE HEADER (interior pages)
   ------------------------------------------------------------------ */
.page-header {
  background: var(--band);
  color: var(--band-ink);
  padding-block: clamp(6.5rem, 13vw, 10rem) clamp(3rem, 6vw, 5rem);
  position: relative;
  overflow: hidden;
}
.page-header::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--tile);
  background-position: center;
  opacity: 0.055;
  pointer-events: none;
}
.page-header .container { position: relative; }
.page-header .page-title { color: var(--band-ink); }
.page-header .section-intro { color: var(--band-soft); margin-top: 1.5rem; }
.page-header .meta { color: var(--limone); }
.page-header .meta-dot::before { background: var(--limone); }

/* ------------------------------------------------------------------
   10. EDITORIAL GRIDS
   ------------------------------------------------------------------ */
.about-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
}

.about-image-wrap {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-card);
  /* Capped so a tall portrait doesn't tower over the column beside it. */
  width: min(100%, 460px);
  margin-inline: auto;
}
.about-image-wrap::after {
  content: "";
  position: absolute;
  inset: 10px;
  border: 1px solid rgba(250, 249, 245, 0.35);
  pointer-events: none;
}
/* The source is a 500x750 portrait. Forcing it into a 4:3 landscape with
   object-fit:cover discarded roughly half the frame and cut off a face,
   so the image now keeps its own proportions and is never cropped. */
.about-image {
  width: 100%;
  height: auto;
  transition: transform 1.1s var(--ease);
}
.about-image-wrap:hover .about-image { transform: scale(1.045); }

.about-copy p { color: var(--ink-soft); max-width: 56ch; }

.accent-line {
  border-left: 2px solid var(--accent);
  padding-left: 1.1rem;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.18rem;
  line-height: 1.45;
  color: var(--ink);
}

/* ------------------------------------------------------------------
   11. MARQUEE — the one piece of ambient motion
   ------------------------------------------------------------------ */
.marquee {
  overflow: hidden;
  border-block: 1px solid var(--rule);
  padding-block: 1.15rem;
  user-select: none;
}
.section-band .marquee { border-block-color: var(--band-rule); }

.marquee-track {
  display: flex;
  width: max-content;
  animation: marquee 34s linear infinite;
}
.marquee:hover .marquee-track { animation-play-state: paused; }

.marquee-group {
  display: flex;
  align-items: center;
  flex: none;
}
.marquee-group span {
  font-family: var(--font-display);
  font-weight: 300;
  font-style: italic;
  font-size: clamp(1.4rem, 2.8vw, 2.35rem);
  letter-spacing: -0.02em;
  padding-inline: 1.4rem;
  white-space: nowrap;
}
.marquee-group i {
  width: 7px;
  height: 7px;
  flex: none;
  background: var(--accent);
  transform: rotate(45deg);
}

@keyframes marquee {
  to { transform: translateX(-50%); }
}

/* ------------------------------------------------------------------
   12. CARDS
   ------------------------------------------------------------------ */
.card {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius-card);
  padding: var(--pad-card);
}

.featured-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: 0;
  border-top: 1px solid var(--rule);
}
.section-band .featured-grid { border-top-color: var(--band-rule); }

.dish-card {
  position: relative;
  padding: clamp(2rem, 3.5vw, 2.9rem) clamp(1.2rem, 2.4vw, 2rem);
  border-bottom: 1px solid var(--rule);
  border-right: 1px solid var(--rule);
  transition: background-color 0.45s var(--ease);
}
.section-band .dish-card { border-color: var(--band-rule); }
.dish-card:last-child { border-right: 0; }
.dish-card:hover { background: color-mix(in srgb, var(--accent) 8%, transparent); }

.dish-index {
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  color: var(--price);
  display: block;
  margin-bottom: 1.4rem;
}

.dish-card h3 {
  font-size: clamp(1.6rem, 2.4vw, 2.15rem);
  line-height: 1;
  margin: 0 0 0.6rem;
}

.dish-card .menu-desc {
  color: var(--ink-soft);
  font-size: 0.94rem;
  margin-bottom: 1.4rem;
}
.section-band .dish-card .menu-desc { color: var(--band-soft); }

.dish-foot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--rule);
}
.section-band .dish-foot { border-top-color: var(--band-rule); }

.menu-price {
  font-family: var(--font-body);
  font-size: 0.9rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--price);
  white-space: nowrap;
}

/* Testimonials */
.testimonial-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 270px), 1fr));
  gap: 0;
  border-top: 1px solid var(--rule);
  border-left: 1px solid var(--rule);
}
.testimonial-card {
  padding: clamp(2rem, 3.5vw, 3rem) clamp(1.4rem, 2.5vw, 2.2rem);
  border-right: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  display: flex;
  flex-direction: column;
  gap: 1.2rem;
}
.stars {
  display: flex;
  gap: 4px;
  color: var(--accent);
}
.stars svg { width: 14px; height: 14px; fill: currentColor; }
.testimonial-card blockquote {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(1.2rem, 1.9vw, 1.55rem);
  line-height: 1.34;
  letter-spacing: -0.015em;
}
.testimonial-card cite {
  font-style: normal;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-top: auto;
}

/* Facts strip */
.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
  border-top: 1px solid var(--band-rule);
  border-bottom: 1px solid var(--band-rule);
}
.facts div {
  padding: clamp(1.6rem, 3vw, 2.4rem) 1.2rem;
  border-right: 1px solid var(--band-rule);
}
.facts div:last-child { border-right: 0; }
.facts dt {
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--band-soft);
  margin-bottom: 0.7rem;
}
.facts dd {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(1.8rem, 3vw, 2.7rem);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--band-ink);
}

/* ------------------------------------------------------------------
   13. MENU PAGE
   ------------------------------------------------------------------ */
/* site.js builds the menu and its tabs. Until then the tab bar keeps its
   height and the footnotes below the menu wait, so nothing is shoved down
   when the dishes arrive. */
.js .menu-jump-inner:empty { min-height: calc(44px + 1.7rem); }
.js #menuRoot:empty { min-height: 150vh; }
.js #menuRoot:empty ~ * { display: none; }

.menu-jump {
  position: sticky;
  top: 80px;
  z-index: 40;
  background: var(--canvas-alt);
  background: color-mix(in srgb, var(--canvas-alt) 94%, transparent);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--rule);
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}
.menu-jump-inner {
  display: flex;
  gap: 0.5rem;
  overflow-x: auto;
  padding-block: 0.85rem;
  scrollbar-width: none;
}
.menu-jump-inner::-webkit-scrollbar { display: none; }
.menu-jump a {
  flex: none;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0.45rem 1rem;
  border: 1px solid var(--rule);
  border-radius: var(--radius-pill);
  font-size: 0.73rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink-soft);
  white-space: nowrap;
  transition: background-color 0.3s var(--ease), color 0.3s var(--ease), border-color 0.3s var(--ease);
}
.menu-jump a:hover,
.menu-jump a.active {
  background: var(--blu);
  border-color: var(--blu);
  color: var(--porcellana);
}
[data-theme="dark"] .menu-jump a:hover,
[data-theme="dark"] .menu-jump a.active {
  background: var(--limone);
  border-color: var(--limone);
  color: var(--notte);
}

.menu-category {
  padding-top: clamp(2.5rem, 5vw, 4rem);
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
  border-top: 1px solid var(--rule);
  scroll-margin-top: 160px;
}
.menu-category:first-child { border-top: 0; padding-top: 0; }

.menu-category-head {
  display: grid;
  grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
  gap: clamp(1rem, 3vw, 3rem);
  align-items: start;
  margin-bottom: 2rem;
}
.menu-category h3 {
  font-size: clamp(2rem, 3.6vw, 3.1rem);
  line-height: 0.95;
  margin: 0;
}
/* One photo per section, only where a real dish photo matches. On wide
   screens it fills the empty column under the title; below 1080px it shrinks
   to a thumbnail beside the title so the dishes stay first. */
.menu-photo {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  margin-top: 1.5rem;
  border-radius: var(--radius-card);
}

.category-note {
  display: block;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.05rem;
  color: var(--ink-soft);
  letter-spacing: 0;
  margin-top: 0.5rem;
}

.menu-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr));
  gap: 0 clamp(2rem, 4vw, 4rem);
}

.menu-subhead {
  grid-column: 1 / -1;
  padding-top: 2rem;
}
.menu-subhead:first-child { padding-top: 0; }
.menu-subhead h4 {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.6rem;
  font-weight: 400;
  line-height: 1.1;
}
.menu-subhead .category-note { margin-top: 0.25rem; font-size: 0.98rem; }

/* Base prices for a group whose dishes are preparations (Chicken & Veal). */
.menu-bases {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin: 1rem 0 0.6rem;
  padding: 0;
  list-style: none;
}
.menu-bases li {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  padding: 0.7rem 1.15rem;
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
}
.menu-base-name {
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 500;
  color: var(--ink);
}
.menu-base-name em {
  font-family: var(--font-display);
  font-weight: 400;
  color: var(--ink-soft);
}
.menu-base-price {
  font-family: var(--font-display);
  font-size: 1.6rem;
  line-height: 1;
  color: var(--price);
  white-space: nowrap;
}

.menu-item {
  padding-block: 1.05rem;
  border-bottom: 1px solid var(--rule);
}
.menu-item-top {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
}
.menu-item-top h4,
.menu-item-top h5 {
  margin: 0;
  font-family: var(--font-body);
  font-size: 0.98rem;
  font-weight: 500;
  letter-spacing: -0.005em;
  line-height: 1.35;
}
.menu-item-top::before {
  content: "";
  order: 2;
  flex: 1;
  height: 1px;
  align-self: center;
  background: var(--rule-strong);
  opacity: 0.55;
}
.menu-item-top .menu-price { order: 3; }
.menu-desc {
  margin: 0.3rem 0 0;
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--ink-soft);
  max-width: 58ch;
}

/* ------------------------------------------------------------------
   14. GALLERY
   ------------------------------------------------------------------ */
/* Every photo whole, at its own proportions: a masonry of columns, not
   a grid that crops. Captions sit under the picture, not over it. */
.gallery-grid {
  columns: 3 300px;
  column-gap: clamp(1rem, 2.2vw, 2rem);
}
/* Each photo is a framed print: a porcelain mat with a keyline, lemon
   corner mounts, and its caption inside the mat. */
.gallery-item {
  position: relative;
  break-inside: avoid;
  margin: 0 0 clamp(1.1rem, 2.2vw, 2rem);
  padding: clamp(0.55rem, 1vw, 0.8rem) clamp(0.55rem, 1vw, 0.8rem) 0;
  background: var(--surface);
  border: 1px solid var(--rule);
  box-shadow: 0 1px 2px rgba(10, 26, 49, 0.06), 0 18px 30px -22px rgba(10, 26, 49, 0.45);
}
.gallery-item::before,
.gallery-item::after {
  content: "";
  position: absolute;
  width: 18px;
  height: 18px;
  border: 2px solid var(--limone);
  pointer-events: none;
}
.gallery-item::before { top: -1px; left: -1px; border-right: 0; border-bottom: 0; }
.gallery-item::after { bottom: -1px; right: -1px; border-left: 0; border-top: 0; }

/* The wall is hung in three groups, each with a heading and a count. */
.gallery-group + .tile-band { margin-block: clamp(2.5rem, 6vw, 4.5rem); }
.gallery-head {
  display: flex;
  align-items: baseline;
  gap: clamp(0.7rem, 1.6vw, 1.2rem);
  margin-bottom: clamp(1.4rem, 3vw, 2.2rem);
}
.gallery-no {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.15rem;
  color: var(--link);
  min-width: 1.6em;
}
.gallery-title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.7rem, 3.2vw, 2.4rem);
  line-height: 1.1;
  color: var(--ink);
}
.gallery-rule { flex: 1; align-self: center; height: 1px; background: var(--rule-strong); }
.gallery-count {
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  white-space: nowrap;
}
@media (max-width: 560px) { .gallery-count { display: none; } }
.gallery-item button {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: var(--canvas-alt);
  overflow: hidden;
  cursor: zoom-in;
  position: relative;
}
.gallery-item img {
  display: block;
  width: 100%;
  height: auto;
  transition: transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}
/* A hairline mat that tightens on hover, and the photo leans in. */
.gallery-item button::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 1px solid rgba(250, 249, 245, 0);
  transition: inset 0.5s var(--ease), border-color 0.5s var(--ease);
  pointer-events: none;
}
@media (hover: hover) {
  .gallery-item button:hover img { transform: scale(1.035); }
  .gallery-item button:hover::after { inset: 12px; border-color: rgba(250, 249, 245, 0.7); }
}
.gallery-item button:focus-visible { outline: 2px solid var(--limone); outline-offset: 4px; }
.gallery-item figcaption {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.75rem 0.3rem 0.9rem;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.12rem;
  line-height: 1.25;
  color: var(--ink);
}
.gallery-num {
  font-size: 0.95rem;
  color: var(--ink-soft);
  min-width: 1.5em;
}

/* Lightbox */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: grid;
  place-items: center;
  padding: clamp(1rem, 4vw, 3rem);
  background: rgba(6, 18, 35, 0.95);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.35s var(--ease), visibility 0.35s;
}
/* Visible at once on opening (the fade still runs), so focus can move into it. */
.lightbox.is-open { opacity: 1; visibility: visible; transition: opacity 0.35s var(--ease), visibility 0s; }
.lightbox img {
  max-width: min(100%, 1800px);
  max-height: 84vh;
  width: auto;
  height: auto;
  object-fit: contain;
  transform: scale(0.96);
  transition: transform 0.45s var(--ease);
}
.lightbox.is-open img { transform: none; }
.lightbox-caption {
  color: #f3f1ea;
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin-top: 1.2rem;
  text-align: center;
}
.lightbox-credit {
  display: block;
  margin-top: 0.45rem;
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: none;
  opacity: 0.75;
}
.footer-origin {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 0.3em;
  font: 400 13px/1.3 'Inter', system-ui, sans-serif;
  letter-spacing: -0.005em;
  color: var(--band-soft);
}
.footer-comma { margin-left: -0.3em; }
.lightbox-close {
  position: absolute;
  top: clamp(1rem, 3vw, 2rem);
  right: clamp(1rem, 3vw, 2rem);
  width: 46px;
  height: 46px;
  border: 1px solid rgba(243, 241, 234, 0.5);
  border-radius: var(--radius-pill);
  background: transparent;
  color: #f3f1ea;
  font-size: 1.2rem;
  cursor: pointer;
  transition: background-color 0.3s var(--ease), transform 0.3s var(--ease);
}
.lightbox-close:hover { background: rgba(243, 241, 234, 0.14); transform: rotate(90deg); }

/* ------------------------------------------------------------------
   15. RESERVATIONS + FORMS
   ------------------------------------------------------------------ */
.reservation-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: clamp(1.5rem, 3.5vw, 3.5rem);
  align-items: start;
}

.info-list,
.hours-list {
  list-style: none;
  margin: 1.5rem 0 0;
  padding: 0;
}
.info-list li,
.hours-list li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 0.75rem;
  border-bottom: 1px solid var(--rule);
  font-size: 0.9rem;
}
.info-list li span:first-child,
.hours-list li span:first-child {
  color: var(--ink-faint);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  align-self: center;
}
.info-list li span:last-child,
.hours-list li span:last-child { text-align: right; }

.note {
  margin-top: 1.5rem;
  padding: 1rem 1.2rem;
  background: color-mix(in srgb, var(--accent) 13%, transparent);
  border-left: 2px solid var(--accent);
  font-size: 0.88rem;
  line-height: 1.55;
}

.field { margin-bottom: 1.35rem; }
.field label {
  display: block;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 0.55rem;
}
.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 0.85rem 0;
  border: 0;
  border-bottom: 1px solid var(--rule-strong);
  border-radius: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1rem;
  transition: border-color 0.3s var(--ease);
}
.field textarea { resize: vertical; padding-block: 0.85rem; }
.field select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 12px) 50%, calc(100% - 7px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 2rem;
}
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-bottom-color: var(--accent);
  border-bottom-width: 2px;
  padding-bottom: calc(0.85rem - 1px);
}
.field input.invalid,
.field select.invalid,
.field textarea.invalid { border-bottom-color: var(--error); }

.field-error {
  margin: 0.5rem 0 0;
  color: var(--error);
  font-size: 0.82rem;
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
  gap: 0 1.5rem;
}

.form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  margin-top: 1.75rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--rule);
}

/* Honeypot — off-screen rather than display:none, which some bots skip. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.btn[disabled],
.btn[aria-disabled="true"] {
  opacity: 0.5;
  cursor: progress;
  pointer-events: none;
}

.form-status {
  margin: 1.25rem 0 0;
  padding: 0.95rem 1.15rem;
  border-left: 2px solid var(--error);
  background: color-mix(in srgb, var(--error) 10%, transparent);
  color: var(--ink);
  font-size: 0.9rem;
  line-height: 1.55;
}
.form-status a {
  color: var(--ink);
  text-decoration-color: var(--error);
  font-weight: 500;
}

.confirmation { border-color: var(--accent); border-width: 1px; }
.confirmation-status {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(1.6rem, 3vw, 2.4rem);
  line-height: 1.05;
  letter-spacing: -0.03em;
  margin: 0 0 0.9rem;
}
.confirmation-status:focus { outline: none; }

.summary-list {
  margin: 1.5rem 0 0;
  border-top: 1px solid var(--rule);
}
.summary-list > div {
  display: flex;
  justify-content: space-between;
  gap: 1.5rem;
  padding-block: 0.8rem;
  border-bottom: 1px solid var(--rule);
}
.summary-list dt {
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.summary-list dd { margin: 0; text-align: right; font-size: 0.94rem; }

/* ------------------------------------------------------------------
   15b. RESERVATION MODAL + STATUS LOOK-UP
   ------------------------------------------------------------------ */
.field-hint {
  margin: 0.4rem 0 0;
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--ink-faint);
}

/* Confirm-before-send dialog */
.modal {
  position: fixed;
  inset: 0;
  z-index: 130;
  display: grid;
  place-items: center;
  padding: clamp(1rem, 4vw, 2.5rem);
}
.modal[hidden] { display: none; }

.modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(6, 18, 35, 0.72);
  opacity: 0;
  transition: opacity 0.3s var(--ease);
}
.modal.is-open .modal-backdrop { opacity: 1; }

.modal-panel {
  position: relative;
  width: min(100%, 540px);
  max-height: min(86vh, 760px);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-top: 3px solid var(--accent);
  padding: clamp(1.5rem, 4vw, 2.5rem);
  opacity: 0;
  transform: translateY(18px) scale(0.985);
  transition: opacity 0.35s var(--ease), transform 0.4s var(--ease);
}
.modal.is-open .modal-panel { opacity: 1; transform: none; }

.modal-title {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(1.7rem, 3.4vw, 2.4rem);
  line-height: 1.05;
  letter-spacing: -0.03em;
  margin: 0 0 1rem;
}
.modal-panel p { color: var(--ink-soft); font-size: 0.95rem; }
.modal-panel strong { color: var(--ink); }
.modal-panel .summary-list { margin-top: 1.5rem; }

/* The panel scrolls when the summary is long, so the buttons stay pinned to
   the bottom of it — the primary action is never below the fold. */
.modal-actions {
  position: sticky;
  bottom: calc(clamp(1.5rem, 4vw, 2.5rem) * -1);
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.75rem;
  padding-block: 1.5rem;
  border-top: 1px solid var(--rule);
  background: var(--surface);
}

/* Status look-up */
.status-check {
  border: 1px solid var(--rule);
  background: var(--surface);
  padding: var(--pad-card);
}

.status-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 1rem;
}
.status-form .field {
  flex: 1 1 min(100%, 320px);
  margin-bottom: 0;
}
.status-form .btn { flex: none; margin-top: 1.85rem; }

.status-results:empty { display: none; }
.status-results { margin-top: 1.75rem; }

.status-empty,
.status-error {
  margin: 0;
  padding: 1rem 1.2rem;
  border-left: 2px solid var(--rule-strong);
  background: var(--canvas-alt);
  font-size: 0.92rem;
  color: var(--ink-soft);
}
.status-error { border-left-color: var(--error); }

.status-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--rule);
}
.status-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  padding-block: 1.1rem;
  border-bottom: 1px solid var(--rule);
}
/* Let the details column shrink so a long explanation never pushes the
   status chip onto its own line while its neighbours stay inline. */
.status-list li > div:first-child {
  flex: 1 1 240px;
  min-width: 0;
}
.status-when {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(1.25rem, 2.2vw, 1.6rem);
  line-height: 1.1;
  letter-spacing: -0.025em;
  margin: 0;
}
.status-meta {
  display: block;
  margin-top: 0.3rem;
  font-size: 0.76rem;
  font-weight: 500;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* The four states, as flat chips */
.status-pill {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.95rem;
  border: 1px solid currentColor;
  border-radius: var(--radius-pill);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
}
.status-pill::before {
  content: "";
  width: 6px;
  height: 6px;
  background: currentColor;
  transform: rotate(45deg);
}
.status-pill.is-pending   { color: #7a5b00; }
.status-pill.is-confirmed { color: #1c6b3a; }
.status-pill.is-cancelled { color: var(--ink-faint); }
.status-pill.is-declined  { color: var(--error); }

[data-theme="dark"] .status-pill.is-pending   { color: #e9b824; }
[data-theme="dark"] .status-pill.is-confirmed { color: #6ac48c; }
[data-theme="dark"] .status-pill.is-declined  { color: #ff9c92; }

.status-note {
  margin: 1.25rem 0 0;
  font-size: 0.86rem;
  color: var(--ink-faint);
}

@media (max-width: 560px) {
  .status-form .btn { margin-top: 0; width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .modal-backdrop,
  .modal-panel { transition: none; }
}

/* ------------------------------------------------------------------
   15c. ORDERING PLATFORMS
   ------------------------------------------------------------------ */
.order-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
  gap: clamp(0.75rem, 1.6vw, 1.25rem);
}

.order-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.4rem;
  padding: clamp(1.5rem, 3vw, 2.1rem) 1.25rem;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius-card);
  text-decoration: none;
  color: var(--ink);
  transition:
    background-color 0.4s var(--ease),
    border-color 0.4s var(--ease),
    transform 0.45s var(--ease);
}
.order-tile:hover,
.order-tile:focus-visible {
  background: var(--canvas-alt);
  border-color: var(--rule-strong);
  transform: translateY(-4px);
  color: var(--ink);
}

/* Fixed box so tiles line up whatever shape each logo happens to be. */
.order-logo {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  max-width: 132px;
  height: 40px;
  margin-bottom: 0.75rem;
}
.order-logo-img {
  /* Pinned to the mount so the box does the constraining and object-fit does
     the letterboxing. A percentage height was not enough on its own: centred
     in a grid, it never resolved against the 40px row, and a mark carrying its
     own dimensions — Slice is 129x83 — overflowed the tile. */
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
}

/* Shown until a real logo file is dropped into img/brands/. */
.order-wordmark {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.65rem;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--ink);
  white-space: nowrap;
}
.order-logo.has-logo .order-wordmark { display: none; }

.order-note {
  font-size: 0.82rem;
  color: var(--ink-faint);
}

.order-empty {
  margin: 0;
  padding: 1.1rem 1.3rem;
  border-left: 2px solid var(--accent);
  background: var(--canvas-alt);
  font-size: 0.94rem;
  color: var(--ink-soft);
}

/* ------------------------------------------------------------------
   16. CONTACT
   ------------------------------------------------------------------ */
.contact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
  border-top: 1px solid var(--rule);
  border-left: 1px solid var(--rule);
}
.contact-card {
  border: 0;
  border-right: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  padding: clamp(1.75rem, 3vw, 2.5rem);
  transition: background-color 0.4s var(--ease);
}
.contact-card:hover { background: var(--canvas-alt); }
.contact-card h3 {
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 0.9rem;
}
.contact-card a {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(1.35rem, 2.4vw, 1.9rem);
  letter-spacing: -0.025em;
  text-decoration: none;
  color: var(--ink);
}
.contact-card a:hover { color: var(--price); }

.hours-location-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: clamp(1.5rem, 3.5vw, 3.5rem);
  align-items: stretch;
}
.map-wrap {
  position: relative;
  min-height: 380px;
  border: 1px solid var(--rule);
  overflow: hidden;
}
.map-wrap iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  filter: grayscale(0.55) contrast(1.05);
  transition: filter 0.6s var(--ease);
}
.map-wrap:hover iframe { filter: none; }
[data-theme="dark"] .map-wrap iframe { filter: grayscale(0.4) invert(0.9) hue-rotate(180deg); }
[data-theme="dark"] .map-wrap:hover iframe { filter: invert(0.9) hue-rotate(180deg); }

/* ------------------------------------------------------------------
   17. FOOTER
   ------------------------------------------------------------------ */
.footer {
  background: var(--band);
  color: var(--band-ink);
}
.footer .container { padding-block: clamp(3.5rem, 7vw, 6rem) 2rem; }

.footer-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) repeat(2, minmax(0, 1fr));
  gap: clamp(2rem, 5vw, 4rem);
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
  border-bottom: 1px solid var(--band-rule);
}
/* A ~2.4:1 wordmark. It was being given width AND height of 62px, which
   squashed it into a square and stretched the artwork. Size by height and
   let the width follow; object-fit guards the case where max-width binds. */
.footer-logo {
  width: auto;
  height: clamp(58px, 7vw, 78px);
  max-width: min(100%, 300px);
  object-fit: contain;
  object-position: left center;
  margin-bottom: 1.25rem;
}
.footer h2 {
  font-size: clamp(2rem, 4vw, 3rem);
  line-height: 0.95;
  letter-spacing: -0.035em;
  text-transform: uppercase;
  margin: 0 0 0.8rem;
  color: var(--band-ink);
}
.footer p { color: var(--band-soft); max-width: 42ch; font-size: 0.94rem; }
.footer h3 {
  font-family: var(--font-body);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--band-soft);
  margin: 0 0 1.2rem;
}
.footer-list { list-style: none; margin: 0; padding: 0; }
.footer-list li { margin-bottom: 0.75rem; font-size: 0.94rem; color: var(--band-soft); }
.footer-list a,
.footer-credit a,
.social-links a {
  color: var(--band-ink);
  text-decoration: none;
  background-image: linear-gradient(var(--limone), var(--limone));
  background-size: 0% 1px;
  background-position: left bottom;
  background-repeat: no-repeat;
  padding-bottom: 2px;
  transition: background-size 0.4s var(--ease), color 0.3s var(--ease);
}
.footer-list a:hover,
.footer-credit a:hover,
.social-links a:hover { background-size: 100% 1px; color: var(--limone); }

.social-links {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  margin-top: 1.5rem;
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 1.75rem;
  font-size: 0.74rem;
  letter-spacing: 0.08em;
  color: var(--band-soft);
}
.footer-bottom em {
  font-family: var(--font-display);
  font-size: 1.05rem;
  letter-spacing: 0;
}

/* Copyright and studio credit share the left side and wrap together. */
.footer-legal {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35rem 0.9rem;
}
.footer-sep { opacity: 0.45; }

/* Silver Web Studio credit: the studio's own Inter wordmark and orb, the same
   as on the studio's other client sites. */
.footer-legal { align-items: center; }
.sws-credit {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  min-height: 44px;
  font: 400 13px/1.3 'Inter', system-ui, sans-serif;
  letter-spacing: -0.005em;
  color: var(--band-soft);
  text-decoration: none;
  transition: color 0.2s var(--ease);
}
.sws-credit:hover,
.sws-credit:focus-visible { color: var(--band-ink); }
.sws-credit__orb {
  width: 15px;
  height: 15px;
  flex: none;
  border-radius: 50%;
  background:
    radial-gradient(circle at 32% 28%, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0) 55%),
    conic-gradient(from 200deg, rgba(104, 236, 155, 0.9), rgba(255, 162, 18, 0.9), rgba(226, 54, 44, 0.9), rgba(150, 190, 238, 0.9), rgba(104, 236, 155, 0.9));
  transition: transform 0.4s cubic-bezier(0.2, 0.9, 0.25, 1.2);
}
.sws-credit:hover .sws-credit__orb { transform: rotate(180deg) scale(1.12); }
@media (prefers-reduced-motion: reduce) {
  .sws-credit:hover .sws-credit__orb { transform: none; }
}

/* ------------------------------------------------------------------
   18. SCROLL REVEAL + PAGE TRANSITION
   ------------------------------------------------------------------ */
/* One declarative vocabulary, driven by IntersectionObserver in site.js.
   Elements declare intent with [data-anim]; containers add [data-stagger]
   to cascade their children. Everything collapses under reduced motion.

     rise   copy and blocks lift into place
     fade   plain opacity, for things that shouldn't move
     clip   imagery wipes open from the bottom edge
     scale  imagery settles from a slight over-scale
     mask   headings rise word by word behind a mask
*/
.js [data-anim] {
  --anim-delay: calc(var(--i, 0) * 90ms + var(--reveal-delay, 0ms));
}

.js [data-anim="rise"],
.js .reveal {
  opacity: 0;
  transform: translateY(26px);
  transition:
    opacity 0.85s var(--ease) var(--anim-delay, var(--reveal-delay, 0ms)),
    transform 0.85s var(--ease) var(--anim-delay, var(--reveal-delay, 0ms));
}

.js [data-anim="fade"] {
  opacity: 0;
  transition: opacity 1s var(--ease) var(--anim-delay);
}

/* The clip lives on the child, never on the observed element itself: an
   element clipped to zero area reports no intersection, so the observer
   would never fire and the image would stay hidden for good. */
/* A frame drawn over a clipped image (the ::after line on the About photo)
   waits for the picture, then settles into place, instead of showing as an
   empty outline before the image has opened. */
.js [data-anim="clip"]::after {
  opacity: 0;
  transform: scale(0.94);
  transition:
    opacity 0.6s var(--ease) calc(var(--anim-delay) + 0.75s),
    transform 0.9s var(--ease) calc(var(--anim-delay) + 0.75s);
}
.js [data-anim="clip"].is-visible::after { opacity: 1; transform: none; }

.js [data-anim="scale"] {
  opacity: 0;
  transform: scale(1.05);
  transition:
    opacity 0.95s var(--ease) var(--anim-delay),
    transform 1.25s var(--ease) var(--anim-delay);
}

.js [data-anim="rule"],
.js .reveal-rule {
  transform: scaleX(0);
  transform-origin: left center;
  opacity: 1;
  transition: transform 0.95s var(--ease) var(--anim-delay, var(--reveal-delay, 0ms));
}

.js [data-anim].is-visible,
.js .reveal.is-visible { opacity: 1; transform: none; }
.js [data-anim="rule"].is-visible,
.js .reveal-rule.is-visible { transform: scaleX(1); }

/* Word-level mask reveal — site.js splits the heading into .word spans. */
/* Room below the baseline so descenders (y, g, j, p) clear the mask;
   the negative margin gives the space back, so line spacing is unchanged. */
.word {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  padding-bottom: 0.26em;
  margin-bottom: -0.26em;
}
.word > span { display: inline-block; }
.js [data-anim="mask"] .word > span {
  transform: translateY(105%);
  transition: transform 0.9s var(--ease);
  transition-delay: calc(var(--w, 0) * 55ms + var(--anim-delay, 0ms));
}
.js [data-anim="mask"].is-visible .word > span { transform: none; }

/* ------------------------------------------------------------------
   18b. LIVELIER REVEALS
   ------------------------------------------------------------------ */
/* 1. Photos open from the top behind a lemon edge while the picture
   settles from a slight zoom; a frame drawn over the photo traces in last
   (above). Built from sliding layers only (the GPU moves them), never a
   repainted clip: site.js wraps the contents in .reveal-frame, which
   slides down out of hiding while its contents slide the other way, so the
   picture itself stays put and the frame's bottom edge is the reveal line. */
.js [data-anim="clip"] { overflow: hidden; }
.js [data-anim="clip"] > .reveal-frame {
  position: relative;
  height: 100%;
  translate: 0 -101%;
  transition: translate 1.15s cubic-bezier(0.77, 0, 0.18, 1) var(--anim-delay);
}
.js [data-anim="clip"] > .reveal-frame > * {
  translate: 0 101%;
  transition:
    translate 1.15s cubic-bezier(0.77, 0, 0.18, 1) var(--anim-delay),
    scale 1.7s cubic-bezier(0.16, 1, 0.3, 1) var(--anim-delay);
}
.js [data-anim="clip"]:not(.is-visible) > .reveal-frame > img { scale: 1.1; }
.js [data-anim="clip"].is-visible > .reveal-frame,
.js [data-anim="clip"].is-visible > .reveal-frame > * { translate: 0 0; }
.js [data-anim="clip"] > .reveal-frame::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 3px;
  z-index: 2;
  background: var(--limone);
  box-shadow: 0 4px 16px 2px color-mix(in srgb, var(--limone) 55%, transparent);
  pointer-events: none;
  transition: opacity 0.45s var(--ease) calc(var(--anim-delay) + 0.95s);
}
.js [data-anim="clip"].is-visible > .reveal-frame::after { opacity: 0; }
/* The map's iframe fills its box absolutely, so its frame must too. */
.js .map-wrap > .reveal-frame { position: absolute; inset: 0; height: auto; }
/* A clipped block with its own border (the map) keeps the border back
   until its contents open, so it never shows as an empty outline. */
.js [data-anim="clip"]:not(.is-visible) { border-color: transparent; }
.js [data-anim="clip"] { transition: border-color 0.6s var(--ease) calc(var(--anim-delay) + 0.8s); }

/* Gallery tiles: settle from a zoom inside their frame as they fade up. */
.js .gallery-grid [data-anim="scale"] img {
  scale: 1.08;
  transition: scale 1.6s cubic-bezier(0.16, 1, 0.3, 1) var(--anim-delay);
}
.js .gallery-grid [data-anim="scale"].is-visible img { scale: 1; }

/* 2. Section headings: after the words rise, a short lemon rule draws
   in underneath. */
.section-title[data-anim="mask"]::after {
  content: "";
  display: block;
  width: 3.2rem;
  height: 2px;
  margin-top: 0.32em;
  background: var(--limone);
  transform-origin: left center;
}
.js .section-title[data-anim="mask"]::after {
  transform: scaleX(0);
  transition: transform 0.9s cubic-bezier(0.65, 0, 0.35, 1) calc(var(--anim-delay) + 0.45s);
}
.js .section-title[data-anim="mask"].is-visible::after { transform: scaleX(1); }

/* 3. Cards lift in and settle, one after another. */
.js :is(.card, .review, .testimonial-card, .contact-card, .dish-card)[data-anim="rise"] {
  transform: translateY(34px) scale(0.97);
  transition:
    opacity 0.8s var(--ease) var(--anim-delay),
    transform 1s cubic-bezier(0.16, 1, 0.3, 1) var(--anim-delay),
    background-color 0.45s var(--ease);
}
.js :is(.card, .review, .testimonial-card, .contact-card, .dish-card)[data-anim="rise"].is-visible {
  transform: none;
}

/* 5. Interior page openings: label, title, intro in sequence, timed to
   land just as the sweep clears. */
.js .page-header .meta,
.js .page-header .section-intro:not([data-anim]),
.js .page-header .page-title {
  animation: intro-rise 1s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.js .page-header .meta { animation-delay: calc(0.05s + var(--intro-delay, 0ms)); }
.js .page-header .page-title {
  animation-name: intro-title;
  animation-duration: 1.2s;
  animation-delay: calc(0.15s + var(--intro-delay, 0ms));
}
.js .page-header .section-intro:not([data-anim]) { animation-delay: calc(0.4s + var(--intro-delay, 0ms)); }
.js .page-header::after { animation: intro-tiles 1.8s var(--ease) calc(0.2s + var(--intro-delay, 0ms)) both; }

@keyframes intro-rise {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}
@keyframes intro-title {
  from { opacity: 0; transform: translateY(0.45em); }
  to   { opacity: 1; transform: none; }
}
@keyframes intro-tiles { from { opacity: 0; } }

/* 6. Photo bands: taller than their frame so the parallax drift never
   shows an edge. */
.photo-band .reveal-frame { height: 100%; }

@media (prefers-reduced-motion: reduce) {
  .js [data-anim="clip"] > .reveal-frame,
  .js [data-anim="clip"] > .reveal-frame > * { translate: none; scale: none; }
  .js .gallery-grid [data-anim="scale"] img { scale: none; }
  .js [data-anim="clip"] > .reveal-frame::after { display: none; }
  .js .section-title[data-anim="mask"]::after { transform: none; }
  .js .page-header .meta,
  .js .page-header .section-intro,
  .js .page-header .page-title,
  .js .page-header::after { animation: none; }
  .photo-band img { top: 0; height: 100%; }
}

.facts dd[data-count] { font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------------
   PAGE TRANSITION — the navy curtain
   Plain CSS animation; no cross-document view transitions (one crashed
   Safari on an iPhone). Following a link, a navy curtain with a lemon
   leading edge sweeps in from the direction of travel (pages further
   along the nav come from the right) and covers the page; site.js then
   navigates. The next page's <head> marks the arrival before its first
   paint, so it opens under the same curtain, which carries on across
   and out while the content drifts in after it. Reduced motion: none.
   ------------------------------------------------------------------ */
body.page-leaving::after,
html.arrive::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: var(--band);
  pointer-events: none;
}
body.page-leaving.swipe-next::after {
  border-left: 3px solid var(--limone);
  animation: curtain-in-next 0.42s cubic-bezier(0.7, 0, 0.25, 1) both;
}
body.page-leaving.swipe-prev::after {
  border-right: 3px solid var(--limone);
  animation: curtain-in-prev 0.42s cubic-bezier(0.7, 0, 0.25, 1) both;
}
html.arrive-next::after {
  border-right: 3px solid var(--limone);
  animation: curtain-out-next 0.7s cubic-bezier(0.22, 1, 0.36, 1) 0.06s both;
}
html.arrive-prev::after {
  border-left: 3px solid var(--limone);
  animation: curtain-out-prev 0.7s cubic-bezier(0.22, 1, 0.36, 1) 0.06s both;
}
/* The curtain carries the sideways motion; the content just settles up into
   place behind it (a vertical drift can never open a sideways scrollbar). */
html.arrive .site-main { animation: page-settle 0.9s cubic-bezier(0.22, 1, 0.36, 1) 0.06s both; }

@keyframes curtain-in-next  { from { translate: 101% 0; } to { translate: 0 0; } }
@keyframes curtain-in-prev  { from { translate: -101% 0; } to { translate: 0 0; } }
@keyframes curtain-out-next { from { translate: 0 0; } to { translate: -101% 0; } }
@keyframes curtain-out-prev { from { translate: 0 0; } to { translate: 101% 0; } }
@keyframes page-settle      { from { translate: 0 14px; } to { translate: 0 0; } }

@media (prefers-reduced-motion: reduce) {
  body.page-leaving::after,
  html.arrive::after { display: none; }
  html.arrive .site-main { animation: none; }
}

@keyframes page-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

body.nav-open { overflow: hidden; }

/* ------------------------------------------------------------------
   19. RESPONSIVE
   ------------------------------------------------------------------ */
/* The header used to drop straight from "everything" to "hamburger" at
   1080px. Just above that the brand, full nav, phone, toggle and Reserve
   button no longer fit and pushed the page sideways, so the bar now sheds
   one item at a time before it collapses. */
@media (max-width: 1460px) {
  .nav { gap: 1.4rem; }
}

@media (max-width: 1360px) {
  .header-phone { display: none; }
}

/* Order goes before Reserve: booking a table is the primary action, and
   Order online stays reachable from the menu page and the drawer. */
@media (max-width: 1260px) {
  .header-actions .btn-order { display: none; }
}

@media (max-width: 1140px) {
  .header-actions .btn-reserve { display: none; }
}

@media (max-width: 1080px) {
  .nav { display: none; }
  .nav-toggle { display: flex; }
  .hero-lower { grid-template-columns: 1fr; }
  .menu-category-head { grid-template-columns: 1fr; }
  .menu-category-intro.has-photo {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 96px;
    gap: 1rem;
    align-items: center;
  }
  .menu-photo { margin-top: 0; aspect-ratio: 1; width: 96px; }
}

@media (max-width: 860px) {
  .about-grid,
  .reservation-grid,
  .hours-location-grid { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .footer-grid > :first-child { grid-column: 1 / -1; }
  .dish-card { border-right: 0; }
  .hero-lemon { opacity: 0.1; top: 12%; }
}

/* The brand block is flex:none, so it cannot shrink its way out of an
   overflow. Below these widths it sheds the strap line, then the repeated
   name — the logo lockup already reads "Trattoria Sorrento" on its own. */
@media (max-width: 620px) {
  .brand-text { font-size: 1.1rem; }
  .brand img { height: 42px; }
  .header-inner { gap: 0.9rem; }
}

@media (max-width: 520px) {
  .brand-text,
  .brand-small { display: none; }
  .brand img { height: 44px; }
}

@media (max-width: 380px) {
  .brand img { height: 38px; }
  .header-inner { gap: 0.6rem; }
  .header-actions { gap: 0.5rem; }
}

@media (max-width: 760px) {
  .footer-sep { display: none; }
  .footer-legal { gap: 0.5rem; }
  .footer-legal > span { flex: 1 1 100%; }
}

@media (max-width: 560px) {
  .footer-grid { grid-template-columns: 1fr; }
  .brand-small { display: none; }
  .hero-meta { font-size: 0.62rem; }
  .facts div { border-right: 0; border-bottom: 1px solid var(--band-rule); }
  .testimonial-grid,
  .contact-grid { border-left: 0; }
  .testimonial-card,
  .contact-card { border-right: 0; }
}

/* ------------------------------------------------------------------
   20. REDUCED MOTION
   ------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  *,
  ::before,
  ::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .hero-title .line > span { transform: none; }
  .js .hero-fade { opacity: 1; }
  .hero-image { transform: none; }
  .marquee-track { animation: none; }
  .js [data-anim],
  .js [data-anim] > *,
  .js .reveal {
    opacity: 1;
    transform: none;
    clip-path: none;
  }
  .js [data-anim="mask"] .word > span { transform: none; }
  .js [data-anim="rule"],
  .js .reveal-rule { transform: scaleX(1); }
  .nav-drawer { transition: none; }
}

@media print {
  .header, .footer, .nav-drawer, .menu-jump, .tile-band { display: none !important; }
  body { background: #fff; color: #000; }
}

/* ------------------------------------------------------------------
   Menu footnotes — the small print carried over from the printed menu.
   ------------------------------------------------------------------ */
.menu-notes {
  max-width: 62ch;
  margin-inline: auto;
  text-align: center;
}

.menu-notes .italic-note + .italic-note {
  margin-top: 0.9rem;
}

/* ------------------------------------------------------------------
   Photo band — a full-width strip of one photograph, used to break up
   the longer pages. It sits between sections rather than inside them,
   so it never competes with the menu, the booking form, or the map.
   ------------------------------------------------------------------ */
.photo-band {
  position: relative;
  overflow: hidden;
  /* Tall enough to read as a photograph, not a sliver. */
  height: clamp(280px, 38vw, 560px);
  background: var(--notte);
}

/* Taller than its band (12% spare above and below) so the parallax drift
   in site.js, capped at that spare, never shows an edge. */
.photo-band img {
  display: block;
  position: absolute;
  left: 0;
  top: -12%;
  width: 100%;
  height: 124%;
  object-fit: cover;
  object-position: center;
  /* A touch softer than full strength so the band sits quietly between
     sections, while still reading clearly as the dish or the room. */
  filter: saturate(0.95) brightness(0.96);
}

/* The clip reveal animates the child, so the band needs no extra rules. */
@media (prefers-reduced-motion: reduce) {
  .photo-band img { filter: saturate(0.8) brightness(0.88); }
}

/* ------------------------------------------------------------------
   Reservation time quick picks. Dinner is only eight slots wide, so
   offering them all beats stepping through a native time input's
   hour / minute / AM-PM segments one at a time.
   ------------------------------------------------------------------ */
.time-picks {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.6rem;
}

.time-pick {
  font-family: var(--font-sans);
  font-size: 0.8rem;
  letter-spacing: 0.02em;
  padding: 0.38rem 0.7rem;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background 0.2s var(--ease), border-color 0.2s var(--ease), color 0.2s var(--ease);
}

.time-pick:hover { border-color: var(--limone); }

.time-pick:focus-visible {
  outline: 2px solid var(--limone);
  outline-offset: 2px;
}

.time-pick[aria-pressed="true"] {
  background: var(--limone);
  border-color: var(--limone);
  color: var(--notte);
}


/* ------------------------------------------------------------------
   Staff link. Sits in the footer boilerplate, quieter than the legal
   text beside it — plain to anyone looking for it, unremarkable to
   everyone else. The desk's own login is what actually guards it.
   ------------------------------------------------------------------ */
.footer-staff {
  color: inherit;
  opacity: 0.72;
  text-decoration: none;
}

.footer-staff:hover,
.footer-staff:focus-visible {
  opacity: 1;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ------------------------------------------------------------------
   A one-line pointer to the ordering links, at the top of the menu.
   Deliberately small and unboxed: most people reading the menu are
   coming in, so it should read as an aside, not an advert.
   ------------------------------------------------------------------ */
.menu-takeaway {
  margin-top: 1.25rem;
  font-size: 0.95rem;
  color: var(--ink-soft);
}

.menu-takeaway a {
  color: var(--link);
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  padding-bottom: 1px;
}

.menu-takeaway a::after {
  content: " \2193";          /* points down, because that is where it goes */
  letter-spacing: 0.05em;
}

.menu-takeaway a:hover,
.menu-takeaway a:focus-visible {
  color: var(--link-hover);
}

/* The jump lands the section under the sticky header rather than behind it. */
#order-online {
  scroll-margin-top: 5.5rem;
}

/* Reviews — real Google quotes, credited */
.reviews-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: 1.25rem;
}
.review { margin: 0; display: flex; flex-direction: column; gap: 0.9rem; }
.review__stars { margin: 0; color: var(--accent); letter-spacing: 0.15em; }
.review blockquote { margin: 0; font-size: 1.05rem; line-height: 1.55; flex: 1; }
.review figcaption { font-size: 0.9rem; color: var(--ink-soft); }
.review figcaption a { color: inherit; }

/* Instagram / Facebook brand icons */
.social-links { align-items: center; }
.social-links a.social-icon { background-image: none; padding: 0; display: inline-flex; transition: transform 0.3s var(--ease); }
.social-links a.social-icon:hover { transform: translateY(-2px); }
.social-icon img { width: 28px; height: 28px; display: block; }
.social-row { display: flex; align-items: center; gap: 0.6rem; margin-top: 0.5rem; }
.social-row img { width: 24px; height: 24px; flex: none; }
