/* Components — app shell, mockup-bar, nav, mobile menu, buttons, surfaces, help, toast, lightbox. */


/* ── App shell ────────────────────────── */
.app { height: 100vh; display: flex; flex-direction: column; }
.mockup-bar {
  height: var(--mockup-h);
  background: var(--brand-deep);
  color: var(--champagne-light);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-align: center;
  font-weight: 500;
  display: flex; align-items: center; justify-content: center; gap: 12px;
  flex-shrink: 0;
}
.mockup-bar span { color: var(--champagne); margin: 0 4px; }
/* Theme switcher pills — review-only control, lives in the mockup-bar.
   Persists to localStorage and applies before paint via the head bootstrap. */
.mb-theme {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding-left: 8px;
  border-left: 1px solid rgba(var(--cream-rgb),0.18);
  flex-wrap: wrap;
  row-gap: 4px;
}
.mb-theme-label {
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--champagne);
  opacity: 0.7;
  margin-right: 2px;
}
.mb-theme-btn {
  background: rgba(var(--cream-rgb),0.06);
  border: 1px solid rgba(var(--cream-rgb),0.14);
  color: var(--champagne-light);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.06em;
  padding: 2px 9px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.18s var(--ease), color 0.18s var(--ease), border-color 0.18s var(--ease);
}
.mb-theme-btn:hover { background: rgba(var(--cream-rgb),0.14); }
.mb-theme-btn[aria-pressed="true"] {
  background: var(--champagne);
  color: #1A1208;
  border-color: var(--champagne);
}

/* ── Nav ──────────────────────────────── */
.app-nav {
  height: var(--nav-h);
  background: rgba(var(--cream-rgb), 0.86);
  backdrop-filter: saturate(150%) blur(18px);
  -webkit-backdrop-filter: saturate(150%) blur(18px);
  border-bottom: 1px solid var(--border);
  /* Soft drop-shadow under the nav so content scrolling beneath reads
     as "passing under" instead of meeting a hard horizontal cut. */
  box-shadow: 0 4px 14px rgba(58, 40, 24, 0.10);
  /* Grid (not flex) so tabs sit centered on the viewport, not centered
     between logo and nav-right. The two 1fr columns balance regardless
     of the intrinsic widths of logo / right-cluster. */
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: 0 36px;
  gap: 32px;
  flex-shrink: 0;
  z-index: 10;
  position: relative;
}
/* Champagne hairline at very top — luxury packaging cue */
.app-nav::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 1px;
  background: linear-gradient(90deg,
    transparent 0%,
    rgba(201,176,138,0.0) 8%,
    rgba(201,176,138,0.55) 50%,
    rgba(201,176,138,0.0) 92%,
    transparent 100%);
}
.nav-logo { height: 44px; display: flex; align-items: center; cursor: pointer; justify-self: start; }
/* Real Elite Tents logo from the Webflow site (downloaded to
   photos/brand/logo.png, 303×84). Rendered as a CSS mask so the colour
   is driven by background-color — switches between espresso (default)
   and any other brand colour without touching the PNG itself. */
.nav-logo-img {
  display: inline-block;
  height: 40px;
  aspect-ratio: 303 / 84;
  background-color: var(--brand);
  -webkit-mask: url("../photos/brand/logo.png") no-repeat center / contain;
  mask: url("../photos/brand/logo.png") no-repeat center / contain;
}

.nav-tabs { display: flex; justify-content: center; gap: 4px; }
.tab-btn {
  padding: 9px 18px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--muted);
  border-radius: 999px;
  transition: color 0.25s var(--ease);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  position: relative;
}
.tab-btn:hover { color: var(--brand); }
/* Active = editorial underline, NOT a filled pill. The filled dark pill is
   reserved for the CTA — under the aubergine theme --cta-bg equals --brand,
   so a filled active tab read as a second "Request a quote" button (state
   masquerading as action). Marker: 3px rounded bar spanning the label,
   scaleX-revealed from center. Brings desktop in family with the mobile
   menu's non-pill active treatment (accent text + indent). */
.tab-btn.active { color: var(--brand); }
.tab-btn::after {
  content: "";
  position: absolute;
  left: 18px;
  right: 18px;
  bottom: 3px;
  height: 2px;
  border-radius: 999px;
  background: var(--brand);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform 0.25s var(--ease);
}
.tab-btn.active::after { transform: scaleX(1); }
.tab-btn:active { transform: scale(0.96); }
.tab-badge {
  background: var(--accent);
  color: var(--cream);
  font-size: 10px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 999px;
  min-width: 18px;
  text-align: center;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}
.tab-badge.hidden { display: none; }

.nav-right { display: flex; align-items: center; gap: 18px; justify-self: end; }

/* On the RAQ view itself, the header "Request a quote" CTA is redundant
   (it would just scroll the form to the top). Hide it and let the phone
   CTA carry the secondary path. Root data-attribute is set by
   switchView() in site.js. */
html[data-active-view="quote"] .nav-cta-mobile { display: none; }

/* Home view, NARROW phones only (<600): while the hero's own CTAs are in
   viewport, the header CTA hides — a phone-width header has no room for full
   phone + CTA + hamburger, and the hero already shows the primary CTA, so the
   freed space lets the phone expand to its full number (mobile.css). It fades
   back in as the hero CTAs scroll behind the sticky header.

   At COMPACT/WIDE (>=600) the header CTA stays VISIBLE at the top: there's
   ample room, the repeated-CTA pattern (header + hero) is a conventional,
   well-converting one, and keeping the CTA present means the phone sits in its
   right-aligned [phone][CTA][hamburger] cluster instead of floating into an
   empty reserved slot. data-hero-cta-in-view is set by an IntersectionObserver
   in site.js (initHeaderCtaScrollReveal) observing .hero-ctas. */
@media (max-width: 599px) {
  html[data-active-view="home"][data-hero-cta-in-view="true"] .nav-cta-mobile {
    opacity: 0;
    pointer-events: none;
    transform: translateY(8px);
    transition: opacity 220ms var(--ease-soft), transform 220ms var(--ease-soft), filter 0.28s var(--ease-soft), box-shadow 0.28s var(--ease-soft);
  }
}

/* Smart cart bar — defined in mobile.css for the mobile breakpoint.
   Hidden on desktop (the desktop tabbar already shows the My Event tab
   + badge, so the bar would duplicate). */
@media (min-width: 1024px) {
  .smart-cart-bar { display: none !important; }
}

.nav-phone {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  color: var(--brand);
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  text-decoration: none;
  /* Phone + CTA are siblings inside .nav-right (a flex container inside a
     1fr grid column). Without flex-shrink: 0 + white-space: nowrap, the
     1fr/auto/1fr balance squeezes the right column at ~1280px and forces
     both the phone number and the CTA button text onto two lines. */
  flex-shrink: 0;
  transition: color 0.2s var(--ease);
}
.nav-phone-icon { width: 16px; height: 16px; flex-shrink: 0; }
.nav-phone-num { white-space: nowrap; }
.nav-phone:hover { color: var(--accent); }

/* Nav CTA never carries the trailing arrow icon. Text-only across all
   viewports per design direction. Hero + inline btn-primary instances
   keep their arrows because the arrow IS the brand chrome there. */
.nav-cta-mobile .btn-icon { display: none; }
/* No arrow here, so the btn-primary asymmetric padding (10/12/10/18, whose
   tight 12px right hugged the dropped arrow) reads left-heavy. Symmetrize. */
.nav-cta-mobile { gap: 0; padding: 10px 18px; }

/* Narrow desktop (iPad landscape + 1280px-class laptops). The 1fr/auto/1fr
   grid balance that viewport-centers the tabs is tight here: at 1280px the
   right column gets ~306px, less than the phone + CTA natural width (~333px);
   at 1024px (iPad landscape, mobile breakpoint floor) it's tighter still.
   Trim nav padding, grid gap, and tab horizontal padding to free ~70px for
   the right cluster so neither item is forced to flex-shrink. */
@media (min-width: 1024px) and (max-width: 1279px) {
  .app-nav { padding: 0 20px; gap: 16px; }
  .tab-btn { padding: 9px 14px; }
  .tab-btn::after { left: 14px; right: 14px; } /* track the tighter padding */
}

/* Hamburger (mobile) — bars cross-fade to an X when menu is open.
   Both icons stay in DOM; aria-expanded drives the rotation+opacity swap.
   Same grid-stack pattern used by the product-add icon and review carousels. */
.nav-hamburger {
  display: none;
  width: 42px;
  height: 42px;
  place-items: center;
  color: var(--brand);
  background: transparent;
  border-radius: 10px;
  flex-shrink: 0;
  transition: background 0.2s var(--ease);
}
.nav-hamburger:hover { background: rgba(58,40,24,0.08); }
.nav-hamburger:active { transform: scale(0.96); }
.nav-hamburger svg {
  width: 22px;
  height: 22px;
  grid-area: 1 / 1;
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
}
.nav-hamburger .hamburger-bars { opacity: 1; transform: rotate(0); }
.nav-hamburger .hamburger-x { opacity: 0; transform: rotate(-90deg); }
.nav-hamburger[aria-expanded="true"] .hamburger-bars { opacity: 0; transform: rotate(90deg); }
.nav-hamburger[aria-expanded="true"] .hamburger-x { opacity: 1; transform: rotate(0); }

/* Mobile menu overlay */
.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: 1200;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s var(--ease);
}
.mobile-menu.show { opacity: 1; pointer-events: auto; }
.mobile-menu-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(35,24,15,0.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.mobile-menu-panel {
  position: absolute;
  top: 0;
  right: 0;
  width: 86%;
  max-width: 360px;
  height: 100%;
  background: var(--cream);
  padding: 24px 28px 28px;
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 0.45s var(--ease);
  box-shadow: -10px 0 60px rgba(35,24,15,0.22);
}
.mobile-menu.show .mobile-menu-panel { transform: translateX(0); }
.mobile-menu-head { display: flex; justify-content: flex-end; margin-bottom: 20px; }
.mobile-menu-close {
  width: 48px; height: 48px;
  display: flex; align-items: center; justify-content: center;
  background: transparent;
  border-radius: 10px;
  color: var(--brand);
  font-size: 28px;
  font-family: var(--serif);
  font-weight: 300;
  transition: background 0.2s var(--ease);
}
.mobile-menu-close:hover { background: rgba(58,40,24,0.08); }
.mobile-menu-close:active { transform: scale(0.96); }
.mobile-menu-nav { display: flex; flex-direction: column; gap: 0; flex: 1; }
.mobile-menu-link {
  font-family: var(--serif);
  font-weight: 300;
  font-size: 28px;
  color: var(--ink);
  padding: 16px 0;
  letter-spacing: -0.02em;
  border-bottom: 1px solid var(--border);
  text-align: left;
  cursor: pointer;
  transition: color 0.25s var(--ease), padding 0.25s var(--ease);
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: transparent;
  text-wrap: balance;
}
.mobile-menu-link:hover { color: var(--accent); padding-left: 6px; }
.mobile-menu-link.active { color: var(--accent); }
.mobile-menu-link.active .menu-badge { background: var(--accent); color: var(--cream); }
.menu-badge {
  background: var(--cream-2);
  color: var(--accent);
  font-size: 12px;
  font-weight: 500;
  padding: 2px 10px;
  border-radius: 999px;
  font-family: var(--sans);
  min-width: 26px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.menu-badge.hidden { display: none; }
.mobile-menu-link-arrow {
  font-size: 18px;
  color: var(--faint);
  opacity: 0.5;
  transition: transform 0.25s var(--ease), opacity 0.25s var(--ease);
}
.mobile-menu-link.active .mobile-menu-link-arrow {
  color: var(--accent);
  opacity: 1;
  transform: translateX(4px);
}
.mobile-menu-contact { display: flex; flex-direction: column; gap: 12px; }
.mobile-menu-contact-label {
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--faint);
  font-weight: 500;
  margin-bottom: 4px;
}
.mobile-menu-contact a,
.mobile-menu-contact span {
  display: flex; align-items: center; gap: 12px;
  font-size: 14px;
  color: var(--ink);
  padding: 6px 0;
}
.mobile-menu-contact svg {
  width: 16px; height: 16px;
  color: var(--accent);
  flex-shrink: 0;
}

/* ── Buttons ───────────────────────────── */
/* Primary CTA — uses semantic tokens so themes swap it without
   touching this rule. Box-shadow tint pulls from --cta-shadow-rgb.
   Hover state (s24 lead direction): Apple-restrained — one tiny scale
   for "alive," one subtle filter for color, nothing else. Earlier
   iteration moved the arrow circle separately + lifted the whole
   button + grew the shadow; that read as too-many-things-at-once.
   The arrow now stays put relative to its button. Slimmer base size
   too: lead wanted the CTA a touch smaller across the system. */
.btn-primary {
  background: var(--cta-bg);
  color: var(--cta-fg);
  padding: 10px 12px 10px 18px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.02em;
  /* Transform is FAST + un-delayed for snappy press/hover (Emil tip 1 + 6).
     The entrance is driven by Motion One (WAAPI), which ignores this CSS
     transition, so the old 360ms/160ms-delay transform only ever made the
     press feel laggy. Opacity keeps its entrance-fallback timing (used by
     the no-JS [data-stagger] fallback). */
  transition: opacity 360ms 160ms var(--ease-soft), transform 0.2s var(--ease-soft), filter 0.28s var(--ease-soft), box-shadow 0.28s var(--ease-soft);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  /* Pair with .nav-phone. When this button is inside .nav-right (a flex
     container) the 1fr right column squeezes both at narrow desktops. */
  white-space: nowrap;
  flex-shrink: 0;
  box-shadow: var(--inset-highlight-dark), 0 1px 2px rgba(var(--cta-shadow-rgb),0.08), 0 4px 14px rgba(var(--cta-shadow-rgb),0.22);
  will-change: transform;
}
.btn-primary:hover {
  filter: brightness(0.96) saturate(1.08);
  transform: scale(1.02);
}
.btn-primary:active { transform: scale(0.98); }
/* Press-confirm "push". A complete tactile gesture: press in (0.94), spring
   back out past rest (1.02), settle (1) — then pressNav() navigates on
   animationend so the full push reads BEFORE the view changes. The earlier
   version held the pressed-in state then cut to the page, which read as
   "stuck"; the release is what makes it feel sophisticated. GPU-only
   (transform); CSS animation reverts cleanly so :hover/:active resume after.
   Reduced-motion: pressNav skips this and navigates instantly. */
@keyframes cta-push {
  0%   { transform: scale(1); }
  38%  { transform: scale(0.94); }
  72%  { transform: scale(1.02); }
  100% { transform: scale(1); }
}
.btn-primary.is-pushing { animation: cta-push 0.26s var(--ease-out); }

/* Button-in-Button trailing icon — nested circle wrapper.
   Lives entirely inside the button's transform on hover (no separate
   motion of its own — see comment on .btn-primary above). */
.btn-icon {
  width: 24px;
  height: 24px;
  border-radius: 999px;
  background: rgba(var(--cream-rgb),0.18);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.btn-icon svg { width: 14px; height: 14px; }

/* Hero CTA is text-only (no .btn-icon arrow), so the base btn-primary's
   arrow-asymmetric padding (18px left / 12px right — the tight right hugs the
   arrow) would shove its label right of center. Symmetrize it. The nav CTA,
   also text-only, does the same (.nav-cta-mobile above); arrow-bearing
   btn-primary instances (me-continue, raq-submit) keep the asymmetry. */
.hero-ctas .btn-primary { padding: 10px 18px; }

.btn-ghost {
  background: transparent;
  color: var(--brand);
  padding: 12px 22px;
  border-radius: 999px;
  border: 1px solid rgba(58,40,24,0.35);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.02em;
  transition: background 0.25s var(--ease), color 0.25s var(--ease), border-color 0.25s var(--ease), transform 0.25s var(--ease);
}
.btn-ghost:hover { background: var(--brand); color: var(--cream); border-color: var(--brand); }
.btn-ghost:active { transform: scale(0.96); }

.btn-ghost-light {
  background: transparent;
  color: var(--cream);
  padding: 12px 22px;
  border-radius: 999px;
  border: 1px solid rgba(var(--cream-rgb),0.45);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.02em;
  transition: background 0.25s var(--ease), border-color 0.25s var(--ease), transform 0.25s var(--ease);
  display: inline-flex; align-items: center; gap: 10px;
}
.btn-ghost-light:hover { background: rgba(var(--cream-rgb),0.12); border-color: var(--cream); }
.btn-ghost-light:active { transform: scale(0.96); }

.btn-champagne {
  background: var(--champagne);
  color: var(--brand);
  padding: 12px 14px 12px 22px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.02em;
  display: inline-flex; align-items: center; gap: 12px;
  transition: background 0.25s var(--ease), transform 0.25s var(--ease);
  box-shadow: var(--inset-highlight);
}
.btn-champagne:hover { background: var(--champagne-light); }
.btn-champagne:active { transform: scale(0.96); }
.btn-champagne .btn-icon {
  background: rgba(58,40,24,0.10);
}
.btn-champagne:hover .btn-icon {
  background: rgba(58,40,24,0.16);
  transform: translate(2px, -1px);
}

/* ── Surface helpers ──────────────────── */
/* Double-Bezel — outer shell sits on the page, inner core holds content.
   Used on Collection cards and the filter card.
   The "concentric" radii are inner = outer - padding. */
.bezel-out {
  background: linear-gradient(180deg, rgba(var(--cream-3-rgb),0.55) 0%, rgba(var(--cream-2-rgb),0.85) 100%);
  border-radius: 22px;
  padding: 6px;
  box-shadow: var(--ring-hair), var(--shadow-card);
  transition: box-shadow 0.35s var(--ease), transform 0.35s var(--ease);
}
.bezel-out:hover { box-shadow: var(--ring-hair), var(--shadow-card-hover); }
.bezel-in {
  background: var(--cream);
  border-radius: 16px;
  box-shadow: var(--inset-highlight);
  overflow: hidden;
  position: relative;
}
/* Card-level paper grain — heavy-stock paper feel on Linen surfaces.
   Layered under content via z-index, multiply-blended at low opacity so it
   reads as material texture rather than pattern. Disabled on touch + mobile
   to match the global `.grain` overlay's iOS Safari memory-pressure guard. */
.bezel-in::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: 0.05;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
}
.bezel-in > * { position: relative; z-index: 1; }
@media (pointer: coarse), (max-width: 1023px) {
  .bezel-in::before { display: none; }
}
.img-frame {
  outline: 1px solid rgba(0,0,0,0.1);
  outline-offset: -1px;
  border-radius: inherit;
}

/* Reveal-on-scroll baseline (Motion One overrides via inView) */
[data-reveal] {
  opacity: 0;
  transform: translateY(24px);
  filter: blur(4px);
  will-change: transform, opacity, filter;
}
[data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
  filter: blur(0);
  transition: opacity 0.9s var(--ease-out), transform 0.9s var(--ease-out), filter 0.6s var(--ease-out);
}
/* Stagger group baseline — initial hidden state for children */
[data-stagger] [data-stagger-item] {
  opacity: 0;
  transform: translateY(20px);
  will-change: transform, opacity;
}
[data-stagger].is-visible [data-stagger-item] {
  opacity: 1;
  transform: translateY(0);
}

/* ═══════════════════════════════════════ */
/*  HELP WIDGET (carry over, refined)      */
/* ═══════════════════════════════════════ */
.help-bubble {
  position: fixed;
  bottom: 24px;
  right: 24px;
  width: 56px;
  height: 56px;
  background: var(--brand);
  color: var(--champagne);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 900;
  box-shadow: var(--inset-highlight-dark), var(--shadow-bubble);
  transition: transform 0.35s var(--ease), background 0.25s var(--ease);
}
.help-bubble:hover { background: var(--accent); transform: translateY(-2px) scale(1.04); }
.help-bubble:active { transform: scale(0.94); }
.help-bubble svg { width: 22px; height: 22px; }
.help-bubble-dot {
  position: absolute;
  top: 6px; right: 6px;
  width: 9px; height: 9px;
  background: var(--champagne);
  border-radius: 50%;
  border: 2px solid var(--brand);
}

/* ── Back to top — secondary FAB, stacks above the help-bubble ──────────────
   Appears after ~2 viewport-heights of scroll (setupBackToTop in site.js).
   Lighter (cream-on-plum) than the help-bubble so the two don't read as the
   same control; mirrors the help-bubble's cart-bar lift on mobile (mobile.css). */
.back-to-top {
  position: fixed;
  bottom: 94px;   /* help-bubble (bottom 24 + height 56) + 14 gap */
  right: 24px;
  width: 56px;
  height: 56px;
  background: var(--cream);
  color: var(--brand);
  border: 1px solid var(--border);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 900;
  box-shadow: var(--shadow-bubble);
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px);
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease),
              visibility 0.3s var(--ease), background 0.25s var(--ease), color 0.25s var(--ease);
}
.back-to-top.visible { opacity: 1; visibility: visible; transform: translateY(0); }
.back-to-top:hover { background: var(--brand); color: var(--champagne); transform: translateY(-2px) scale(1.04); }
.back-to-top:active { transform: scale(0.94); }
.back-to-top svg { width: 22px; height: 22px; }
@media (prefers-reduced-motion: reduce) {
  .back-to-top { transition: opacity 0.3s var(--ease), visibility 0.3s var(--ease); }
  .back-to-top.visible, .back-to-top:hover, .back-to-top:active { transform: none; }
}
.help-panel {
  position: fixed;
  bottom: 92px;
  right: 24px;
  width: 380px;
  max-height: 540px;
  background: var(--cream);
  border-radius: 22px;
  box-shadow: var(--shadow-pop);
  z-index: 901;
  display: flex;
  flex-direction: column;
  opacity: 0;
  pointer-events: none;
  transform: translateY(8px) scale(0.98);
  transform-origin: bottom right;
  transition: opacity 0.28s var(--ease), transform 0.35s var(--ease);
  overflow: hidden;
}
.help-panel.show { opacity: 1; pointer-events: auto; transform: translateY(0) scale(1); }
.help-panel-header {
  padding: 22px 24px 20px;
  background: var(--brand);
  color: var(--cream);
  display: flex;
  justify-content: space-between;
  align-items: start;
  box-shadow: var(--inset-highlight-dark);
}
.help-panel-header-title {
  font-family: var(--serif);
  font-size: 19px;
  font-weight: 400;
  color: var(--cream);
}
.help-panel-header-sub {
  font-size: 12px;
  color: var(--champagne-light);
  margin-top: 4px;
}
.help-panel-close {
  font-size: 22px;
  color: var(--champagne-light);
  padding: 0 0 0 10px;
  transition: color 0.2s var(--ease);
}
.help-panel-close:hover { color: var(--champagne); }
.help-panel-body { flex: 1; overflow-y: auto; padding: 22px 24px; }
.help-panel-label {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 14px;
}
.help-question {
  background: var(--cream-2);
  border: 1px solid transparent;
  padding: 12px 16px;
  border-radius: 12px;
  font-size: 13px;
  width: 100%;
  text-align: left;
  margin-bottom: 6px;
  color: var(--ink);
  transition: background 0.25s var(--ease), color 0.25s var(--ease);
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  line-height: 1.4;
}
.help-question:hover { background: var(--cream-3); }
.help-question.active {
  background: var(--brand);
  color: var(--cream);
  box-shadow: var(--inset-highlight-dark);
}
.help-question-arrow {
  font-size: 12px;
  opacity: 0.6;
  margin-left: 10px;
  transition: transform 0.3s var(--ease);
}
.help-question.active .help-question-arrow { transform: rotate(180deg); }
.help-answer {
  padding: 12px 16px 14px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--muted);
  display: none;
  border-left: 2px solid var(--accent);
  margin: 0 0 14px 8px;
  background: var(--cream);
  border-radius: 0 8px 8px 0;
}
.help-answer.show { display: block; animation: fadeIn 0.3s var(--ease-out); }
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}
.help-panel-footer {
  padding: 14px 24px;
  border-top: 1px solid var(--border);
  background: var(--cream-2);
  font-size: 12px;
  color: var(--muted);
  text-align: center;
  line-height: 1.55;
}
.help-panel-footer a { color: var(--accent); font-weight: 500; cursor: pointer; }
.help-panel-footer a:hover { text-decoration: underline; }
.help-panel-footer strong { color: var(--brand); font-weight: 500; }

/* ═══════════════════════════════════════ */
/*  TOAST                                  */
/* ═══════════════════════════════════════ */
.toast {
  position: fixed;
  bottom: 28px;
  left: 50%;
  transform: translateX(-50%) translateY(80px);
  background: var(--brand);
  color: var(--cream);
  padding: 13px 24px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 500;
  box-shadow: var(--inset-highlight-dark), var(--shadow-bubble);
  z-index: 1050;
  opacity: 0;
  transition: opacity 0.3s var(--ease), transform 0.4s var(--ease);
  display: flex;
  align-items: center;
  gap: 10px;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.toast-icon {
  width: 18px; height: 18px;
  background: var(--champagne);
  color: var(--brand);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  /* The toast is display:flex; without flex-shrink:0 the icon gets
     squeezed horizontally when the text wraps to multiple lines —
     renders as an egg/oval instead of a circle. Pin intrinsic size. */
  flex-shrink: 0;
  flex-grow: 0;
}
.toast-text {
  /* Truncate at one line so long product names + the action button
     don't push the toast past the viewport. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 0 1 auto;
  min-width: 0;
  max-width: 180px;
}
/* "View my event" — toast's forward-motion CTA. Separator dot before
   the link signals "different region, tappable affordance." Underline
   on press to confirm the tap. */
.toast-action {
  position: relative;
  flex-shrink: 0;
  padding: 4px 6px;
  margin-left: 4px;
  font-size: 13px;
  font-weight: 500;
  color: var(--champagne);
  background: transparent;
  border-radius: 8px;
  cursor: pointer;
  letter-spacing: 0.01em;
}
.toast-action::before {
  content: '·';
  position: absolute;
  left: -6px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--champagne);
  opacity: 0.6;
  font-size: 16px;
}
.toast-action[hidden] { display: none; }
.toast-action:active { color: var(--cream); background: rgba(var(--cream-rgb),0.12); }
.toast-action:focus-visible {
  outline: 2px solid var(--champagne);
  outline-offset: 1px;
}
/* Close button — 32×32 hit area, 14×14 glyph centered. WCAG min target. */
.toast-close {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  margin-left: 2px;
  margin-right: -8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--champagne);
  opacity: 0.7;
  border-radius: 50%;
  cursor: pointer;
  transition: opacity 0.2s var(--ease), background 0.2s var(--ease);
}
.toast-close:hover, .toast-close:focus-visible { opacity: 1; background: rgba(var(--cream-rgb),0.10); }
.toast-close:active { background: rgba(var(--cream-rgb),0.18); }

/* Reduced motion — drop the transform slide, opacity-only fade. */
@media (prefers-reduced-motion: reduce) {
  .toast {
    transform: translateX(-50%) translateY(0);
    transition: opacity 0.12s ease-out;
  }
  .toast.show { transform: translateX(-50%) translateY(0); }
}

/* ═══════════════════════════════════════ */
/*  SUCCESS MODAL                          */
/* ═══════════════════════════════════════ */
/* Gallery lightbox is PhotoSwipe (CDN) — see mockup.html init. */

.success-modal {
  position: fixed;
  inset: 0;
  background: rgba(35,24,15,0.6);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  display: flex; align-items: center; justify-content: center;
  z-index: 1100;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s var(--ease);
  padding: 20px;
}
.success-modal.show { opacity: 1; pointer-events: auto; }
.success-card {
  background: var(--cream);
  border-radius: 22px;
  padding: 44px 48px 40px;
  max-width: 460px;
  width: 100%;
  text-align: center;
  box-shadow: var(--inset-highlight), var(--shadow-pop);
  transform: scale(0.96);
  transition: transform 0.45s var(--ease);
}
.success-modal.show .success-card { transform: scale(1); }
.success-icon {
  width: 64px; height: 64px;
  border-radius: 50%;
  background: var(--cream-2);
  display: inline-flex; align-items: center; justify-content: center;
  margin-bottom: 24px;
  box-shadow: var(--ring-hair);
}
.success-icon svg { width: 28px; height: 28px; color: var(--accent); }
.success-card h3 {
  font-family: var(--serif);
  font-size: 30px;
  font-weight: 300;
  color: var(--ink);
  margin-bottom: 12px;
  letter-spacing: -0.02em;
}
.success-card p {
  font-size: 14.5px;
  color: var(--muted);
  line-height: 1.65;
  margin-bottom: 24px;
}
.success-contact-line {
  font-size: 13px;
  color: var(--ink);
  padding: 13px 18px;
  background: var(--cream-2);
  border-radius: 12px;
  margin-bottom: 24px;
}
.success-contact-line strong { color: var(--brand); font-weight: 500; font-variant-numeric: tabular-nums; }

/* Skip-link — invisible until a keyboard user tabs to it, then visible
   + focusable above all chrome. Lets sighted keyboard users jump past
   the nav directly to the main content. Per WCAG 2.4.1 (Bypass Blocks). */
.skip-to-main {
  position: absolute;
  top: -100px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--ink);
  color: var(--cream);
  padding: 10px 18px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-decoration: none;
  z-index: 10000;
  transition: top 0.2s var(--ease);
}
.skip-to-main:focus {
  top: 12px;
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

