/* Hand-written additions on top of styles.css + fonts.css. This is where
   the site's own custom behavior lives — everything else is generated. */

/* Real, pre-existing bug found during the 2026-09-19 mobile pass: the hero
   video's object-cover/object-[center_35%]/sm:object-center classes look
   like ordinary Tailwind utilities, but only object-cover actually exists
   in the frozen styles.css extraction — neither object-position class was
   ever generated, so the video has been rendering at the browser's default
   center-center crop on every viewport this whole time, mobile included.
   Attribute selectors (not class selectors) sidestep escaping the literal
   [ ] % : characters in these class names. */
[class~="object-[center_35%]"] { object-position: center 35%; }
@media (min-width: 640px) {
  [class~="sm:object-center"] { object-position: center; }
}

/* Seasonal Drink Highlights hover: the whole row (image, text, and the
   space between them — the permanent padding below makes that space real
   instead of just the flex gap) is a single hover/focus target. The entire
   card fills with brand green and lifts slightly; only color/transform/
   shadow animate, padding and radius are permanent so nothing changes size
   on hover. No pop-up card — all info stays normal, always-visible content. */
.seasonal-row {
  background-color: transparent;
  transition:
    background-color 0.35s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.35s cubic-bezier(0.16, 1, 0.3, 1),
    box-shadow 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}
.seasonal-row:hover,
.seasonal-row:focus-within {
  background-color: var(--brand-green);
  transform: translateY(-6px) scale(1.015);
  box-shadow: 0 24px 40px -16px rgba(13, 63, 41, 0.45);
}
.seasonal-row .text-brand-green-dark,
.seasonal-row .text-muted-foreground {
  transition: color 0.35s ease;
}
.seasonal-row:hover .text-brand-green-dark,
.seasonal-row:focus-within .text-brand-green-dark {
  color: var(--paper);
}
.seasonal-row:hover .text-muted-foreground,
.seasonal-row:focus-within .text-muted-foreground {
  color: rgb(250 248 243 / 85%);
}
.seasonal-row .bg-brand-green\/10 {
  transition: background-color 0.35s ease;
}
.seasonal-row:hover .bg-brand-green\/10,
.seasonal-row:focus-within .bg-brand-green\/10 {
  background-color: rgb(255 255 255 / 15%);
}

/* styles.css is a frozen extraction from a past `next build` — it only
   contains utility classes the React app happened to use at that time. The
   crêpes showcase below needs one Tailwind utility that extraction never
   included, so it's added by hand here to match Tailwind's own definition
   exactly (same --spacing token, same formula) rather than substituting a
   different spacing value and letting the two sites drift apart. */
.mt-10 {
  margin-top: calc(var(--spacing) * 10);
}

/* Same story as .mt-10 above: styles.css only has size-2 through size-9 (the
   sizes the React app happened to use), so the mobile hamburger trigger's
   bump to a proper 44px touch target needs its own hand-added rule, using
   Tailwind's own formula so it stays consistent with every other size-*
   value already in the file. */
.size-11 {
  width: calc(var(--spacing) * 11);
  height: calc(var(--spacing) * 11);
}

/* Accordion open/close (menu categories, FAQ items): animates a real
   element.style.height set by accordion.js, not a CSS keyframe var() — this
   is deliberate. var() references inside @keyframes to a custom property
   set via inline style do not reliably resolve across browsers, so a plain
   height transition is the robust choice here. */
[data-accordion-content] {
  overflow: hidden;
  transition: height 0.2s ease-out;
}

/* ---- Caffeine / dairy icons -------------------------------------------
   Colors here are the single source of truth the legend key must match
   exactly — a green mug = contains caffeine, a red crossed-out mug =
   caffeine-free, a warm-brown milk glass = contains dairy by default. */
.icon-caffeine--contains { color: var(--brand-green); }
.icon-caffeine--free { color: #b3261e; }
.icon-dairy { color: #8a6d3b; }

/* ---- Menu / gallery key --------------------------------------------- */
.menu-key {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 1.5rem;
  border-radius: 0.75rem;
  border: 1px solid var(--border);
  background: var(--card);
  padding: 0.75rem 1rem;
  font-size: 0.75rem;
}
.menu-key__item {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--foreground);
  white-space: nowrap;
}
.menu-key__note {
  flex-basis: 100%;
  margin-top: 0.15rem;
  font-size: 0.7rem;
  line-height: 1.5;
  color: var(--muted-foreground);
}

/* ---- Crêpe / food cards ------------------------------------------------
   The plates are round, shot on white, and taller than the old fixed 4:3
   object-cover box allowed — that box was cropping the plate edges. This
   container has a fixed height budget but VISIBLE overflow, with the image
   at its natural proportions (object-fit: contain) and bottom-aligned, so
   the full plate always stays visible and may intentionally peek above the
   card's own top edge instead of being cropped or stretched. */
.food-card__image-box {
  position: relative;
  height: 12rem;
  overflow: visible;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.food-card__image-box img {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 128%;
  object-fit: contain;
}
@media (min-width: 640px) {
  .food-card__image-box { height: 14rem; }
}

/* Extra headroom above the crêpe image grid so a peeking plate (see
   .food-card__image-box above) can never reach the "Now available in
   three flavors" text sitting above it. Sized to clear the largest
   possible peek (28% of the box height) with margin to spare. */
.crepe-grid {
  margin-top: 6rem;
}
@media (min-width: 640px) {
  .crepe-grid { margin-top: 7rem; }
}

/* ---- Nav social bubble (desktop, homepage only) ------------------------
   Icons start hidden/small/low, matching "inside the brown bar"; nav.js
   toggles .is-visible once the bar scrolls out of view, which fades the
   icons in while they rise and grow into place — reads as a small bubble
   separating from the bar and settling into the nav. Reversing removes
   .is-visible, so scrolling back up smoothly shrinks/fades them back out
   (nav.js only ever shows them again once the bar is back in view). Plain
   CSS (not Tailwind utility classes) so the transform/opacity/timing are
   guaranteed rather than depending on which arbitrary utilities happen to
   be present in the frozen styles.css extraction. */
[data-nav-social] {
  opacity: 0;
  pointer-events: none;
  transform: translateY(-6px) scale(0.8);
  transition: opacity 0.3s ease-out, transform 0.3s ease-out;
}
[data-nav-social].is-visible {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0) scale(1);
}

/* ---- Homepage gallery preview: green panel redesign -------------------
   One unified, on-brand presentation instead of loose image tiles: a
   rounded forest-green panel holding a clean, uniform grid of small cream
   "mini menu card" tiles (equal image sizes, consistent cup scale, no dark
   caption strip). */
.gallery-preview-panel {
  background: var(--brand-green-dark);
  border-radius: 2rem;
  padding: 1.5rem;
}
@media (min-width: 640px) {
  .gallery-preview-panel { padding: 2.5rem; }
}
.gallery-preview-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1rem;
}
@media (min-width: 640px) {
  .gallery-preview-grid { grid-template-columns: repeat(4, 1fr); gap: 1.25rem; }
}
.gallery-preview-card {
  border-radius: 1.25rem;
  background: var(--cream);
  padding: 0.65rem;
  text-align: center;
}
.gallery-preview-card__image {
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  border-radius: 0.85rem;
  background: var(--paper);
}
.gallery-preview-card__image img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.gallery-preview-card__name {
  margin-top: 0.5rem;
  font-family: var(--font-display);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--brand-green-dark);
}
.gallery-preview-card__meta {
  margin-top: 0.2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  font-size: 0.68rem;
  color: var(--muted-foreground);
}

/* ---- Menu-page category navigation ------------------------------------ */
.menu-layout {
  display: block;
}
@media (min-width: 1024px) {
  .menu-layout {
    display: grid;
    grid-template-columns: 12rem 1fr;
    gap: 2.5rem;
    align-items: start;
  }
}
.category-nav-desktop {
  display: none;
}
@media (min-width: 1024px) {
  .category-nav-desktop {
    display: block;
    position: sticky;
    top: 6rem;
    border-radius: 1rem;
    background: var(--brand-green-dark);
    padding: 1rem;
  }
}
.category-nav-desktop__eyebrow {
  padding-inline: 0.5rem;
  margin-bottom: 0.5rem;
  font-size: 0.65rem;
  color: var(--gold);
}
.category-nav-desktop__item {
  display: block;
  width: 100%;
  border: none;
  cursor: pointer;
  border-radius: 0.5rem;
  padding: 0.5rem 0.75rem;
  text-align: left;
  font-size: 0.875rem;
  font-weight: 500;
  background: transparent;
  color: rgb(246 240 230 / 85%);
  transition: background-color 0.2s ease, color 0.2s ease;
}
.category-nav-desktop__item:hover { background: rgb(255 255 255 / 10%); color: var(--paper); }
.category-nav-desktop__item[aria-current="true"] { background: var(--gold); color: var(--brand-green-dark); }

.category-nav-mobile {
  position: sticky;
  top: 4rem;
  z-index: 20;
  margin-inline: -1.25rem;
  overflow-x: auto;
  border-bottom: 1px solid var(--border);
  background: rgb(250 248 243 / 95%);
  padding: 0.65rem 1.25rem;
  backdrop-filter: blur(6px);
}
@media (min-width: 640px) { .category-nav-mobile { top: 5rem; } }
@media (min-width: 1024px) { .category-nav-mobile { display: none; } }
.category-nav-mobile__row {
  display: flex;
  width: max-content;
  gap: 0.5rem;
}
.category-nav-mobile__item {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  min-height: 2.75rem;
  border: none;
  cursor: pointer;
  border-radius: 999px;
  padding: 0.5rem 1rem;
  font-size: 0.85rem;
  font-weight: 500;
  background: var(--muted);
  color: var(--foreground);
}
.category-nav-mobile__item[aria-current="true"] { background: var(--brand-green-dark); color: var(--paper); }

/* ---- Mobile floating quick-actions dock (2026-09-19; scroll collapse
   restored 2026-09-19) -----------------------------------------------------
   Replaces the old edge-to-edge 3-column bottom bar with a small centered
   pill so it reads as part of the cafe's own design rather than an app
   toolbar. Colors are the site's own tokens: --paper (cream), --brand-
   green/-dark (forest green), the existing dairy-icon brown (#8a6d3b) for a
   warm border tint, and --peach for the pressed-state accent.

   assets/js/mobile-nav.js (loaded identically on every real page) toggles
   the one .is-collapsed class below while the user is actively scrolling
   down; every link stays a real ~44px tap target in both states (min-
   height/min-width are NOT reduced when collapsed — only the label width/
   opacity and the dock's own padding shrink), so collapsing only ever
   changes appearance, never blocks tapping through to Menu/Order/Call.
   This same class + file pair is THE ONLY mobile bottom-nav implementation
   in the project — there is deliberately no per-page CSS override and no
   second script; if a future change needs to touch this behavior, edit
   these two files and it applies everywhere at once.

   Desktop hiding is done with this file's own @media rule after the block
   below (matching .category-nav-mobile's pattern above — the media query
   has to come AFTER the base rule to win the cascade), not the markup's
   lg:hidden utility class alone: custom.css loads after styles.css, so an
   unconditional .mobile-dock rule of equal specificity would otherwise beat
   lg:hidden at every width, which is exactly what happened in testing
   before this was split out. */
.mobile-dock {
  position: fixed;
  left: 50%;
  bottom: calc(0.85rem + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.3rem;
  border-radius: 999px;
  background: rgb(250 248 243 / 92%);
  border: 1px solid rgb(138 109 59 / 18%);
  box-shadow: 0 10px 28px -10px rgb(13 63 41 / 30%), 0 2px 8px -2px rgb(13 63 41 / 14%);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: gap 0.2s ease, padding 0.2s ease;
}
.mobile-dock__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  min-height: 2.75rem;
  min-width: 2.75rem;
  padding: 0.5rem 0.95rem;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--brand-green-dark);
  white-space: nowrap;
  transition: padding 0.2s ease, background-color 0.2s ease;
}
.mobile-dock__item:active { background: rgb(244 210 188 / 60%); }
.mobile-dock__icon { flex-shrink: 0; width: 1.2rem; height: 1.2rem; }
.mobile-dock__label {
  overflow: hidden;
  max-width: 4rem;
  opacity: 1;
  transition: max-width 0.2s ease, opacity 0.15s ease, margin-left 0.2s ease;
}
.mobile-dock__item--order {
  background: var(--brand-green);
  color: var(--paper);
}
.mobile-dock__item--order:active { background: var(--brand-green-dark); }

.mobile-dock.is-collapsed { gap: 0.15rem; padding: 0.3rem; }
.mobile-dock.is-collapsed .mobile-dock__item { padding: 0.6rem; }
.mobile-dock.is-collapsed .mobile-dock__label {
  max-width: 0;
  opacity: 0;
  margin-left: -0.4rem;
}

@media (min-width: 1024px) {
  .mobile-dock { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .mobile-dock,
  .mobile-dock__item,
  .mobile-dock__label {
    transition: none;
  }
}
