/* =========================================================
   Bakemono Bakers — placeholder build
   Fonts: HAL Timezone Mono (address/mono UI), Maxeville (display/body)
   ========================================================= */
 
@font-face {
  font-family: 'HAL Timezone Mono';
  src: url('../fonts/HALTimezoneMono-Regular.woff2') format('woff2'),
       url('../fonts/HALTimezoneMono-Regular.woff') format('woff');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Maxeville';
  src: url('../fonts/Maxeville-Regular.woff2') format('woff2'),
       url('../fonts/Maxeville-Regular.woff') format('woff');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Maxeville';
  src: url('../fonts/Maxeville-Bold.woff2') format('woff2'),
       url('../fonts/Maxeville-Bold.woff') format('woff');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Maxeville Tekst';
  src: url('../fonts/Maxeville-Tekst.woff2') format('woff2'),
       url('../fonts/Maxeville-Tekst.woff') format('woff');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
 
:root {
  /* Brand Identity Toolkit, Dec 2025 — official palette:
     Starter #FBF8F3, Charcoal #3B3B3C, Herb #787364,
     Dough #E5DACF, Flour #FFFFFF. */
  --bg: #FBF8F3;
  --ink: #3B3B3C;
  --ink-soft: #787364;
  --line: rgba(59, 59, 60, 0.14);
  --dough: #E5DACF;
  --dough-soft: #F2ECE7;
  --white: #FFFFFF;
 
  --font-mono: 'HAL Timezone Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;
  --font-display: 'Maxeville', 'Helvetica Neue', Arial, sans-serif;
  --font-body: 'Maxeville Tekst', 'Maxeville', 'Helvetica Neue', Arial, sans-serif;
 
  --header-h: 128px;
  --footer-h: 64px;
  --pane-left: 50%;
  --edge-gap: 44px;
  --ease: cubic-bezier(.65,.05,.36,1);
}

/* Crossfades same-origin page navigations (nav links, gallery tiles,
   product prev/next) using the browser's native View Transitions API.
   Unsupported browsers just navigate instantly — no fallback needed. */
@view-transition {
  navigation: auto;
}
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: .45s;
  animation-timing-function: var(--ease);
}

/* =========================================================
   RIGHT-SECTION ALIGNMENT RULE (site-wide, don't break this)

   Every page is split into a left column (text) and a right column
   ("the right section" — photo, gallery, or nav) using the same
   `grid-template-columns: var(--pane-left) 1fr` on both .site-header
   and .view. Because both grids share that definition, their second
   column lines up pixel-for-pixel across every page automatically.

   Anything placed in the right section must:
     1. Start flush at the column's left edge — no left padding/margin.
     2. End with `padding-right: var(--edge-gap)` (or the equivalent
        margin) — never flush to the true viewport edge.
     3. Never get a one-off width/margin. If the right section's
        alignment needs to change, change --pane-left or --edge-gap
        here and every page/element (nav, gallery, photos) moves
        together automatically.

   Current members: .site-nav, .gallery (menu.html), the photo panes
   on about/catering/product (.view__pane--right.view__pane--image).
   ========================================================= */
 
* { box-sizing: border-box; }
/* .carousel-arrow (and a few other elements) set `display` directly,
   which otherwise beats the browser's own [hidden] rule in a specificity
   tie — this keeps the hidden attribute reliably hiding things. */
[hidden] { display: none !important; }
html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
}
body { overflow-x: hidden; }
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font-family: inherit; background: none; border: none; padding: 0; cursor: pointer; color: inherit; }
ul { margin: 0; padding: 0; list-style: none; }
 
.mono { font-family: var(--font-display); letter-spacing: 0.02em; }
/* Allergen list is the one place that keeps the mono font. */
#allergenToggle { font-family: var(--font-mono); }
 
/* ---------- Logo lockup (shared) ---------- */
.addr {
  display: block;
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.addr--small {
  width: 310px; /* 로고 전체 폭 고정 */

  /* 브랜드 규격 Clear Space (X = H / 2) */
  --lockup-h: 60px;
  --clear-space: calc(var(--lockup-h) / 2);
}
.landing__address {
  width: 360px;
}

/* Charcoal PNG sits on top; the Dough PNG underneath crossfades in on
   hover — a raster swap standing in for the old text block's
   color-transition, since an <img> can't be recolored with `color`. */
.addr__lockup {
  position: relative;
  display: block;
}
.addr__lockup img {
  display: block;
  width: 100%;
  height: auto;
}
.addr__lockup img:first-child {
  transition: opacity .35s var(--ease);
}
.addr__lockup img:last-child {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity .35s var(--ease);
}
.addr:hover .addr__lockup img:first-child { opacity: 0; }
.addr:hover .addr__lockup img:last-child { opacity: 1; }

/* Single-line "BAKEMONO BAKERS®" logotype — swaps in for the header's
   multi-line address lockup on mobile only (see the responsive block
   below), where that long 3-line block ran cramped at the reduced
   width. Desktop keeps the full address lockup. */
.addr__mobile-logotype { display: none; }

/* 헤더 상단/좌측 X 규격 여백 적용 */
.site-header {
  align-items: flex-start;
  padding-top: var(--clear-space);
}

.site-header .addr--small {
  margin-left: var(--clear-space);
}
/* ============ LANDING ============ */
.landing {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  z-index: 50;
  transition: opacity .7s var(--ease), visibility .7s var(--ease);
}
.landing.is-leaving { opacity: 0; visibility: hidden; pointer-events: none; }
/* Background stays put — only the logo lockup's colour cycles through
   all 4 palette tones (Charcoal, Herb/olive, Flour white, Dough), not
   just the 2 the charcoal/dough PNGs come in. Hides the two raster
   images (keeping the first for its intrinsic size/aspect ratio) and
   uses the charcoal PNG's alpha channel as a mask instead, so any
   solid --colour can show through the exact logotype shape. Landing
   page only — the header lockup elsewhere is untouched. */
.landing__address .addr__lockup img:first-child { opacity: 0; }
.landing__address .addr__lockup {
  background-color: var(--ink);
  -webkit-mask-image: url('../assets/logos/bakemono-lockup-charcoal.png');
  mask-image: url('../assets/logos/bakemono-lockup-charcoal.png');
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  animation: landing-logo-4color 6s linear infinite;
}
@keyframes landing-logo-4color {
  0%   { background-color: var(--ink); }
  33%  { background-color: var(--ink-soft); }
  66%  { background-color: var(--dough); }
  100% { background-color: var(--ink); }
}
 
.landing__mark {
  position: absolute;
  top: -160px;
  left: calc(100vw - 140px);
  width: 110px;
  height: auto;
  padding: 0;
  animation: fall-in 6s ease-in infinite;
  animation-delay: .5s;
  transition: transform .3s var(--ease);
  /* Mobile Safari/Chrome draw a default tap-highlight box on links —
     easy to mistake for a stray outline appearing on hover/tap. */
  -webkit-tap-highlight-color: transparent;
}
.landing__mark img { width: 100%; height: auto; }
.landing__mark:hover { transform: scale(1.08) rotate(-4deg); }
/* Keep the focus ring for keyboard tabbing, drop it for mouse/touch. */
.landing__mark:focus:not(:focus-visible),
.landing__address:focus:not(:focus-visible) { outline: none; }
.landing__mark:active { transform: scale(.94) rotate(2deg); }

/* Falls straight through from off the top of the screen to off the
   bottom, fading out as it goes, then a long pause off-screen before
   the next drop. */
@keyframes fall-in {
  0%     { top: -160px; opacity: 1; }
  64.5%  { opacity: 1; }
  71.5%  { top: calc(100vh + 160px); opacity: 0; }
  100%   { top: calc(100vh + 160px); opacity: 0; }
}
 
.landing__address {
  animation: addr-in .9s var(--ease) both;
  animation-delay: .5s;
}
@keyframes addr-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
 
/* ============ SITE SHELL ============ */
.site { position: relative; min-height: 100vh; }
 
/* Header mirrors the .view grid — see RIGHT-SECTION ALIGNMENT RULE
   above. .site-nav is a right-section member. */
.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: var(--header-h);
  display: grid;
  grid-template-columns: var(--pane-left) 1fr;
  align-items: center;
  background: var(--bg);
  z-index: 20;
  border-bottom: 1px solid transparent;
}
.site-header .addr--small { margin-left: var(--edge-gap); }
.site-nav {
  display: flex;
  justify-content: space-between;
  padding-right: var(--edge-gap);
}
.site-nav a {
  font-family: var(--font-display);
  font-weight: 700;
  /* Shrinks smoothly on narrower windows instead of wrapping or
     overflowing past the photo/nav column edge. */
  font-size: clamp(9px, 1.35vw, 13px);
  letter-spacing: 0.08em;
  color: var(--ink);
  padding: 6px 0;
  position: relative;
  white-space: nowrap;
  transition: color .35s var(--ease);
}
.site-nav a:hover { color: var(--ink-soft); }

/* Hamburger toggle only exists for the mobile dropdown nav — hidden
   entirely above the 860px breakpoint where .site-nav is a plain row. */
.nav-toggle { display: none; }

/* ============ VIEWS ============ */
.views { position: relative; min-height: 100vh; }
.view {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: var(--pane-left) 1fr;
  min-height: 100vh;
  opacity: 0;
  visibility: hidden;
  transform: translateY(14px);
  transition: opacity .5s var(--ease), transform .5s var(--ease), visibility .5s;
  pointer-events: none;
}
.view.is-active {
  position: relative;
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  pointer-events: auto;
}

.view__pane { padding: 48px 44px; }
.view__pane--left {
  display: flex;
  flex-direction: column;
  gap: 22px;
  padding-top: calc(var(--header-h) + 48px);
  padding-bottom: calc(var(--footer-h) + 48px);
}
/* Right pane — see RIGHT-SECTION ALIGNMENT RULE above. Clears the
   fixed header with padding-top. */
.view__pane--right {
  padding: 0;
  padding-top: var(--header-h);
  padding-right: var(--edge-gap);
  position: relative;
}
.view__pane--image {
  overflow: hidden;
}
.view__pane--right.view__pane--image {
  min-height: calc(100vh - var(--header-h));
}
.view__pane--image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.media-frame {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.pane-note {
  font-family: var(--font-display);
  font-size: 13px;
  letter-spacing: 0.12em;
  color: var(--ink-soft);
  margin: 0;
}
.pane-copy {
  font-family: var(--font-body);
  font-size: 15px;
  letter-spacing: -0.01em;
  line-height: 1.6;
  color: var(--ink);
  max-width: 46ch;
  margin: 0;
}
.pane-copy--muted { color: var(--ink-soft); }
 /* ============ MENU GALLERY ============ */
#view-menu,
.menu-container {
  width: 100%;
  box-sizing: border-box;
}
/* Menu is the one view that scrolls with the page instead of being
   capped to 100vh, so — unlike the other views' panes — it never
   reserved space for the fixed .site-footer pill. Without this the
   footer sits on top of the last gallery row once you scroll to the
   bottom of the page. */
.view--menu .view__pane--right {
  padding-bottom: calc(var(--footer-h) + 40px);
}

.gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 5px; /* gllaery gap lay out */
  width: 100%;
  box-sizing: border-box;
}

.gallery-tile {
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  cursor: pointer;
  background: var(--dough);
}

.gallery-tile img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.02);
  transition: filter .45s var(--ease), transform .6s var(--ease);
}

.gallery-tile__label {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--white);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0;
  background: rgba(59, 59, 60, 0.2);
  text-shadow: 0 1px 6px rgba(59, 59, 60, 0.4);
  transition: opacity .4s var(--ease);
  text-align: center;
  padding: 10px;
  line-height: 1.2;
}

.gallery-tile:hover img {
  filter: blur(6px) brightness(1.18); /*brighteness o.82*/
  transform: scale(1.08);
}

.gallery-tile:hover .gallery-tile__label { 
  opacity: 1; 
}

.gallery-tile:focus-visible { 
  outline: 2px solid var(--ink); 
  outline-offset: -2px; 
}

/* Pending-photo style */
.gallery-tile--pending img {
  filter: blur(14px) brightness(1.02);
  transform: scale(1.12);
}

.gallery-tile--pending:hover img {
  filter: blur(16px) brightness(1.06);
  transform: scale(1.16);
}

/* Mobile-only quick-view drawer (js/menu.js) — full styling lives in
   the responsive block below; desktop keeps this out of the layout
   entirely rather than relying only on aria-hidden. */
.menu-drawer { display: none; }

.gallery-tile__pending-badge,
.pending-badge {
  position: absolute;
  left: 50%;
  bottom: 10px;
  transform: translateX(-50%);
  font-size: 9px;
  letter-spacing: 0.06em;
  color: var(--white);
  background: rgba(59, 59, 60, 0.55);
  padding: 4px 10px;
  border-radius: 999px;
  white-space: nowrap;
  pointer-events: none;
}

@media (max-width: 768px) {
  .gallery {
    max-width: 100%;
    gap: 10px;
  }
}
/* ============ PRODUCT DETAIL ============ */
/* Product is a normal scrolling page (like menu.html), not capped to
   one viewport — .product-top holds the title/photo "hero" at roughly
   one screen tall, and .product-related sits below it, reached by
   scrolling. No carousel arrows; related tiles are how you move
   between items now. .view--product overrides the base .view grid
   (var(--pane-left) 1fr) — it now stacks two full-width children
   (.product-top, .product-related) instead of two side-by-side ones. */
.view--product { display: block; }
.product-top {
  display: grid;
  grid-template-columns: var(--pane-left) 1fr;
  min-height: 100vh;
}

/* 1. 좌측 텍스트 패널: 오른쪽 사진 중앙 정렬 (상품명+설명 한 블록) */
.view--product .view__pane--left {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-top: var(--header-h);
  padding-left: var(--edge-gap);
  padding-right: 40px;
}

/* 2열 레이아웃 구조 (상품명 180px | 설명 잔여 폭)
   사진 세로 중앙보다 2줄 정도 아래에 위치하도록 상단 여백 추가 */
.product-detail-layout {
  display: grid;
  grid-template-columns: 180px 1fr;
  gap: 32px;
  align-items: flex-start; 
  width: 100%;
  margin-top: 300px; /* description part layout */
}

.product-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 20px;
  line-height: 1.1;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  margin: 0;
  color: var(--ink);
}

.product-col-body {
  display: flex;
  flex-direction: column;
  gap: 18px;
  align-items: flex-start;
}

.product-desc {
  font-family: var(--font-display);
  font-size: 13px;
  line-height: 1.45;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0;
  letter-spacing: 0.01em;
  max-width: 44ch;
}

/* Allergen/Dietary toggle — plain text, no pill/oval framing. */
#allergenToggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1.4;
  color: var(--ink-soft);
  background: none;
  border: none;
  padding: 3px 10px 3px 0;
  cursor: pointer;
  transition: color .25s var(--ease);
}
#allergenToggle:hover { color: var(--ink); }
.accordion__icon { display: inline-block; transition: transform .25s var(--ease); }
#allergenToggle[aria-expanded="true"] .accordion__icon { transform: rotate(45deg); }

/* Collapsed by default — clicking the toggle above reveals this panel. */
.accordion__panel {
  overflow: hidden;
  max-height: 0;
  transition: max-height .35s var(--ease);
}
.accordion__panel.is-open { max-height: 240px; }

.accordion__line {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-soft);
  margin: 12px 0 0;
}
.accordion__line + .accordion__line { margin-top: 12px; }

/* Items read as a spaced row instead of a comma list. */
.accordion__tag { margin-right: 18px; }
.accordion__tag:last-child { margin-right: 0; }

/* 2. 우측 이미지 영역 — sizing is unified with about/catering below
   (see the .view--about/.view--catering/.view--product padding rule
   further down this file), so no page-specific padding is set here. */
.view--product .media-frame {
  position: relative;
  width: 100%;
  height: 100%;
  background: var(--dough);
}

.view--product .product-hero {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}

/* 3. 관련 상품 — 스크롤해서 만나는 섹션, 클릭하면 해당 상품으로 이동 */
.product-related {
  padding: 56px var(--edge-gap) calc(var(--footer-h) + 40px) var(--edge-gap);
}
.product-related__label {
  font-size: 13px;
  letter-spacing: 0.12em;
  color: var(--ink-soft);
  text-transform: uppercase;
  margin: 0 0 18px;
}
.product-related__grid { grid-template-columns: repeat(4, 1fr); }

/* 4. 푸터 — 뷰포트 맨 아래에 고정된, 불투명 배경의 전체 폭 바.
   스크롤되는 콘텐츠가 뒤에 겹쳐 비치지 않도록 배경으로 항상 덮는다. */
.site-footer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 28px;
  padding: 20px var(--edge-gap);
  background: var(--bg);
}

.footer-link {
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  color: var(--ink);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  transition: color .25s var(--ease);
}
.footer-link:hover { color: var(--ink-soft); }
/* ============ CATERING ============ */
.view--catering .view__pane--left > :last-child { margin-bottom: 24px; }

.catering-form-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  align-self: flex-start;
  margin-top: 8px;
  padding: 10px 20px;
  border: none;
  border-radius: 999px;
  background: var(--bg);
  font-family: var(--font-display);
  font-size: 13px;
  letter-spacing: 0.08em;
  color: var(--ink);
  cursor: pointer;
  transition: background-color .25s var(--ease), color .25s var(--ease);
}
.catering-form-link:hover { background-color: var(--ink-soft); color: var(--white); }
.catering-form-link__arrow { display: inline-block; }

/* ---- Catering order form (always visible below the intro copy) ---- */
.catering-form {
  display: flex;
  flex-direction: column;
  gap: 20px;
  margin-top: 40px; /* ← 폼 시작 전 위쪽 여백 (위치 조정) */
  padding-top: 20px;/* ← 선과 폼 내용 사이 여백 */
}
.catering-form__field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.catering-form__label {
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
/* Minimal single-line fields — label sits inline to the left of the
   input instead of stacked above it (name/email/phone/pickup date). */
.catering-form__field--inline {
  display: grid;
  grid-template-columns: 90px 1fr;
  align-items: baseline;
  column-gap: 14px;
  row-gap: 4px;
}
.catering-form__field--inline .catering-form__label { margin: 0; }
.catering-form__field--inline .catering-form__input { padding: 6px 2px; }
.catering-form__field--inline .catering-form__hint {
  grid-column: 2 / -1;
}
.catering-form__input {
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--ink);
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--line);
  padding: 8px 2px;
  transition: border-color .25s var(--ease);
}
.catering-form__input:focus {
  outline: none;
  border-bottom-color: var(--ink);
}
.catering-form__input--area { resize: vertical; min-height: 64px; border: 1px solid var(--line); padding: 10px; }
.catering-form__input--area:focus { border-color: var(--ink); }
.catering-form__hint { font-size: 11px; color: var(--ink-soft); letter-spacing: 0.02em; }
.catering-form__hint--error { color: var(--ink-soft); }

/* ---- Custom date/time pickers — brand-styled replacements for the
   native <input type="date"> calendar and <select> dropdown, whose
   popups can't be restyled with CSS. The real input/select stay in
   the DOM (visually hidden) so catering.js's existing value/option
   logic keeps working untouched; these are just a styled UI on top. */
.catering-form__native-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.catering-form__datepicker,
.catering-form__select {
  position: relative;
}
.catering-form__select-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  text-align: left;
  cursor: pointer;
}
.catering-form__select-trigger-label { flex: 1; }
.catering-form__select-caret {
  font-size: 9px;
  color: var(--ink-soft);
  transition: transform .25s var(--ease);
}
.catering-form__select-trigger[aria-expanded="true"] .catering-form__select-caret {
  transform: rotate(180deg);
}

.catering-form__select-panel,
.catering-form__calendar {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  background: var(--bg);
  border: 1px solid var(--line);
  box-shadow: 0 14px 32px rgba(59, 59, 60, 0.14);
  z-index: 30;
}
.catering-form__select-panel {
  right: 0;
  max-height: 260px;
  overflow-y: auto;
  list-style: none;
  margin: 0;
  padding: 4px;
  scrollbar-width: thin;
  scrollbar-color: var(--dough) transparent;
}
.catering-form__select-option {
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--ink);
  padding: 8px 10px;
  cursor: pointer;
  border-radius: 2px;
  transition: background-color .15s var(--ease);
}
.catering-form__select-option:hover,
.catering-form__select-option.is-active {
  background: var(--dough-soft);
}
.catering-form__select-option.is-selected {
  background: var(--dough);
  font-weight: 700;
}
.catering-form__select-option[aria-disabled="true"] {
  color: var(--ink-soft);
  opacity: .45;
  cursor: not-allowed;
}
.catering-form__select-option[aria-disabled="true"]:hover { background: none; }

.catering-form__calendar {
  width: 272px;
  padding: 12px;
}
.catering-form__calendar-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}
.catering-form__calendar-title {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink);
}
.catering-form__calendar-nav {
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-soft);
  cursor: pointer;
  border-radius: 2px;
  transition: background-color .15s var(--ease), color .15s var(--ease);
}
.catering-form__calendar-nav:hover { background: var(--dough-soft); color: var(--ink); }
.catering-form__calendar-nav:disabled { opacity: .35; cursor: not-allowed; background: none; }
.catering-form__calendar-weekdays,
.catering-form__calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
}
.catering-form__calendar-weekdays {
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-align: center;
  margin-bottom: 4px;
}
.catering-form__calendar-grid { gap: 2px; }
.catering-form__calendar-day {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--ink);
  border-radius: 999px;
  cursor: pointer;
  transition: background-color .15s var(--ease), color .15s var(--ease);
}
.catering-form__calendar-day:hover { background: var(--dough-soft); }
.catering-form__calendar-day.is-selected { background: var(--ink); color: var(--bg); }
.catering-form__calendar-day.is-disabled { color: var(--ink-soft); opacity: .35; cursor: not-allowed; pointer-events: none; }
.catering-form__calendar-day.is-empty { visibility: hidden; cursor: default; }

.catering-form__menu-label,
.catering-form__menu > .catering-form__label { margin-bottom: 6px; }
.catering-form__menu-list {
  display: flex;
  flex-direction: column;
  max-height: 340px;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: 4px;
}
/* Visible scrollbar on every internally-scrolling pane — the OS default
   overlay scrollbar (macOS) is invisible until you scroll, which hides
   the fact that there's more content below the fold. */
.view__pane--left,
.view__pane--right.view__pane--image,
.catering-form__menu-list {
  scrollbar-width: thin;
  scrollbar-color: var(--dough) transparent;
}
.view__pane--left::-webkit-scrollbar,
.view__pane--right.view__pane--image::-webkit-scrollbar,
.catering-form__menu-list::-webkit-scrollbar {
  width: 8px;
}
.view__pane--left::-webkit-scrollbar-track,
.view__pane--right.view__pane--image::-webkit-scrollbar-track,
.catering-form__menu-list::-webkit-scrollbar-track {
  background: transparent;
}
.view__pane--left::-webkit-scrollbar-thumb,
.view__pane--right.view__pane--image::-webkit-scrollbar-thumb,
.catering-form__menu-list::-webkit-scrollbar-thumb {
  background-color: var(--dough);
  border-radius: 999px;
}
.catering-form__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
}
.catering-form__item:last-child { border-bottom: none; }
.catering-form__item-info { min-width: 0; }
.catering-form__item-name {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0;
}
.catering-form__item-ready {
  display: block;
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--ink-soft);
  margin-top: 2px;
}
.catering-form__item-qty-wrap {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-shrink: 0;
}
.catering-form__item-price {
  font-family: var(--font-display);
  letter-spacing: 0.02em;
  font-size: 11px;
  color: var(--ink-soft);
  min-width: 3.4em;
  text-align: left;
}
.catering-form__total {
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
  text-align: right;
}
/* Quantity stepper — < 1 > in the site's mono UI voice, standing in
   for the browser's native number-input spin arrows. */
.qty-stepper {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}
.qty-stepper__btn {
  font-family: var(--font-mono);
  font-size: 15px;
  line-height: 1;
  color: var(--ink-soft);
  background: none;
  border: none;
  padding: 4px 2px;
  cursor: pointer;
  transition: color .25s var(--ease);
}
.qty-stepper__btn:hover { color: var(--ink); }
.qty-stepper__btn:disabled { color: var(--line); cursor: default; }
.qty-stepper__value {
  min-width: 14px;
  font-family: var(--font-display);
  letter-spacing: 0.02em;
  font-size: 11px;
  text-align: center;
  color: var(--ink);
}

.catering-form__honey { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }

#cfSubmit:disabled { opacity: 0.55; cursor: default; pointer-events: none; }

.catering-form__status {
  margin-top: 4px;
  font-size: 12px;
  letter-spacing: 0.08em;
}
.catering-form__status--error { color: var(--ink-soft); }
.catering-form__status--success { color: var(--ink-soft); }

/* About, Catering and Gift card are capped to one viewport — no page
   scroll. The photo shrinks to fit instead of cropping full-bleed,
   and the left-column text anchors to the bottom instead of the top.
   Product and Menu scroll with the page instead (see PRODUCT DETAIL
   and MENU GALLERY sections). */
.view--about,
.view--catering,
.view--giftcard {
  height: 100vh;
  overflow: hidden;
}
.view--about .view__pane--left,
.view--catering .view__pane--left,
.view--giftcard .view__pane--left {
  justify-content: flex-end;
  overflow-y: auto;
}
/* The catering and gift card forms are always in the DOM and can grow
   much taller than the viewport, so they can't use plain
   justify-content: flex-end — that packs overflow toward the top edge
   in a way that isn't reachable by scrolling down (the amount picker
   and card fields end up clipped above the visible pane on gift card).
   Top-anchor instead; js/catering.js pins the intro copy's bottom edge
   to the first catering photo's bottom edge (see alignCateringIntro),
   so the form starts right where the photo ends and only comes into
   view once you scroll down. */
.view--catering .view__pane--left,
.view--giftcard .view__pane--left {
  justify-content: flex-start;
}
.view--catering .view__pane--left {
  padding-bottom: calc(var(--footer-h) + 40px);
}
.catering-intro {
  display: flex;
  flex-direction: column;
  gap: 22px;
  margin-top: 240px; /* 이 값으로 내려가는 정도 조절 */

}
/* Gift card's intro copy + Purchase button never got the same
   down-shift as catering — it sat flush at the pane's top edge
   (justify-content: flex-start, needed so the checkout form's
   overflow scrolls correctly) instead of reading level with the
   card photo's vertical center. */
.giftcard-intro {
  display: flex;
  flex-direction: column;
  gap: 22px;
  margin-top: 240px;
}
.catering-scroll-cue {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  align-self: flex-start;
  font-family: var(--font-display);
  font-size: 13px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  transition: color .25s var(--ease);
}
.catering-scroll-cue:hover { color: var(--ink); }
.catering-scroll-cue__arrow { display: inline-block; transition: transform .25s var(--ease); }
.catering-scroll-cue:hover .catering-scroll-cue__arrow { transform: translateY(2px); }
.view--about .view__pane--right.view__pane--image,
.view--catering .view__pane--right.view__pane--image,
.view--giftcard .view__pane--right.view__pane--image {
  height: 100vh;
}
/* All photo panes (about, catering, product, gift card) share the same
   top/bottom inset for breathing room, and stay flush on the left per
   the RIGHT-SECTION ALIGNMENT RULE above — a left padding here used to
   shift the photo ~16px off that shared column edge, so it read as a
   slightly different width from the gallery/nav on other pages. */
.view--about .view__pane--right.view__pane--image,
.view--catering .view__pane--right.view__pane--image,
.view--product .view__pane--right.view__pane--image,
.view--giftcard .view__pane--right.view__pane--image {
  padding: 32px var(--edge-gap) 20px 0;
}
.view--about .media-frame,
.view--catering .media-frame,
.view--product .media-frame,
.view--giftcard .media-frame {
  height: 100%;
  border-radius: 4px;
}
.view--about .about-hero,
.view--catering .catering-hero,
.view--giftcard .giftcard-hero {
  object-fit: cover;
  object-position: bottom;
}
/* Product keeps its own dedicated object-position: center (see above) —
   it used to be listed here too, but same-specificity + later-in-file
   silently overrode that back to bottom, which crops purely from the
   top and was cutting into some photos (e.g. Plain croissant) that
   don't have as much empty backdrop above the pastry as others. */
/* Clicking the card graphic cycles to the next design — cursor hints
   that beyond just the small arrow buttons beside it. */
.view--giftcard .giftcard-hero {
  cursor: pointer;
}
/* Catering hero is a square photo (like the product hero below) — sized
   to its own 1:1 aspect instead of stretched/cropped to fill the
   (taller) photo pane, then centered in it, so nothing gets cut off
   the top or bottom. */
.view--catering .view__pane--right.view__pane--image {
  display: flex;
  align-items: center;
}
.view--catering .media-frame {
  height: auto;
  aspect-ratio: 1 / 1;
}

/* Product detail hero is always a 1:1 square, regardless of pane
   height — width-driven instead of stretched to fill the viewport,
   then centered in the (taller) photo pane. */
.view--product .view__pane--right.view__pane--image {
  display: flex;
  align-items: center;
}
.view--product .media-frame {
  height: auto;
  aspect-ratio: 1 / 1;
}

/* ============ GIFT CARD ============ */
.giftcard-offer { margin-top: 8px; }

/* Delivery-details block — "send to myself" checkbox, email/text
   method radios, and the SMS consent line. */
.giftcard-checkbox {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  cursor: pointer;
  margin: 10px 0;
}
.giftcard-radio-group {
  display: flex;
  gap: 20px;
  margin: 10px 0;
}
.giftcard-radio {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  cursor: pointer;
}
.giftcard-sms-consent {
  font-size: 11px;
  line-height: 1.5;
  color: var(--ink-soft);
  margin: 10px 0 0;
}

/* Checkout form revealed under the "Purchase now" button — reuses the
   .catering-form field styles for consistency with the catering page. */
.giftcard-checkout {
  margin-top: 20px;
  max-width: 420px;
}
/* Five boxes — $25 / $50 / $100 / $500 / Custom. */
.giftcard-amounts {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
}
.giftcard-amount-btn {
  padding: 10px 4px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: none;
  font-family: var(--font-display);
  font-size: 13px;
  color: var(--ink);
  cursor: pointer;
  transition: border-color .25s var(--ease), background-color .25s var(--ease), color .25s var(--ease);
}
.giftcard-amount-btn:hover { border-color: var(--ink-soft); }
.giftcard-amount-btn.is-selected {
  border-color: var(--ink);
  background-color: var(--ink);
  color: var(--white);
}
.giftcard-amount-btn--custom { font-size: 12px; }
/* Custom amount input reuses .catering-form__input's type/border, but
   needs its own width (that class relies on a parent grid elsewhere)
   and its native number-spinner arrows stripped — those render in the
   OS's own font/size and clash with the site's styled-input look. */
#gcCustomAmount {
  width: 100%;
  box-sizing: border-box;
  margin-top: 8px;
  -moz-appearance: textfield;
}
#gcCustomAmount::-webkit-outer-spin-button,
#gcCustomAmount::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.giftcard-card-container {
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 10px;
  min-height: 44px;
}

/* Apple Pay / Google Pay — shown only once the SDK confirms the
   browser actually supports them, so the divider stays hidden on
   browsers with neither (e.g. plain desktop Chrome without a wallet). */
.giftcard-wallet-buttons {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.giftcard-wallet-btn {
  width: 100%;
  height: 44px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
/* Apple's own system-rendered mark — required by Apple's Apple Pay
   button guidelines instead of a custom logo/text button. Safari-only
   (the button is only unhidden once Square confirms Apple Pay support,
   which in practice means Safari), so the fallback below only matters
   if that check is ever loosened. */
#gcApplePayButton {
  -webkit-appearance: -apple-pay-button;
  appearance: -apple-pay-button;
  -apple-pay-button-type: buy;
  -apple-pay-button-style: black;
}
@supports not (-webkit-appearance: -apple-pay-button) {
  #gcApplePayButton {
    background: #000;
    color: #fff;
    font-family: -apple-system, 'SF Pro Text', var(--font-body);
    font-size: 15px;
    font-weight: 500;
  }
  #gcApplePayButton::after { content: 'Pay with Apple Pay'; }
  #gcApplePayButton:hover { background: #1a1a1a; }
}
.giftcard-wallet-divider {
  margin: 2px 0 0;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-align: center;
}

/* Gift card hero is a cut-out card graphic (transparent background,
   its own rounded corners baked in) at its native 2882:1729 aspect —
   sized to that ratio instead of stretched/cropped to fill the
   (taller) photo pane, then centered in it, so the whole card shows. */
.view--giftcard .view__pane--right.view__pane--image {
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Photo carousel wrapper sits at the card's own size; .media-frame
   inside it still clips the image to its rounded corners, but the
   arrows are siblings of that clipped frame (not children of it) so
   they sit fully outside the card instead of being cut in half by
   the frame's own overflow:hidden. */
.giftcard-photo-carousel {
  position: relative;
  width: 78%;
  aspect-ratio: 2882 / 1729;
}
.giftcard-photo-carousel .media-frame {
  width: 100%;
  height: 100%;
}

.giftcard-photo-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  border-radius: 999px;
  border: none;
  background: var(--white);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 2px 10px rgba(59, 59, 60, 0.18);
  transition: background-color .25s var(--ease), color .25s var(--ease);
}
.giftcard-photo-arrow:hover { background: var(--dough-soft); }
.giftcard-photo-arrow--prev { right: 100%; margin-right: 16px; }
.giftcard-photo-arrow--next { left: 100%; margin-left: 16px; }

/* ============ ABOUT ============ */
.about-row {
  display: flex;
  align-items: baseline;
  gap: 24px;
  font-size: 13px;
}
.about-row + .about-row { margin-top: 18px; }
.about-row:last-child { margin-bottom: 72px; }
.about-row__label {
  width: 180px;
  flex-shrink: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.about-row__lines { display: flex; flex-direction: column; gap: 6px; }
.about-row__line { display: flex; gap: 24px; }
.about-row__line span:first-child { width: 110px; color: var(--ink); }
.about-row__value { color: var(--ink); font-size: 13px; }

.info-label {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin: 0 0 4px;
}
.info-value { font-size: 16px; margin: 0; }
.info-value--link { display: inline-block; font-weight: 700; transition: color .25s var(--ease); }
.info-value--link:hover { color: var(--ink-soft); }
 
/* ============ CONTACT ============ */
.view--contact {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--header-h) 44px var(--footer-h);
  height: 100vh;
  overflow: hidden;
}
.contact-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 40px;
  width: 100%;
  max-width: 1400px;
}
/* text-align:center only centers text runs — flex items themselves
   still default to align-items:stretch (full column width), which is
   what let the label/button/link sit flush left inside the column
   despite the centered text inside them. align-items:center makes the
   whole column read as centered, not just the words in it. */
.contact-col { display: flex; flex-direction: column; align-items: center; gap: 6px; position: relative; text-align: center; }
.contact-running-mark {
  position: absolute;
  bottom: calc(var(--footer-h) + 8px);
  left: -140px;
  width: 92px;
  animation: run-across 6s ease-in infinite;
  animation-delay: 1s;
  filter: brightness(0);
  opacity: 0.76;
}
/* Runs in from off the left edge of the screen and out past the right
   edge, fading out as it goes — timing mirrors the landing mascot's
   fall-in cycle (see .landing__mark): same 6s total, same run/pause split. */
@keyframes run-across {
  0%     { left: -140px; opacity: 1; }
  64.5%  { opacity: 1; }
  71.5%  { left: calc(100% + 140px); opacity: 0; }
  100%   { left: calc(100% + 140px); opacity: 0; }
}

/* Rests draped over the top of one randomly-chosen column's title
   each page load — see contact.js. Anchored to the column's
   horizontal center (now that the column text is centered too), so
   it lines up the same way regardless of how long that column's text
   runs. Hidden by default on all three. */
.contact-lazy-mark {
  position: absolute;
  top: -60px; /* logo up dowwn function */
  left: 50%;
  width: 90px;
  transform: translateX(-50%) rotate(0deg);
  pointer-events: none;
  z-index: 2;
  filter: brightness(0);
  opacity: 0.76;
}
 
/* ============ MODAL ============ */
.modal { position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center; }
.modal[hidden] { display: none; }
.modal__backdrop { position: absolute; inset: 0; background: rgba(59,59,60,0.45); }
.modal__panel {
  position: relative;
  background: var(--white);
  padding: 48px;
  max-width: 760px;
  width: calc(100% - 48px);
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  border-radius: 4px;
}
.modal__title { font-family: var(--font-display); font-size: 20px; margin: 0 0 12px; text-transform: uppercase; }
.modal__body { font-size: 14px; line-height: 1.6; color: var(--ink-soft); margin: 0; }
.modal__close {
  position: absolute; top: 14px; right: 16px;
  font-size: 22px; line-height: 1; color: var(--ink-soft);
}
.modal__close:hover { color: var(--ink); }
 
/* ============ RESPONSIVE ============ */
@media (max-width: 860px) {
  :root { --header-h: 68px; --footer-h: 56px; }

  /* Header collapses to one short row — logo left, hamburger toggle
     right — with the nav links moving into a dropdown panel that
     js/nav.js opens off the toggle instead of a squeezed inline row. */
  .site-header {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    padding: 14px 20px;
  }
  .site-header .addr--small { width: 150px; margin-left: 0; }
  .site-header .addr__lockup { display: none; }
  .addr__mobile-logotype { display: block; width: 100%; height: auto; }

  .nav-toggle {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 5px;
    width: 32px;
    height: 32px;
    padding: 0;
    border: none;
    background: none;
    cursor: pointer;
    flex-shrink: 0;
  }
  .nav-toggle__bar {
    display: block;
    width: 22px;
    height: 2px;
    background: var(--ink);
    transition: transform .25s var(--ease), opacity .25s var(--ease);
  }
  .nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(2) { opacity: 0; }
  .nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

  /* Full-screen panel that slides in from the right instead of just
     appearing — always rendered (transform, not display, so it can
     animate), pushed fully off-screen at rest and pulled onscreen by
     .is-open (toggled by js/nav.js). Doesn't overlap .site-header
     (top: var(--header-h)) so the toggle there — already morphed into
     an X via [aria-expanded] — stays reachable regardless of z-index.
     It DOES overlap the fixed .site-footer (also z-index: 20), so
     this needs to outrank that. */
  .site-nav {
    display: flex;
    position: fixed;
    top: var(--header-h);
    left: 0;
    right: 0;
    /* Covers all the way to the true screen bottom (over the footer,
       hidden underneath at z-index 23 vs. its 20) instead of stopping
       above it — that gap read as a visible sliver of Terms/Refund
       poking out below the menu. Covering it fully also makes the
       centered links symmetric top/bottom, since there's no longer a
       visible footer competing for the "below" half of the space. */
    bottom: 0;
    z-index: 23;
    flex-direction: column;
    justify-content: center;
    gap: 6px;
    padding: 0 22px;
    background: var(--bg);
    transform: translateX(100%);
    visibility: hidden;
    transition: transform .4s var(--ease), visibility 0s linear .4s;
  }
  .site-nav.is-open {
    transform: translateX(0);
    visibility: visible;
    transition: transform .4s var(--ease), visibility 0s linear 0s;
  }
  .site-nav a {
    width: 100%;
    padding: 14px 0;
    font-family: var(--font-display);
    font-size: 26px;
    letter-spacing: 0.01em;
  }
  /* Full-screen nav open — lock the page behind it in place. */
  body.nav-open { overflow: hidden; }

  /* Menu quick-view drawer — tapping a gallery tile slides this in
     from the right instead of navigating straight to product.html
     (desktop keeps the plain navigation, see js/menu.js). Same
     translateX + delayed-visibility pattern as .site-nav. Covers the
     full screen height including the header, since it's its own
     overlay context rather than a nav-menu-under-the-header panel. */
  /* Matches the drawer's own top edge exactly — inset:0 here used to
     extend this dark tint up over the header too (z-index 21 beats the
     header's 20), greying out the logo/nav toggle the drawer itself
     was deliberately left uncovering. Redundant against the drawer's
     own opaque background anyway; kept only for the click-outside
     handler in js/menu.js. */
  .menu-drawer-backdrop {
    position: fixed;
    top: var(--header-h);
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(59, 59, 60, 0.45);
    z-index: 21;
  }
  .menu-drawer {
    display: flex;
    flex-direction: column;
    position: fixed;
    top: var(--header-h);
    left: 0;
    right: 0;
    bottom: 0;
    background: var(--bg);
    z-index: 21;
    overflow-y: auto;
    transform: translateX(100%);
    visibility: hidden;
    transition: transform .4s var(--ease), visibility 0s linear .4s;
  }
  .menu-drawer.is-open {
    transform: translateX(0);
    visibility: visible;
    transition: transform .4s var(--ease), visibility 0s linear 0s;
  }
  .menu-drawer__close {
    position: absolute;
    top: 14px;
    right: 14px;
    width: 36px;
    height: 36px;
    border: none;
    background: none;
    font-size: 24px;
    line-height: 1;
    cursor: pointer;
    z-index: 1;
  }
  .menu-drawer__media {
    width: 100%;
    aspect-ratio: 1 / 1;
    overflow: hidden;
    background: var(--dough);
    flex-shrink: 0;
  }
  .menu-drawer__img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .menu-drawer__body { padding: 22px; display: flex; flex-direction: column; gap: 10px; }
  .menu-drawer__title-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
  /* Multi-price items (Canelés' "Plain $6 · Matcha $6.5 · Earl Grey $6.5")
     drop below the name instead of squeezing in beside it. */
  .menu-drawer__title-row--stacked { flex-direction: column; align-items: flex-start; gap: 4px; }
  .menu-drawer__name { font-family: var(--font-display); font-size: 22px; margin: 0; }
  .menu-drawer__price { font-size: 15px; color: var(--ink-soft); margin: 0; white-space: nowrap; letter-spacing: 0.03em; }
  .menu-drawer__desc { font-size: 15px; line-height: 1.5; margin: 0; }
  .menu-drawer__allergens { font-size: 12px; letter-spacing: 0.04em; color: var(--ink-soft); margin: 0; }
  /* Extra breathing room above "You might also like" — .menu-drawer__body's
     own bottom padding (22px) plus this wasn't reading as enough separation
     from the allergen accordion right above it. */
  .menu-drawer__related { padding: 24px 22px 32px; }
  .menu-drawer__related-label {
    font-size: 12px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ink-soft);
    margin: 0 0 10px;
  }
  .menu-drawer__related-grid { grid-template-columns: repeat(3, 1fr); gap: 4px; }

  .view { grid-template-columns: 1fr; }
  /* About/Catering/Contact/Gift card are capped to one viewport on
     desktop (side-by-side columns), but stacking the text pane above
     the (usually much taller) photo pane here runs into an intrinsic-
     sizing quirk: overflow-y: auto on a pane inside a fixed-height
     grid/flex row lets it collapse far below its own content height,
     so the two panes end up overlapping instead of stacking cleanly.
     Simplest fix: drop the one-viewport cap and let the page scroll
     normally here, same as Menu/Product already do. */
  .view--about,
  .view--catering,
  .view--giftcard {
    height: auto;
    min-height: 0;
    overflow: visible;
  }
  /* Contact has no two-pane text/photo split like the pages above — just
     one centered flex block — so it never had their overlap bug and
     doesn't need height:0. It was bundled into that reset anyway, which
     collapsed it down to its own content height instead of the full
     viewport: with no room left to center into, the flex centering had
     nothing to work with, and .contact-running-mark's `bottom: ...`
     (measured against that now-short box) landed up near the top of the
     page instead of the actual bottom of the screen. Keep it tall enough
     to center within, but let it grow past 100vh if content ever needs
     more room instead of clipping it. */
  .view--contact {
    height: auto;
    min-height: 100vh;
    overflow: visible;
  }
  .view--about .view__pane--left,
  .view--catering .view__pane--left,
  .view--giftcard .view__pane--left {
    overflow-y: visible;
    justify-content: flex-start;
  }
  .view--about .view__pane--right.view__pane--image,
  .view--catering .view__pane--right.view__pane--image,
  .view--giftcard .view__pane--right.view__pane--image {
    height: auto;
    padding-bottom: calc(var(--footer-h) + 40px);
  }
  /* The RIGHT-SECTION ALIGNMENT RULE's flush-left/gap-right padding only
     makes sense while these panes share a column edge with the desktop
     two-column grid — below 860px everything stacks into one column, so
     that same padding just reads as the photo hugging the left edge with
     an uneven gap on the right. Match the symmetric edge padding every
     other stacked mobile element uses instead. */
  .view--about .view__pane--right.view__pane--image,
  .view--catering .view__pane--right.view__pane--image,
  .view--giftcard .view__pane--right.view__pane--image {
    padding-left: 22px;
    padding-right: 22px;
  }
  /* About, catering, and gift card all read better with the photo up
     top like a hero and the text/form beneath it, instead of desktop's
     side-by-side order. Now that the photo pane leads instead of the
     text pane, it needs the same header-clearing buffer every other
     "first on the page" pane gets — the bare var(--header-h) it
     inherited left the photo sitting flush against the header with no
     breathing room, so on some viewports it read as overlapping/
     clipped under the header. */
  .view--about .view__pane--right.view__pane--image,
  .view--catering .view__pane--right.view__pane--image,
  .view--giftcard .view__pane--right.view__pane--image {
    order: 1;
    padding-top: calc(var(--header-h) + 24px);
    padding-bottom: 20px;
  }
  /* The gift card photo is a small centered card graphic, not a
     full-bleed hero shot — the shared 60vh hero height just left a
     wide empty band around it. */
  .view--giftcard .view__pane--right.view__pane--image {
    min-height: 0;
  }
  .view--about .view__pane--left,
  .view--catering .view__pane--left,
  .view--giftcard .view__pane--left {
    order: 2;
    /* The base padding-top clears the fixed header for a pane that's
       first on the page — now that the photo pane leads instead, this
       pane just needs a modest gap under it. */
    padding-top: 24px;
  }
  /* Desktop pins the intro copy's bottom edge to the photo's bottom
     edge with a 240px margin-top (see js/catering.js's
     alignCateringIntro, which already skips this calculation below
     860px) — left in place at mobile it was just dead space between
     the reordered photo and the text underneath it. */
  .catering-intro,
  .giftcard-intro { margin-top: 0; }

  /* Menu's left pane only ever balances the grid column next to the
     gallery on desktop — empty on mobile, it was still claiming the
     full header-clearing padding and leaving a tall blank gap above
     the first row of photos. */
  .view--menu .view__pane--left { display: none; }
  .gallery { grid-template-columns: repeat(2, 1fr); gap: 4px; }

  .product-top { grid-template-columns: 1fr; }
  /* Image first like a hero, description stacked below it. Full-bleed
     1:1 square instead of desktop's flush-left/gap-right pane padding
     (which left uneven cream margins once this stacks to one column)
     or the old contain+letterbox treatment (which left dough-coloured
     bands above/below) — edge-to-edge, cropped to fill the square. */
  .product-top .view__pane--right.view__pane--image { order: 1; }
  .product-top .view__pane--left { order: 2; padding-top: 28px; }
  .view--product .view__pane--right.view__pane--image {
    padding-left: 0;
    padding-right: 0;
    min-height: 0;
  }
  .view--product .media-frame {
    height: auto;
    aspect-ratio: 1 / 1;
  }
  .view--product .product-hero { object-fit: cover; }
  /* The fixed 180px title column left almost no room for the
     description/accordion column on narrow screens, forcing the grid
     wider than the viewport. Stack title above body instead. */
  /* Desktop's 300px margin-top nudges the description down to sit
     roughly level with the photo's vertical center in the two-column
     layout — dead space once the columns stack on mobile. */
  .product-detail-layout { grid-template-columns: 1fr; gap: 12px; margin-top: 0; }
  .view__pane--right.view__pane--image { min-height: 60vh; }
  .media-frame { height: calc(100% - 28px); }
  /* padding-top deliberately omitted — .view__pane--left/--right each
     set their own header-clearing padding-top, and this generic rule
     (equal specificity, later in the cascade) was silently winning
     and overriding it back down to 28px, tucking the first row of
     content under the fixed header. */
  .view__pane { padding-left: 22px; padding-right: 22px; padding-bottom: 28px; }
  .product-related__grid { grid-template-columns: repeat(2, 1fr); }

  /* Desktop's 180px label + 110px inner day-label, side by side, left
     almost nothing for the actual time range on a narrow phone —
     that's what was wrapping "7:30 AM - 3:00 PM" onto two lines.
     Stack the row label above its values instead, freeing the full
     width for them. */
  .about-row { flex-direction: column; align-items: flex-start; gap: 6px; }
  .about-row__label { width: auto; }

  /* Smaller text + more room between each block — at the desktop sizes,
     stacked full-width on mobile read as crowded compared to the clear
     1-2-3 separation the 3-column desktop layout gives for free. */
  .contact-grid { grid-template-columns: 1fr; padding-top: 6vh; gap: 76px; }
  .contact-col { gap: 8px; }
  .info-label { font-size: 12px; }
  .info-value { font-size: 14px; }

  /* Un-fix the footer on mobile — instead of a bar pinned over the
     bottom of the viewport at all times, it now sits at the actual end
     of the page's content and only comes into view once you scroll
     all the way down. */
  .site-footer {
    position: static;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 20px;
    padding: 14px 20px;
  }
  .footer-link { font-size: 11px; }

  .landing__address { width: 340px; }
  .landing__mark { right: 22px; top: 22px; width: 110px; }
}