/*
  HANGry Bếp — Global stylesheet
  Scoped under .hbp-site for safe GHL embedding. All custom classes use the
  hbp- prefix. Do not select bare body/a/button/img/h1 etc. outside this scope.
*/

/* ---------------------------------------------------------------------- */
/* Fonts                                                                   */
/* ---------------------------------------------------------------------- */
@import url('https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,400;0,9..144,500;0,9..144,600;0,9..144,700;1,9..144,500&family=Inter:wght@400;500;600;700&display=swap');

/* ---------------------------------------------------------------------- */
/* Design tokens                                                          */
/* ---------------------------------------------------------------------- */
.hbp-site {
  /* Brand colours — extracted from approved logo artwork */
  --hbp-orange: #D77930;
  --hbp-orange-ink: #7A3E14;   /* darker orange step, for text-on-orange edge cases */
  --hbp-red: #95242D;
  --hbp-cyan: #59BCDF;
  --hbp-cyan-deep: #2E90B3;    /* darker cyan step, for AA text/icons on light bg */

  /* Neutral system — warm, complements the logo rather than competing with it */
  --hbp-cream: #FBF3E7;        /* page background */
  --hbp-surface: #F3E6D3;      /* card / muted surface background */
  --hbp-surface-2: #EAD9C0;    /* deeper muted surface, section alternation */
  --hbp-ink: #26170F;          /* near-black warm charcoal, primary text */
  --hbp-ink-soft: #5B4A3F;     /* secondary text on light backgrounds */
  --hbp-white: #FFFFFF;
  --hbp-line: rgba(38, 23, 15, 0.12);

  /* Type */
  --hbp-font-display: 'Fraunces', ui-serif, Georgia, serif;
  --hbp-font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --hbp-fs-body: clamp(1rem, 0.96rem + 0.15vw, 1.0625rem);
  --hbp-fs-small: 0.875rem;
  --hbp-fs-h1: clamp(2.5rem, 2rem + 3vw, 4.75rem);
  --hbp-fs-h2: clamp(1.875rem, 1.6rem + 1.5vw, 2.75rem);
  --hbp-fs-h3: clamp(1.375rem, 1.2rem + 0.8vw, 1.75rem);
  --hbp-fs-eyebrow: 0.8125rem;

  /* Spacing scale (4px base) */
  --hbp-sp-1: 0.25rem;
  --hbp-sp-2: 0.5rem;
  --hbp-sp-3: 0.75rem;
  --hbp-sp-4: 1rem;
  --hbp-sp-6: 1.5rem;
  --hbp-sp-8: 2rem;
  --hbp-sp-12: 3rem;
  --hbp-sp-16: 4rem;
  --hbp-sp-24: 6rem;
  --hbp-sp-32: 8rem;

  --hbp-container: 1240px;
  --hbp-gutter: clamp(1.25rem, 4vw, 3rem);

  /* Radii — controlled rounding, not a pill-button site */
  --hbp-radius-sm: 6px;
  --hbp-radius-md: 14px;
  --hbp-radius-lg: 28px;
  --hbp-radius-full: 999px;

  /* Signature elevation: a solid offset duplicate (not a blurred drop-shadow),
     directly derived from the logo's cyan directional offset. This is the
     one device that should recur everywhere something needs to feel "lifted". */
  --hbp-offset-x: 8px;
  --hbp-offset-y: 8px;
  --hbp-offset-color: var(--hbp-cyan);

  /* Motion */
  --hbp-ease: cubic-bezier(0.16, 1, 0.3, 1);
  --hbp-dur-fast: 180ms;
  --hbp-dur-med: 420ms;
  --hbp-dur-slow: 720ms;
}

/* ---------------------------------------------------------------------- */
/* Reset (scoped)                                                          */
/* ---------------------------------------------------------------------- */
.hbp-site, .hbp-site * , .hbp-site *::before, .hbp-site *::after {
  box-sizing: border-box;
}
/* No horizontal-overflow guard here on purpose. A `html, body` rule would be
   the one truly unscoped, GHL-unsafe selector in this file — GHL pastes this
   page into a shared environment, and a bare html/body rule leaks onto
   whatever else lives on that page. It also isn't needed: verified at 375px,
   768px and 1400px with no overflow present. An earlier version of this rule
   caused a real bug — overflow other than 'visible' on an ancestor of a
   position:sticky element makes browsers treat that ancestor as the sticky
   containing scroll-context instead of the real viewport, silently breaking
   every sticky element on the page (header, etc.) — so if overflow genuinely
   needs guarding later, fix the specific overflowing element rather than
   reaching for this again. */

.hbp-site {
  background: var(--hbp-cream);
  color: var(--hbp-ink);
  font-family: var(--hbp-font-body);
  font-size: var(--hbp-fs-body);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
.hbp-site img { max-width: 100%; display: block; }
.hbp-site a { color: inherit; text-decoration: none; }
.hbp-site ul { list-style: none; margin: 0; padding: 0; }
.hbp-site button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
.hbp-site h1, .hbp-site h2, .hbp-site h3, .hbp-site h4 {
  font-family: var(--hbp-font-display);
  font-weight: 600;
  line-height: 1.08;
  margin: 0;
  color: var(--hbp-ink);
}
.hbp-site p { margin: 0; }

.hbp-site .hbp-container {
  width: 100%;
  max-width: var(--hbp-container);
  margin-inline: auto;
  padding-inline: var(--hbp-gutter);
}

.hbp-site .hbp-visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

/* Skip link — required for keyboard-accessible navigation (brief §15), but
   must never be visible to a mouse/touch visitor. Uses the same clip-based
   visually-hidden technique as the contact form's honeypot (proven robust)
   rather than a large negative `top` offset, which is easier for an
   unfamiliar host environment's own CSS to override or interact with
   unpredictably. On :focus it switches to position:fixed so it always
   appears relative to the viewport regardless of scroll position. */
.hbp-site .hbp-skip-link {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
  background: var(--hbp-ink);
  color: var(--hbp-white);
  z-index: 200;
}
.hbp-site .hbp-skip-link:focus {
  position: fixed;
  left: var(--hbp-sp-4);
  top: var(--hbp-sp-4);
  width: auto;
  height: auto;
  padding: var(--hbp-sp-3) var(--hbp-sp-4);
  margin: 0;
  overflow: visible;
  clip: auto;
  white-space: normal;
  border-radius: var(--hbp-radius-sm);
}

/* Focus visibility — never remove, only restyle */
.hbp-site a:focus-visible,
.hbp-site button:focus-visible,
.hbp-site input:focus-visible,
.hbp-site textarea:focus-visible,
.hbp-site select:focus-visible {
  outline: 3px solid var(--hbp-cyan-deep);
  outline-offset: 3px;
  border-radius: var(--hbp-radius-sm);
}

/* ---------------------------------------------------------------------- */
/* Eyebrow / small labels                                                  */
/* ---------------------------------------------------------------------- */
.hbp-site .hbp-eyebrow {
  font-size: var(--hbp-fs-eyebrow);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--hbp-red);
}

/* ---------------------------------------------------------------------- */
/* Signature system: Offset Bowl                                          */
/* A solid cyan offset duplicate stands in for drop-shadows across the     */
/* site. Applied to media frames, cards and primary buttons.               */
/* ---------------------------------------------------------------------- */
.hbp-site .hbp-offset {
  position: relative;
}
.hbp-site .hbp-offset::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--hbp-offset-color);
  border-radius: inherit;
  transform: translate(var(--hbp-offset-x), var(--hbp-offset-y));
  z-index: -1;
  transition: transform var(--hbp-dur-med) var(--hbp-ease);
}
/* Images are wrapped in <picture> for the webp/jpg fallback, so this has to
   be a descendant selector (not a direct-child one) to actually reach the
   img — a direct-child selector here would silently skip every picture>img
   pair on the page and leave the image unsized. */
.hbp-site .hbp-offset picture,
.hbp-site .hbp-offset > .hbp-offset-fill {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  overflow: hidden; /* clips the hover zoom below without touching ::before, which lives on .hbp-offset itself, one level up */
}
.hbp-site .hbp-offset picture img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--hbp-dur-med) var(--hbp-ease);
}
@media (hover: hover) {
  .hbp-site .hbp-offset:hover::before,
  .hbp-site .hbp-offset:focus-within::before {
    transform: translate(calc(var(--hbp-offset-x) * 1.4), calc(var(--hbp-offset-y) * 1.4));
  }
  .hbp-site .hbp-offset:hover picture img,
  .hbp-site .hbp-offset:focus-within picture img {
    transform: scale(1.06);
  }
}

/* Bowl-arc divider — replaces a straight section edge with the logo's bowl
   curve. Used sparingly between major homepage moments. */
.hbp-site .hbp-arc-divider {
  display: block;
  width: 100%;
  height: clamp(36px, 6vw, 96px);
  line-height: 0;
}
.hbp-site .hbp-arc-divider svg { width: 100%; height: 100%; display: block; }

/* ---------------------------------------------------------------------- */
/* Buttons                                                                 */
/* ---------------------------------------------------------------------- */
.hbp-site .hbp-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--hbp-sp-2);
  padding: 0.9rem 1.6rem;
  border-radius: var(--hbp-radius-sm);
  font-weight: 700;
  font-size: 0.9375rem;
  letter-spacing: 0.01em;
  white-space: nowrap;
  transition: transform var(--hbp-dur-fast) var(--hbp-ease), background var(--hbp-dur-fast) var(--hbp-ease);
}
.hbp-site .hbp-btn-primary {
  background: var(--hbp-red);
  color: var(--hbp-white);
  position: relative;
}
.hbp-site .hbp-btn-primary::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--hbp-cyan);
  transform: translate(5px, 5px);
  z-index: -1;
  transition: transform var(--hbp-dur-fast) var(--hbp-ease);
}
.hbp-site .hbp-btn-primary:hover::before,
.hbp-site .hbp-btn-primary:focus-visible::before { transform: translate(8px, 8px); }
.hbp-site .hbp-btn-primary:hover,
.hbp-site .hbp-btn-primary:focus-visible { transform: translate(-2px, -2px); }

.hbp-site .hbp-btn-secondary {
  background: transparent;
  color: var(--hbp-ink);
  border: 2px solid var(--hbp-ink);
}
.hbp-site .hbp-btn-secondary:hover { background: var(--hbp-ink); color: var(--hbp-white); }

.hbp-site .hbp-btn-ghost-light {
  background: transparent;
  color: var(--hbp-white);
  border: 2px solid rgba(255,255,255,0.7);
}
.hbp-site .hbp-btn-ghost-light:hover { background: rgba(255,255,255,0.14); border-color: var(--hbp-white); }

/* ---------------------------------------------------------------------- */
/* Header                                                                  */
/* ---------------------------------------------------------------------- */
.hbp-site .hbp-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(251, 243, 231, 0.92);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--hbp-line);
}
.hbp-site .hbp-header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--hbp-sp-4);
  padding-block: var(--hbp-sp-3);
}
.hbp-site .hbp-logo-link { display: inline-flex; align-items: center; }
.hbp-site .hbp-logo-link img { height: clamp(34px, 4vw, 46px); width: auto; }

.hbp-site .hbp-nav { display: flex; align-items: center; gap: var(--hbp-sp-8); }
.hbp-site .hbp-nav-links { display: flex; gap: var(--hbp-sp-6); }
.hbp-site .hbp-nav-links a {
  font-weight: 600;
  font-size: 0.9375rem;
  padding: var(--hbp-sp-2) 0;
  border-bottom: 2px solid transparent;
  transition: border-color var(--hbp-dur-fast) var(--hbp-ease), color var(--hbp-dur-fast) var(--hbp-ease);
}
.hbp-site .hbp-nav-links a:hover,
.hbp-site .hbp-nav-links a[aria-current="page"] {
  border-color: var(--hbp-red);
  color: var(--hbp-red);
}

.hbp-site .hbp-header-actions { display: flex; align-items: center; gap: var(--hbp-sp-4); }
.hbp-site .hbp-menu-toggle {
  display: none;
  padding: var(--hbp-sp-2);
  border-radius: var(--hbp-radius-sm);
}
.hbp-site .hbp-menu-toggle svg { width: 26px; height: 26px; }

.hbp-site .hbp-mobile-nav {
  position: fixed;
  inset: 0;
  z-index: 150;
  background: var(--hbp-cream);
  display: flex;
  flex-direction: column;
  padding: var(--hbp-sp-4) var(--hbp-gutter) var(--hbp-sp-8);
  transform: translateY(-100%);
  transition: transform var(--hbp-dur-med) var(--hbp-ease);
}
.hbp-site .hbp-mobile-nav[data-open="true"] { transform: translateY(0); }
.hbp-site .hbp-mobile-nav-top { display: flex; align-items: center; justify-content: space-between; }
.hbp-site .hbp-mobile-nav-links { margin-top: var(--hbp-sp-12); display: flex; flex-direction: column; gap: var(--hbp-sp-6); }
.hbp-site .hbp-mobile-nav-links a { font-family: var(--hbp-font-display); font-size: var(--hbp-fs-h3); font-weight: 600; }
.hbp-site .hbp-mobile-nav-cta { margin-top: var(--hbp-sp-12); }

@media (max-width: 860px) {
  .hbp-site .hbp-nav-links,
  .hbp-site .hbp-header-actions .hbp-btn { display: none; }
  .hbp-site .hbp-menu-toggle { display: inline-flex; }
}

/* ---------------------------------------------------------------------- */
/* Coming soon ribbon                                                      */
/* ---------------------------------------------------------------------- */
/* Continuous marquee: two identical, back-to-back groups of the message,
   the whole track animated left by exactly 50% of its own width — since
   the groups are identical, the loop point is invisible. The second group
   is aria-hidden (decorative repetition only; the first group already
   carries the real, announced text). Reduced motion gets a plain static
   bar instead (no scroll, no duplicate group shown). */
.hbp-site .hbp-coming-soon-bar {
  background: var(--hbp-ink);
  color: var(--hbp-white);
  overflow: hidden;
}
.hbp-site .hbp-coming-soon-track {
  display: flex;
  width: max-content;
  animation: hbp-marquee 24s linear infinite;
  animation-play-state: paused; /* held at translateX(0) until webfonts
    finish loading — Inter isn't ready on first paint, and swapping it in
    mid-animation changes this track's max-content width, which snaps the
    running -50% transform to a new pixel value and reads as a visible
    jump/reset. site.js starts it once document.fonts.ready resolves. */
}
.hbp-site.hbp-fonts-ready .hbp-coming-soon-track {
  animation-play-state: running;
}
.hbp-site .hbp-coming-soon-group { display: flex; }
.hbp-site .hbp-coming-soon-item {
  /* inline-block, not inline-flex: flexbox turns the <strong> and the text
     that follows it into separate flex items, and flex's whitespace
     handling strips the leading space off that second (text-only) item —
     "Coming soon" and "to Prospect..." would visually run together despite
     a real space in the HTML. */
  display: inline-block;
  font-size: var(--hbp-fs-small);
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
  padding-block: var(--hbp-sp-2);
  padding-inline: var(--hbp-sp-12); /* generous space between repeats */
}
.hbp-site .hbp-coming-soon-item strong { color: var(--hbp-cyan); }

@keyframes hbp-marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .hbp-site .hbp-coming-soon-track { animation: none; }
  .hbp-site .hbp-coming-soon-bar { text-align: center; }
  .hbp-site .hbp-coming-soon-group[aria-hidden="true"] { display: none; }
  .hbp-site .hbp-coming-soon-item { padding-inline: var(--hbp-gutter); white-space: normal; }
}
.hbp-site.hbp-no-js .hbp-coming-soon-track { animation: none; }
.hbp-site.hbp-no-js .hbp-coming-soon-bar { text-align: center; }
.hbp-site.hbp-no-js .hbp-coming-soon-group[aria-hidden="true"] { display: none; }
.hbp-site.hbp-no-js .hbp-coming-soon-item { padding-inline: var(--hbp-gutter); white-space: normal; }

/* ---------------------------------------------------------------------- */
/* Hero                                                                    */
/* Image, location badge, subtext and CTAs are all visible immediately —   */
/* per brief §12/§20, nothing here may delay reaching Menu/Directions.      */
/* (An earlier version of this hero blocked scroll entirely until a poster  */
/* reveal finished; reverted 2026-09-06 as the wrong call for a brand built  */
/* on urgency — see chat. The headline's letter-by-letter entrance below is */
/* now a purely cosmetic, non-blocking flourish: it plays once on load and  */
/* never touches scroll.) */
.hbp-site .hbp-hero-scroll {
  position: relative;
}
.hbp-site .hbp-hero {
  position: relative;
  min-height: min(92vh, 920px);
  display: flex;
  align-items: flex-end;
  overflow: hidden;
}
.hbp-site .hbp-hero-media { position: absolute; inset: 0; z-index: 0; }
.hbp-site .hbp-hero-media img {
  width: 100%; height: 100%; object-fit: cover; object-position: center 62%;
}
.hbp-site .hbp-hero-scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(38,23,15,0.32) 0%, rgba(38,23,15,0.40) 38%, rgba(38,23,15,0.72) 68%, rgba(38,23,15,0.94) 100%);
}
.hbp-site .hbp-hero-content {
  position: relative;
  z-index: 1;
  color: var(--hbp-white);
  padding-block: var(--hbp-sp-16) var(--hbp-sp-12);
  width: 100%;
}
.hbp-site .hbp-hero-location {
  display: inline-flex;
  align-items: center;
  gap: var(--hbp-sp-2);
  background: rgba(255,255,255,0.12);
  border: 1px solid rgba(255,255,255,0.35);
  padding: var(--hbp-sp-2) var(--hbp-sp-4);
  border-radius: var(--hbp-radius-full);
  font-size: var(--hbp-fs-small);
  font-weight: 600;
  margin-bottom: var(--hbp-sp-6);
}
.hbp-site .hbp-hero-title {
  font-size: var(--hbp-fs-h1);
  max-width: 16ch;
  text-wrap: balance;
  text-shadow: 0 2px 24px rgba(0,0,0,0.35);
  color: var(--hbp-white); /* overrides the global h1 ink colour — hero sits on a photo, not the page background */
}
.hbp-site .hbp-hero-title em {
  font-style: italic;
  color: var(--hbp-cyan);
}


/* Per-letter entrance — cosmetic only, plays once on load, never gates
   scroll or the CTAs. JS wraps each visible character in a .hbp-letter span
   carrying --i (its index), then adds .hbp-letters-in to the H1 a tick
   later to trigger this transition; --i staggers each letter's delay so
   they cascade left-to-right instead of all firing at once. A single
   .hbp-sr-only sibling (added by the same JS) carries the real sentence for
   assistive tech, since every .hbp-letter is aria-hidden. */
.hbp-site .hbp-letter {
  display: inline-block;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.45s var(--hbp-ease), transform 0.45s var(--hbp-ease);
  transition-delay: calc(var(--i, 0) * 26ms);
}
.hbp-site .hbp-hero-title.hbp-letters-in .hbp-letter {
  opacity: 1;
  transform: translateY(0);
}
.hbp-site .hbp-sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
  border: 0;
}

/* Reduced motion / no JS: the letter split never happens at all (see
   js/site.js's guard), so the headline just renders as plain, immediately-
   visible text with the <em> colour rule further up still applying. Nothing
   else to override here. */
.hbp-site .hbp-hero-sub {
  margin-top: var(--hbp-sp-4);
  max-width: 46ch;
  font-size: clamp(1rem, 0.94rem + 0.3vw, 1.1875rem);
  color: rgba(255,255,255,0.92);
  text-shadow: 0 1px 12px rgba(0,0,0,0.4);
}
.hbp-site .hbp-hero-actions {
  margin-top: var(--hbp-sp-8);
  display: flex;
  flex-wrap: wrap;
  gap: var(--hbp-sp-4);
}

/* ---------------------------------------------------------------------- */
/* Section rhythm helpers                                                  */
/* ---------------------------------------------------------------------- */
.hbp-site .hbp-section { padding-block: var(--hbp-sp-24); }
.hbp-site .hbp-section-alt { background: var(--hbp-surface); }
.hbp-site .hbp-section-head {
  max-width: 62ch;
  margin-bottom: var(--hbp-sp-12);
}
.hbp-site .hbp-section-head h2 { margin-top: var(--hbp-sp-3); }
.hbp-site .hbp-section-head p { margin-top: var(--hbp-sp-4); color: var(--hbp-ink-soft); font-size: 1.0625rem; }

/* ---------------------------------------------------------------------- */
/* Signature food introduction                                             */
/* ---------------------------------------------------------------------- */
/* Elastic gallery: one photo opens wide while the rest narrow to slivers.
   Pure flex-grow transition, so it works in either direction — a row on
   desktop, a column on mobile. Activated by hover (mouse), click/tap, or
   keyboard focus; see js/site.js. */
.hbp-site .hbp-elastic {
  display: flex;
  gap: var(--hbp-sp-3);
  height: clamp(420px, 52vw, 560px);
}
.hbp-site .hbp-elastic-item {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  min-height: 0;
  border-radius: var(--hbp-radius-lg);
  overflow: hidden;
  background: var(--hbp-ink);
  transition: flex-grow 640ms var(--hbp-ease);
}
.hbp-site .hbp-elastic-item[data-active="true"] { flex-grow: 6; }
.hbp-site .hbp-elastic-item picture,
.hbp-site .hbp-elastic-item img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.hbp-site .hbp-elastic-item img {
  transform: scale(1.1);
  transition: transform 900ms var(--hbp-ease);
}
.hbp-site .hbp-elastic-item[data-active="true"] img { transform: scale(1); }
.hbp-site .hbp-elastic-item::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(38, 23, 15, 0.38);
  transition: background 640ms var(--hbp-ease);
  pointer-events: none;
}
.hbp-site .hbp-elastic-item[data-active="true"]::after {
  background: linear-gradient(to top, rgba(38, 23, 15, 0.86) 0%, rgba(38, 23, 15, 0.35) 42%, rgba(38, 23, 15, 0) 70%);
}
.hbp-site .hbp-elastic-toggle {
  position: absolute;
  inset: 0;
  z-index: 2;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.hbp-site .hbp-elastic-item[data-active="true"] .hbp-elastic-toggle { pointer-events: none; }
.hbp-site .hbp-elastic-toggle:focus-visible { outline: 3px solid var(--hbp-cyan); outline-offset: -6px; }
.hbp-site .hbp-elastic-label {
  position: absolute;
  left: 50%;
  bottom: var(--hbp-sp-6);
  transform: translateX(-50%) rotate(180deg);
  writing-mode: vertical-rl;
  white-space: nowrap;
  color: var(--hbp-white);
  font-weight: 600;
  font-size: 0.9375rem;
  letter-spacing: 0.02em;
  text-shadow: 0 1px 8px rgba(38, 23, 15, 0.6);
  transition: opacity 280ms var(--hbp-ease);
}
.hbp-site .hbp-elastic-item[data-active="true"] .hbp-elastic-label { opacity: 0; }
.hbp-site .hbp-elastic-body {
  position: absolute;
  z-index: 3;
  left: var(--hbp-sp-6);
  bottom: var(--hbp-sp-6);
  width: 20rem;
  max-width: calc(100% - 2 * var(--hbp-sp-6));
  color: var(--hbp-white);
  opacity: 0;
  visibility: hidden;
  transform: translateY(14px);
  transition: opacity 240ms var(--hbp-ease), transform 240ms var(--hbp-ease), visibility 0s 240ms;
}
.hbp-site .hbp-elastic-item[data-active="true"] .hbp-elastic-body {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 420ms var(--hbp-ease) 220ms, transform 520ms var(--hbp-ease) 220ms, visibility 0s;
}
.hbp-site .hbp-elastic-chip {
  display: inline-block;
  padding: 0.2rem 0.75rem;
  border: 1px solid rgba(255, 255, 255, 0.7);
  border-radius: var(--hbp-radius-full);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.hbp-site .hbp-elastic-body h3 { margin-top: var(--hbp-sp-3); color: var(--hbp-white); font-size: var(--hbp-fs-h3); }
.hbp-site .hbp-elastic-sub { margin-top: var(--hbp-sp-1); color: rgba(255, 255, 255, 0.82); font-size: 0.9375rem; }
.hbp-site .hbp-elastic-body .hbp-btn { margin-top: var(--hbp-sp-4); }
.hbp-site .hbp-menu-link-row { margin-top: var(--hbp-sp-12); text-align: center; }

@media (max-width: 700px) {
  .hbp-site .hbp-elastic { flex-direction: column; height: 780px; }
  .hbp-site .hbp-elastic-label {
    left: var(--hbp-sp-4);
    top: 50%;
    bottom: auto;
    transform: translateY(-50%);
    writing-mode: horizontal-tb;
  }
  .hbp-site .hbp-elastic-body { width: auto; left: var(--hbp-sp-4); right: var(--hbp-sp-4); bottom: var(--hbp-sp-4); max-width: none; }
}
@media (prefers-reduced-motion: reduce) {
  .hbp-site .hbp-elastic-item,
  .hbp-site .hbp-elastic-item img,
  .hbp-site .hbp-elastic-item::after,
  .hbp-site .hbp-elastic-label,
  .hbp-site .hbp-elastic-body { transition: none; }
}

/* ---------------------------------------------------------------------- */
/* Family story teaser                                                     */
/* ---------------------------------------------------------------------- */
.hbp-site .hbp-story {
  display: grid;
  grid-template-columns: 0.9fr 1.1fr;
  gap: var(--hbp-sp-24);
  align-items: center;
}
.hbp-site .hbp-story-media { aspect-ratio: 4 / 5; border-radius: var(--hbp-radius-lg); max-width: 480px; }
.hbp-site .hbp-story-content .hbp-eyebrow { display: block; margin-bottom: var(--hbp-sp-3); }
.hbp-site .hbp-story-content h2 { margin-top: var(--hbp-sp-2); }
.hbp-site .hbp-story-content p { margin-top: var(--hbp-sp-6); font-size: 1.0625rem; color: var(--hbp-ink-soft); max-width: 52ch; }
.hbp-site .hbp-story-content .hbp-btn { margin-top: var(--hbp-sp-8); }
.hbp-site .hbp-story-placeholder-note {
  margin-top: var(--hbp-sp-4);
  font-size: var(--hbp-fs-small);
  color: var(--hbp-cyan-deep);
  font-style: italic;
}

@media (max-width: 900px) {
  .hbp-site .hbp-story { grid-template-columns: 1fr; gap: var(--hbp-sp-8); }
  .hbp-site .hbp-story-media { max-width: 100%; aspect-ratio: 4 / 3; }
}

/* ---------------------------------------------------------------------- */
/* Booking popup — Toast reservations widget in a native <dialog>          */
/* ---------------------------------------------------------------------- */
.hbp-site .hbp-booking-modal {
  width: min(92vw, 560px);
  max-height: 90vh;
  margin: auto;
  padding: 0;
  border: 0;
  border-radius: var(--hbp-radius-lg);
  background: var(--hbp-cream);
  color: var(--hbp-ink);
  overflow: auto;
  box-shadow: 0 24px 60px rgba(38, 23, 15, 0.35);
}
.hbp-site .hbp-booking-modal::backdrop { background: rgba(38, 23, 15, 0.62); }
.hbp-site .hbp-booking-modal-inner { position: relative; padding: var(--hbp-sp-8) var(--hbp-sp-6) var(--hbp-sp-6); }
.hbp-site .hbp-booking-modal h2 { padding-right: 3rem; margin-bottom: var(--hbp-sp-4); }
.hbp-site .hbp-booking-close {
  position: absolute;
  top: var(--hbp-sp-3);
  right: var(--hbp-sp-3);
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--hbp-radius-full);
  background: transparent;
  color: var(--hbp-ink);
  cursor: pointer;
}
.hbp-site .hbp-booking-close:hover { background: var(--hbp-surface); }
.hbp-site .hbp-booking-fallback { margin-top: var(--hbp-sp-4); font-size: var(--hbp-fs-small); color: var(--hbp-ink-soft); }

/* ---------------------------------------------------------------------- */
/* About page — real counter photo                                         */
/* ---------------------------------------------------------------------- */
.hbp-site .hbp-about-photo-section { padding-top: 0; }
.hbp-site .hbp-about-photo { max-width: 920px; margin-inline: auto; }
.hbp-site .hbp-about-photo picture {
  display: block;
  aspect-ratio: 16 / 10;
  border-radius: var(--hbp-radius-lg);
  overflow: hidden;
}
.hbp-site .hbp-about-photo img { width: 100%; height: 100%; object-fit: cover; }
.hbp-site .hbp-about-photo figcaption {
  margin-top: var(--hbp-sp-4);
  text-align: center;
  font-size: var(--hbp-fs-small);
  color: var(--hbp-ink-soft);
}

/* ---------------------------------------------------------------------- */
/* About page — intro block and pull-quote                                */
/* ---------------------------------------------------------------------- */
.hbp-site .hbp-about-intro {
  max-width: 62ch;
  text-align: center;
}
.hbp-site .hbp-about-lead {
  margin-top: var(--hbp-sp-6);
  font-size: clamp(1.125rem, 1.02rem + 0.4vw, 1.375rem);
  color: var(--hbp-ink-soft);
}
.hbp-site .hbp-about-quote {
  margin: 0;
  padding-left: var(--hbp-sp-8);
  border-left: 4px solid var(--hbp-cyan);
}
.hbp-site .hbp-about-quote p {
  font-family: var(--hbp-font-display);
  font-size: var(--hbp-fs-h3);
  font-weight: 500;
  line-height: 1.35;
  color: var(--hbp-ink);
}
.hbp-site .hbp-about-quote em {
  font-style: italic;
  color: var(--hbp-red);
}
@media (max-width: 700px) {
  .hbp-site .hbp-about-quote { padding-left: var(--hbp-sp-4); }
}

/* ---------------------------------------------------------------------- */
/* Brand / experience moment — scroll-linked "steam" hero moment          */
/* One deliberate scroll interaction, per brief section 12. Short pin      */
/* budget (not a full scroll-hijack), purely transform/opacity driven by   */
/* a single CSS custom property (--hbp-p, 0→1) that JS updates on scroll.  */
/* Falls back to the plain static layout entirely under reduced-motion.    */
/* ---------------------------------------------------------------------- */
/* PARKED (2026-09-04, at the user's request): the pin/zoom/steam interaction
   below is fully built but temporarily disabled — rendered as a plain static
   section instead. Re-enable by restoring height:200vh here and
   position:sticky on the stage below, and re-adding data-hbp-scroll-moment /
   data-hbp-scroll-moment-stage attributes in index.html (currently removed
   so js/site.js's init skips it). See js/site.js for the matching guard. */
.hbp-site .hbp-scroll-moment {
  position: relative;
  height: auto;
}
.hbp-site .hbp-scroll-moment-stage {
  position: static;
  height: auto;
  min-height: 480px;
  border-radius: var(--hbp-radius-lg);
  overflow: hidden;
  display: flex;
  align-items: center;
  color: var(--hbp-white);
}
.hbp-site .hbp-moment-media { position: absolute; inset: 0; }
.hbp-site .hbp-moment-media img {
  width: 100%; height: 100%; object-fit: cover;
  transform: scale(calc(1 + 0.14 * var(--hbp-p, 0)));
  will-change: transform;
}
.hbp-site .hbp-moment-scrim {
  position: absolute; inset: 0;
  background: linear-gradient(120deg, rgba(149,36,45,0.82), rgba(38,23,15,0.55));
  opacity: calc(0.85 + 0.15 * var(--hbp-p, 0));
}

/* Steam — soft blurred blobs rising off the hot plate as you scroll */
.hbp-site .hbp-moment-steam {
  position: absolute;
  pointer-events: none;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255,255,255,0.9) 0%, rgba(255,255,255,0) 70%);
  filter: blur(18px);
  opacity: calc(var(--hbp-p, 0) * 0.75);
}
.hbp-site .hbp-moment-steam-1 { width: 160px; height: 220px; left: 22%; bottom: 30%; transform: translateY(calc(30px - 140px * var(--hbp-p, 0))) scale(calc(0.8 + 0.5 * var(--hbp-p, 0))); }
.hbp-site .hbp-moment-steam-2 { width: 120px; height: 180px; left: 46%; bottom: 22%; transform: translateY(calc(20px - 170px * var(--hbp-p, 0))) scale(calc(0.7 + 0.6 * var(--hbp-p, 0))); }
.hbp-site .hbp-moment-steam-3 { width: 140px; height: 200px; left: 68%; bottom: 28%; transform: translateY(calc(24px - 150px * var(--hbp-p, 0))) scale(calc(0.75 + 0.55 * var(--hbp-p, 0))); }

.hbp-site .hbp-moment-content {
  position: relative;
  z-index: 1;
  padding: var(--hbp-sp-16);
  max-width: 40ch;
  opacity: calc(min(var(--hbp-p, 0) * 2.2, 1));
  transform: translateY(calc(20px - 20px * min(var(--hbp-p, 0) * 2.2, 1)));
}
.hbp-site .hbp-moment-content h2 { color: var(--hbp-white); }
.hbp-site .hbp-moment-content p { margin-top: var(--hbp-sp-4); color: rgba(255,255,255,0.92); font-size: 1.0625rem; }

/* Parked-state override (see note above .hbp-scroll-moment): with the pin
   disabled, --hbp-p never updates, so force the settled/finished-state look
   rather than leaving content at its animation-start values (image
   unscaled, steam hidden, text fully visible). */
.hbp-site .hbp-moment-media img { transform: none; }
.hbp-site .hbp-moment-steam { display: none; }
.hbp-site .hbp-moment-content { opacity: 1; transform: none; }

@media (max-width: 700px) {
  .hbp-site .hbp-moment-content { padding: var(--hbp-sp-8); }
}

/* Reduced motion: no pin, no zoom, no steam — plain static section, content
   visible immediately, exactly as if JS never ran. */
@media (prefers-reduced-motion: reduce) {
  .hbp-site .hbp-scroll-moment { height: auto; }
  .hbp-site .hbp-scroll-moment-stage { position: static; height: auto; min-height: 480px; border-radius: var(--hbp-radius-lg); }
  .hbp-site .hbp-moment-media img { transform: none; }
  .hbp-site .hbp-moment-steam { display: none; }
  .hbp-site .hbp-moment-content { opacity: 1; transform: none; }
}

/* No JS at all: --hbp-p can never update, so fall back the same way as
   reduced-motion rather than leaving the heading/text permanently at
   opacity 0. */
.hbp-site.hbp-no-js .hbp-scroll-moment { height: auto; }
.hbp-site.hbp-no-js .hbp-scroll-moment-stage { position: static; height: auto; min-height: 480px; border-radius: var(--hbp-radius-lg); }
.hbp-site.hbp-no-js .hbp-moment-media img { transform: none; }
.hbp-site.hbp-no-js .hbp-moment-steam { display: none; }
.hbp-site.hbp-no-js .hbp-moment-content { opacity: 1; transform: none; }

/* ---------------------------------------------------------------------- */
/* Visit section                                                          */
/* ---------------------------------------------------------------------- */
.hbp-site .hbp-visit {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--hbp-sp-24);
}
.hbp-site .hbp-visit-details dl {
  margin-top: var(--hbp-sp-8);
  display: grid;
  gap: var(--hbp-sp-6);
}
.hbp-site .hbp-visit-details dt {
  font-size: var(--hbp-fs-small);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--hbp-red);
}
.hbp-site .hbp-visit-details dd {
  margin: var(--hbp-sp-1) 0 0;
  font-size: 1.0625rem;
}
.hbp-site .hbp-visit-actions { margin-top: var(--hbp-sp-8); display: flex; flex-wrap: wrap; gap: var(--hbp-sp-4); }
.hbp-site .hbp-visit-map {
  border-radius: var(--hbp-radius-lg);
  overflow: hidden;
  min-height: 340px;
  background: var(--hbp-surface-2);
}
/* When still a placeholder (data-placeholder="true"), fall back to the
   centred-text treatment; a real embedded map fills the box edge to edge
   via .hbp-map-iframe below instead. */
.hbp-site .hbp-visit-map[data-placeholder="true"] {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--hbp-sp-8);
  color: var(--hbp-ink-soft);
}
.hbp-site .hbp-map-iframe {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 340px;
  border: 0;
}

@media (max-width: 860px) {
  .hbp-site .hbp-visit { grid-template-columns: 1fr; gap: var(--hbp-sp-12); }
}

/* ---------------------------------------------------------------------- */
/* Final CTA                                                               */
/* ---------------------------------------------------------------------- */
.hbp-site .hbp-final-cta {
  position: relative;
  min-height: 480px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  overflow: hidden;
}
.hbp-site .hbp-final-cta-media { position: absolute; inset: 0; }
.hbp-site .hbp-final-cta-media img { width: 100%; height: 100%; object-fit: cover; }
.hbp-site .hbp-final-cta-scrim { position: absolute; inset: 0; background: rgba(38,23,15,0.62); }
.hbp-site .hbp-final-cta-content { position: relative; z-index: 1; color: var(--hbp-white); padding: var(--hbp-sp-12) var(--hbp-gutter); }
.hbp-site .hbp-final-cta-content h2 { color: var(--hbp-white); max-width: 20ch; margin-inline: auto; }
.hbp-site .hbp-final-cta-content .hbp-btn { margin-top: var(--hbp-sp-8); }

/* ---------------------------------------------------------------------- */
/* Footer                                                                  */
/* ---------------------------------------------------------------------- */
.hbp-site .hbp-footer {
  background: var(--hbp-ink);
  color: rgba(255,255,255,0.82);
  padding-block: var(--hbp-sp-16) var(--hbp-sp-8);
}
.hbp-site .hbp-footer-grid {
  display: grid;
  grid-template-columns: 1.2fr 1fr 1fr;
  gap: var(--hbp-sp-12);
}
.hbp-site .hbp-footer-brand img { height: 40px; width: auto; margin-bottom: var(--hbp-sp-4); }
.hbp-site .hbp-footer-brand p { max-width: 34ch; color: rgba(255,255,255,0.65); }
.hbp-site .hbp-footer h3 {
  font-family: var(--hbp-font-body);
  font-size: var(--hbp-fs-small);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--hbp-cyan);
  margin-bottom: var(--hbp-sp-4);
}
.hbp-site .hbp-footer ul { display: grid; gap: var(--hbp-sp-3); }
.hbp-site .hbp-footer a:hover { color: var(--hbp-cyan); }
.hbp-site .hbp-footer-social { display: flex; gap: var(--hbp-sp-4); margin-top: var(--hbp-sp-2); }
.hbp-site .hbp-footer-bottom {
  margin-top: var(--hbp-sp-16);
  padding-top: var(--hbp-sp-6);
  border-top: 1px solid rgba(255,255,255,0.14);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--hbp-sp-3);
  font-size: var(--hbp-fs-small);
  color: rgba(255,255,255,0.5);
}

@media (max-width: 780px) {
  .hbp-site .hbp-footer-grid { grid-template-columns: 1fr; gap: var(--hbp-sp-8); }
}

/* ---------------------------------------------------------------------- */
/* Mobile persistent action bar                                            */
/* ---------------------------------------------------------------------- */
.hbp-site .hbp-mobile-bar {
  display: none;
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 90;
  background: var(--hbp-cream);
  border-top: 1px solid var(--hbp-line);
  padding: var(--hbp-sp-3) var(--hbp-gutter);
  gap: var(--hbp-sp-3);
}
@media (max-width: 640px) {
  .hbp-site .hbp-mobile-bar { display: flex; }
  .hbp-site .hbp-mobile-bar .hbp-btn { flex: 1; justify-content: center; }
  /* Was `.hbp-site body { ... }` — body can never be a descendant of
     .hbp-site (it's the other way around), so that rule never matched
     anything and the fixed mobile bar has been sitting over the last ~76px
     of page content on mobile this whole time. Fixed to target .hbp-site
     itself, reserving the space on whichever block ends up last (the
     footer one, in the three-block GHL layout). */
  .hbp-site { padding-bottom: 76px; }
}

/* ---------------------------------------------------------------------- */
/* Reveal-on-scroll (progressive enhancement; safe with JS disabled)       */
/* ---------------------------------------------------------------------- */
.hbp-site [data-reveal] {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity var(--hbp-dur-slow) var(--hbp-ease), transform var(--hbp-dur-slow) var(--hbp-ease);
}
.hbp-site [data-reveal].hbp-revealed { opacity: 1; transform: none; }
.hbp-site.hbp-no-js [data-reveal] { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .hbp-site * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
  .hbp-site [data-reveal] { opacity: 1; transform: none; }
  .hbp-site .hbp-offset::before,
  .hbp-site .hbp-btn-primary::before { transition: none; }
}

/* ---------------------------------------------------------------------- */
/* Content placeholder styling — used across Home wherever real business  */
/* facts aren't confirmed yet. Never remove without replacing with real   */
/* content; never let this style leak onto confirmed copy.                */
/* ---------------------------------------------------------------------- */
.hbp-site [data-placeholder="true"] {
  border-bottom: 1px dashed var(--hbp-cyan-deep);
}

/* ---------------------------------------------------------------------- */
/* Menu page — rendered from data/menu.js by js/menu-render.js            */
/* ---------------------------------------------------------------------- */
.hbp-site .hbp-menu-jump {
  position: sticky;
  top: 76px; /* measured header height — was 65px, drifted from the real ~76px and let this bar overlap the header's bottom edge by ~11px */
  z-index: 50;
  background: rgba(251, 243, 231, 0.95);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--hbp-line);
  padding-block: var(--hbp-sp-3);
}
.hbp-site .hbp-menu-jump-list {
  display: flex;
  justify-content: center; /* centers when it fits; still scrolls if it doesn't (narrow/mobile) */
  gap: var(--hbp-sp-6);
  overflow-x: auto;
  padding-inline: var(--hbp-gutter);
  scrollbar-width: none;
}
.hbp-site .hbp-menu-jump-list::-webkit-scrollbar { display: none; }
.hbp-site .hbp-menu-jump-list a {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 1.25;
  padding-block: var(--hbp-sp-1);
  border-bottom: 2px solid transparent;
}
.hbp-site .hbp-menu-jump-list a:hover { border-color: var(--hbp-red); }
.hbp-site .hbp-menu-jump-list a:hover .hbp-menu-jump-en { color: var(--hbp-red); }
.hbp-site .hbp-menu-jump-en {
  font-weight: 700;
  font-size: var(--hbp-fs-small);
  color: var(--hbp-ink-soft);
}
.hbp-site .hbp-menu-jump-vn {
  font-weight: 500;
  font-size: 0.75rem;
  color: var(--hbp-ink-soft);
  opacity: 0.75;
}

.hbp-site .hbp-menu-section:nth-of-type(even) { background: var(--hbp-surface); }
/* Clears both sticky bars (header + category nav) when a jump-nav link
   scrolls this section into view, so the heading lands below them instead
   of being cut off behind them. 76px header + ~67.5px jump-nav (now two
   lines tall — EN + VN — since the jump-nav labels gained a Vietnamese
   subheading) + a little breathing room. */
.hbp-site .hbp-menu-section { scroll-margin-top: 160px; }

.hbp-site .hbp-menu-cat-sub {
  font-family: var(--hbp-font-body);
  font-weight: 500;
  font-size: 0.55em;
  color: var(--hbp-ink-soft);
  vertical-align: middle;
}
.hbp-site .hbp-menu-cat-note {
  margin-top: var(--hbp-sp-3);
  font-size: var(--hbp-fs-small);
  color: var(--hbp-cyan-deep);
}

.hbp-site .hbp-menu-items {
  margin-top: var(--hbp-sp-8);
  display: grid;
  gap: var(--hbp-sp-8);
  max-width: 72ch;
}
.hbp-site .hbp-menu-item {
  padding-bottom: var(--hbp-sp-6);
  border-bottom: 1px solid var(--hbp-line);
}
.hbp-site .hbp-menu-item:last-child { border-bottom: 0; }
.hbp-site .hbp-menu-item-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--hbp-sp-4);
}
.hbp-site .hbp-menu-item-head h3 { font-size: var(--hbp-fs-h3); }
.hbp-site .hbp-menu-item-sub {
  font-family: var(--hbp-font-body);
  font-weight: 500;
  font-size: 0.9rem;
  color: var(--hbp-ink-soft);
}
.hbp-site .hbp-menu-price {
  flex: 0 0 auto;
  font-weight: 700;
  color: var(--hbp-red);
  white-space: nowrap;
}
.hbp-site .hbp-menu-item-desc {
  margin-top: var(--hbp-sp-2);
  color: var(--hbp-ink-soft);
  font-size: 0.9375rem;
  max-width: 58ch;
}
.hbp-site .hbp-menu-item-note {
  margin-top: var(--hbp-sp-2);
  font-size: var(--hbp-fs-small);
  font-style: italic;
  color: var(--hbp-ink-soft);
}
.hbp-site .hbp-menu-dietary { display: inline-flex; flex-wrap: wrap; gap: var(--hbp-sp-2); margin-top: var(--hbp-sp-2); }
.hbp-site .hbp-menu-dietary-tag {
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--hbp-cyan-deep);
  border: 1px solid var(--hbp-cyan-deep);
  border-radius: var(--hbp-radius-full);
  padding: 0.15rem 0.6rem;
}
.hbp-site .hbp-menu-tag {
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--hbp-orange-ink);
  border: 1px solid var(--hbp-orange-ink);
  border-radius: var(--hbp-radius-full);
  padding: 0.15rem 0.6rem;
}
.hbp-site .hbp-menu-cat-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 400px);
  gap: var(--hbp-sp-12);
  align-items: start;
}
.hbp-site .hbp-menu-cat-photo {
  margin: var(--hbp-sp-8) 0 0;
  position: sticky;
  top: 160px; /* below the sticky header (76px) + two-line jump-nav (~67.5px) + breathing room */
  aspect-ratio: 4 / 5;
  border-radius: var(--hbp-radius-lg);
  overflow: hidden;
}
.hbp-site .hbp-menu-cat-photo picture,
.hbp-site .hbp-menu-cat-photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
.hbp-site .hbp-menu-cat-photo-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--hbp-sp-6);
  text-align: center;
  color: var(--hbp-ink-soft);
  border: 2px dashed var(--hbp-cyan-deep);
}
@media (max-width: 900px) {
  .hbp-site .hbp-menu-cat-body { grid-template-columns: minmax(0, 1fr); gap: var(--hbp-sp-6); }
  .hbp-site .hbp-menu-cat-photo { position: static; order: -1; margin-top: var(--hbp-sp-6); aspect-ratio: 1 / 1; }
}
.hbp-site .hbp-menu-badge {
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--hbp-white);
  background: var(--hbp-red);
  border-radius: var(--hbp-radius-full);
  padding: 0.2rem 0.7rem;
}
.hbp-site .hbp-menu-steps {
  list-style: none;
  margin: var(--hbp-sp-6) 0 0;
  padding: 0;
  display: grid;
  gap: var(--hbp-sp-6);
}
.hbp-site .hbp-menu-step-title {
  font-family: var(--hbp-font-body);
  font-size: 1rem;
  font-weight: 700;
  color: var(--hbp-ink);
}
.hbp-site .hbp-menu-step-limit {
  margin-left: var(--hbp-sp-2);
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--hbp-red);
}
.hbp-site .hbp-menu-step-options {
  list-style: none;
  margin: var(--hbp-sp-3) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--hbp-sp-2);
}
.hbp-site .hbp-menu-step-options li {
  font-size: 0.9375rem;
  color: var(--hbp-ink-soft);
  border: 1px solid var(--hbp-line);
  border-radius: var(--hbp-radius-full);
  padding: 0.3rem 0.85rem;
}
.hbp-site .hbp-menu-option-sub {
  font-size: 0.8125rem;
  opacity: 0.75;
  margin-left: var(--hbp-sp-1);
}
.hbp-site .hbp-menu-cat-footnote {
  margin-top: var(--hbp-sp-8);
  max-width: 72ch;
  font-size: 0.9375rem;
  font-style: italic;
  color: var(--hbp-ink-soft);
}
.hbp-site .hbp-menu-addons {
  margin-top: var(--hbp-sp-8);
  padding-top: var(--hbp-sp-6);
  border-top: 1px solid var(--hbp-line);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--hbp-sp-2) var(--hbp-sp-6);
  max-width: 72ch;
}
.hbp-site .hbp-menu-addons-label {
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.75rem;
  color: var(--hbp-ink-soft);
  flex: 0 0 100%;
}
.hbp-site .hbp-menu-addon { font-size: 0.9375rem; color: var(--hbp-ink-soft); white-space: nowrap; }
.hbp-site .hbp-menu-addon .hbp-menu-price { color: var(--hbp-red); margin-left: var(--hbp-sp-1); }
.hbp-site .hbp-menu-variant-list { margin-top: var(--hbp-sp-4); display: grid; gap: var(--hbp-sp-2); }
.hbp-site .hbp-menu-variant {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--hbp-sp-4);
  flex-wrap: wrap;
}
.hbp-site .hbp-menu-variant-name { font-weight: 600; }
.hbp-site .hbp-menu-variant-name em { font-style: italic; font-weight: 500; color: var(--hbp-ink-soft); }
.hbp-site .hbp-menu-variant-sizes { display: flex; gap: var(--hbp-sp-4); }
.hbp-site .hbp-menu-size { font-size: 0.9375rem; color: var(--hbp-ink-soft); white-space: nowrap; }
.hbp-site .hbp-menu-size .hbp-menu-price { color: var(--hbp-red); margin-left: var(--hbp-sp-1); }

@media (max-width: 700px) {
  .hbp-site .hbp-menu-jump { top: 67px; } /* measured mobile header height — was 57px, same drift as desktop */
  .hbp-site .hbp-menu-item-head { flex-direction: column; align-items: flex-start; gap: var(--hbp-sp-1); }
  .hbp-site .hbp-menu-section { scroll-margin-top: 150px; } /* 67px header + ~67.5px two-line jump-nav + breathing room — was 130px before the jump-nav gained its Vietnamese subheading line */
}

/* ---------------------------------------------------------------------- */
/* Contact page — layout and form                                         */
/* ---------------------------------------------------------------------- */
.hbp-site .hbp-contact-grid {
  display: grid;
  grid-template-columns: 1.3fr 1fr;
  gap: var(--hbp-sp-24);
  align-items: start;
}
.hbp-site .hbp-contact-details h2 { font-size: var(--hbp-fs-h3); }
.hbp-site .hbp-contact-details dl { margin-top: var(--hbp-sp-6); display: grid; gap: var(--hbp-sp-5); }
.hbp-site .hbp-contact-details dt {
  font-size: var(--hbp-fs-small);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--hbp-red);
}
.hbp-site .hbp-contact-details dd { margin: var(--hbp-sp-1) 0 0; font-size: 1.0625rem; }
.hbp-site .hbp-contact-socials { margin-top: var(--hbp-sp-6); display: flex; gap: var(--hbp-sp-4); }
.hbp-site .hbp-contact-socials a { font-weight: 700; border-bottom: 2px solid var(--hbp-cyan); }
.hbp-site .hbp-contact-details .hbp-visit-map { margin-top: var(--hbp-sp-8); min-height: 220px; }

@media (max-width: 900px) {
  .hbp-site .hbp-contact-grid { grid-template-columns: 1fr; gap: var(--hbp-sp-12); }
}

/* Form */
.hbp-site #hbp-contact-form { display: grid; gap: var(--hbp-sp-6); }
.hbp-site .hbp-form-row { display: grid; gap: var(--hbp-sp-2); }
.hbp-site .hbp-form-row-group { display: grid; grid-template-columns: 1fr 1fr; gap: var(--hbp-sp-6); }
@media (max-width: 560px) {
  .hbp-site .hbp-form-row-group { grid-template-columns: 1fr; }
}
.hbp-site .hbp-form-row label,
.hbp-site .hbp-form-consent label {
  font-weight: 600;
  font-size: 0.9375rem;
}
.hbp-site .hbp-form-required { color: var(--hbp-red); }
.hbp-site .hbp-form-optional { font-weight: 400; color: var(--hbp-ink-soft); }

.hbp-site .hbp-form-row input,
.hbp-site .hbp-form-row textarea,
.hbp-site .hbp-form-row select {
  font: inherit;
  color: var(--hbp-ink);
  background: var(--hbp-white);
  border: 1.5px solid var(--hbp-line);
  border-radius: var(--hbp-radius-sm);
  padding: var(--hbp-sp-3);
  width: 100%;
}
.hbp-site .hbp-form-row input:focus-visible,
.hbp-site .hbp-form-row textarea:focus-visible,
.hbp-site .hbp-form-row select:focus-visible {
  outline: 3px solid var(--hbp-cyan-deep);
  outline-offset: 1px;
  border-color: var(--hbp-cyan-deep);
}
.hbp-site .hbp-form-row input[aria-invalid="true"],
.hbp-site .hbp-form-row textarea[aria-invalid="true"] {
  border-color: var(--hbp-red);
}
.hbp-site .hbp-form-row textarea { resize: vertical; min-height: 7rem; }

.hbp-site .hbp-form-error {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--hbp-red);
  font-weight: 600;
}

.hbp-site .hbp-form-consent {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--hbp-sp-1) var(--hbp-sp-3);
  align-items: start;
}
.hbp-site .hbp-form-consent input { margin-top: 0.2em; }
.hbp-site .hbp-form-consent .hbp-form-error { grid-column: 2; }

.hbp-site #hbp-form-submit { justify-self: start; }
.hbp-site #hbp-form-submit:disabled { opacity: 0.6; cursor: default; transform: none; }

.hbp-site .hbp-form-status {
  margin: 0;
  font-weight: 600;
  font-size: 0.9375rem;
}
.hbp-site .hbp-form-status-success { color: #2E7D46; }
.hbp-site .hbp-form-status-error { color: var(--hbp-red); }
