/* ============================================================================
   JFM Motion Foundation — Batch 0 (M1–M7, group "Motion")
   Designed 31 May, shipped now. Loads on every page via root layout.
   DOCTRINE: animate ONLY transform + opacity. Max 600ms. Compositor-friendly.
   Havenly tokens only (--jfm-* / --hv-*). No Tailwind. ~3KB.
   ========================================================================== */

/* ── M1 · Motion tokens ──────────────────────────────────────────────────── */
:root {
  --jfm-dur-fast: 150ms;
  --jfm-dur-normal: 280ms;
  --jfm-dur-slow: 600ms;
  --jfm-ease-out: cubic-bezier(.2, 0, 0, 1);
  --jfm-ease-spring: cubic-bezier(.34, 1.56, .64, 1);
}

/* ── M2 · Fade-up on scroll ──────────────────────────────────────────────── */
/* Starts hidden + nudged down; .in-view (added by the IntersectionObserver in
   useMotion) settles it to rest. Transform + opacity only. */
.jfm-fade-up {
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity var(--jfm-dur-normal) var(--jfm-ease-out),
    transform var(--jfm-dur-normal) var(--jfm-ease-out);
  will-change: transform, opacity;
}
.jfm-fade-up.in-view {
  opacity: 1;
  transform: translateY(0);
}

/* ── M3 · Hover-lift ─────────────────────────────────────────────────────── */
.jfm-hover-lift {
  transition:
    transform var(--jfm-dur-fast) var(--jfm-ease-out),
    box-shadow var(--jfm-dur-fast) var(--jfm-ease-out);
  will-change: transform;
}
.jfm-hover-lift:hover {
  transform: translateY(-4px);
  box-shadow: 0 16px 36px -12px rgba(0, 16, 46, .26);
}

/* ── M4 · Count-up ───────────────────────────────────────────────────────── */
/* Value is driven by JS (useMotion count-up runner). CSS only keeps the digits
   from reflowing as they tick. */
.jfm-count {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* ── M5 · Press / tap ────────────────────────────────────────────────────── */
.jfm-press {
  transition: transform var(--jfm-dur-fast) var(--jfm-ease-out);
}
.jfm-press:active {
  transform: scale(.97);
}

/* ── M6 · Keyframe library (consumed by later batches) ───────────────────── */
/* All keyframes animate transform/opacity only. */
@keyframes jfm-shimmer { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
@keyframes jfm-slide-up { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); } }
@keyframes jfm-scale-in { from { opacity: 0; transform: scale(.94); } to { opacity: 1; transform: scale(1); } }
@keyframes jfm-stamp-in {
  0% { opacity: 0; transform: scale(1.4) rotate(-8deg); }
  60% { opacity: 1; transform: scale(.92) rotate(-8deg); }
  100% { opacity: 1; transform: scale(1) rotate(-8deg); }
}
@keyframes jfm-heart-pop {
  0% { transform: scale(1); }
  35% { transform: scale(1.35); }
  60% { transform: scale(.9); }
  100% { transform: scale(1); }
}
@keyframes jfm-ken-burns { from { transform: scale(1) translate(0, 0); } to { transform: scale(1.12) translate(-2%, -2%); } }
@keyframes jfm-pin-drop {
  0% { opacity: 0; transform: translateY(-18px) scale(.8); }
  70% { opacity: 1; transform: translateY(2px) scale(1.04); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

/* Thin opt-in utilities so the keyframes are demonstrable + reusable.
   Each animates transform/opacity, capped at --jfm-dur-slow. */
.jfm-anim-slide-up { animation: jfm-slide-up var(--jfm-dur-normal) var(--jfm-ease-out) both; }
.jfm-anim-scale-in { animation: jfm-scale-in var(--jfm-dur-normal) var(--jfm-ease-spring) both; }
.jfm-anim-stamp-in { animation: jfm-stamp-in var(--jfm-dur-normal) var(--jfm-ease-spring) both; }
.jfm-anim-heart-pop { animation: jfm-heart-pop var(--jfm-dur-normal) var(--jfm-ease-spring); }
.jfm-anim-pin-drop { animation: jfm-pin-drop var(--jfm-dur-slow) var(--jfm-ease-spring) both; }
.jfm-anim-ken-burns { animation: jfm-ken-burns 6s var(--jfm-ease-out) alternate infinite; }
/* Shimmer rides on an ::after sweep so only transform animates. */
.jfm-anim-shimmer { position: relative; overflow: hidden; }
.jfm-anim-shimmer::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 20%, rgba(255, 255, 255, .55) 50%, transparent 80%);
  transform: translateX(-100%);
  animation: jfm-shimmer 1.4s var(--jfm-ease-out) infinite;
}

/* Image inside a .jfm-hover-lift card: gentle ken-burns-style zoom on hover.
   Container must clip overflow (cards already do). Transform only. */
.jfm-zoom {
  transition: transform var(--jfm-dur-slow) var(--jfm-ease-out);
  will-change: transform;
}
.jfm-hover-lift:hover .jfm-zoom { transform: scale(1.06); }

/* ── Discovery (Batch 1: JS1/JS2/JS3) motion helpers ──────────────────────── */
/* Open-now pulse ring on a map pin (the pin's own transform stays free for the
   pin-drop keyframe; the ring animates via ::after). */
@keyframes jfm-pin-pulse {
  0% { transform: scale(1); opacity: .5; }
  70% { transform: scale(2.4); opacity: 0; }
  100% { transform: scale(2.4); opacity: 0; }
}
.jfm-map-pin.is-open::after {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: 999px;
  border: 2px solid var(--hv-core-sage-500, #2e7d4d);
  animation: jfm-pin-pulse 2.2s var(--jfm-ease-out) infinite;
  pointer-events: none;
}
/* DiscoveryCanvas split → map collapses under the grid on narrow screens. */
.jfm-discovery__split { display: grid; grid-template-columns: 1.1fr .9fr; gap: 18px; align-items: start; }
@media (max-width: 760px) { .jfm-discovery__split { grid-template-columns: 1fr; } }

/* ── Bottom Sheet (O4) — slide-up panel + scrim fade ─────────────────────── */
@keyframes jfm-sheet-up { from { transform: translateY(100%); } to { transform: translateY(0); } }
@keyframes jfm-scrim-in { from { opacity: 0; } to { opacity: 1; } }
.jfm-sheet-up { animation: jfm-sheet-up var(--jfm-dur-normal) var(--jfm-ease-out) both; }
.jfm-scrim-in { animation: jfm-scrim-in var(--jfm-dur-normal) var(--jfm-ease-out) both; }

/* ── TopBar v2 nav motion (transform+opacity only; global guard below collapses) ──
   navpill-in: the compact search docking into the desktop nav on scroll (ported
   from the deleted AdaptiveSearch dockSlide). tab-active: the mobile bottom-tab
   active-state icon pop. The map/list bottom-sheet reuses jfm-sheet-up above. */
@keyframes jfm-navpill-in { from { opacity: 0; transform: translateY(-6px) scale(.98); } to { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes jfm-tab-active { from { transform: translateY(1px) scale(.9); } to { transform: translateY(0) scale(1); } }

/* ── Map-style search overlay: dark backdrop fade + bar rise-from-top ── */
@keyframes jfm-overlay-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes jfm-overlay-rise { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } }
.jfm-overlay-fade { animation: jfm-overlay-fade var(--jfm-dur-normal) var(--jfm-ease-out) both; }
.jfm-overlay-rise { animation: jfm-overlay-rise var(--jfm-dur-normal) var(--jfm-ease-out) both; }

/* ── M7 · Reduced-motion guard (MANDATORY, global) ───────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ══ Review System (JT2 v2 .jfm-rr) + Write Review (JT3 .jfm-wr) ══════════
   FTA-correct premium reviews. Responsive bits live here (inline styles can't
   do media queries); the global reduced-motion guard above collapses all motion. */
.jfm-rr { display: flex; flex-direction: column; gap: 18px; }

/* summary + rating breakdown (computed from ALL published reviews) */
.jfm-rr__summary { display: grid; grid-template-columns: minmax(160px, 220px) 1fr; gap: 22px; align-items: center;
  background: #fff; border: 1px solid var(--hv-color-border-default, #e4eaf1); border-radius: 12px; padding: 18px 20px; }
.jfm-rr__score { text-align: center; }
.jfm-rr__score-num { font-size: 42px; font-weight: 500; color: var(--v7-ink, #00102E); line-height: 1; }
.jfm-rr__score-stars { color: var(--v7-rating, #FFB52E); font-size: 15px; letter-spacing: 1px; margin-top: 6px; }
.jfm-rr__score-count { font-size: 12px; color: var(--v7-muted, #52617a); margin-top: 5px; }
.jfm-rr__verified-pct { font-size: 11.5px; color: var(--hv-core-sage-700, #1f6b3f); margin-top: 7px; font-weight: 500; }
.jfm-rr__bars { display: flex; flex-direction: column; gap: 6px; }
.jfm-rr__bar { all: unset; box-sizing: border-box; cursor: pointer; display: grid; grid-template-columns: 34px 1fr 52px; gap: 10px; align-items: center;
  font-size: 12px; color: var(--v7-muted, #52617a); border-radius: 6px; padding: 1px 4px; }
.jfm-rr__bar:hover, .jfm-rr__bar.is-active { background: var(--hv-color-border-subtle, #eef2f7); }
.jfm-rr__bar-track { height: 8px; border-radius: 999px; background: var(--hv-color-border-subtle, #eef2f7); overflow: hidden; }
.jfm-rr__bar-fill { height: 100%; border-radius: 999px; background: var(--v7-rating, #FFB52E); transition: width .5s var(--jfm-ease-out, ease); }

/* toolbar + filter sheet */
.jfm-rr__toolbar { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.jfm-rr__btn { all: unset; box-sizing: border-box; cursor: pointer; font-size: 12.5px; font-weight: 500; padding: 7px 12px; border-radius: 999px;
  border: 1px solid var(--hv-color-border-default, #e4eaf1); background: #fff; color: var(--v7-muted, #52617a); display: inline-flex; align-items: center; gap: 6px; }
.jfm-rr__btn.is-on { border-color: var(--v7-navy, #001F60); background: var(--v7-navy, #001F60); color: #fff; }
.jfm-rr__select { font: inherit; font-size: 12.5px; padding: 7px 10px; border-radius: 8px; border: 1px solid var(--hv-color-border-default, #e4eaf1); background: #fff; color: var(--v7-ink, #00102E); cursor: pointer; }
.jfm-rr__search { font: inherit; font-size: 12.5px; padding: 7px 12px; border-radius: 999px; border: 1px solid var(--hv-color-border-default, #e4eaf1); min-width: 160px; }
.jfm-rr__showing { font-size: 12px; color: var(--v7-muted, #52617a); }
.jfm-rr__sheet { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; background: #fff;
  border: 1px solid var(--hv-color-border-default, #e4eaf1); border-radius: 12px; padding: 12px 14px; }
.jfm-rr__sheet-title { display: none; }

/* trust note */
.jfm-rr__trust { font-size: 12px; color: var(--v7-muted, #52617a); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.jfm-rr__trust svg { color: var(--hv-core-sage-700, #1f6b3f); }

/* review cards */
.jfm-rr__grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; }
.jfm-rr__card { background: #fff; border: 1px solid var(--hv-color-border-default, #e4eaf1); border-radius: 12px; padding: 15px; display: flex; flex-direction: column; gap: 10px; }
.jfm-rr__head { display: flex; align-items: center; gap: 9px; }
.jfm-rr__avatar { width: 32px; height: 32px; border-radius: 50%; background: var(--v7-navy, #001F60); color: #fff; display: grid; place-items: center; font-size: 12px; font-weight: 600; flex: 0 0 auto; }
.jfm-rr__name { font-size: 12.5px; font-weight: 600; color: var(--v7-ink, #00102E); }
.jfm-rr__meta { font-size: 10.5px; color: var(--v7-muted, #52617a); }
.jfm-rr__vbadge { align-self: flex-start; display: inline-flex; align-items: center; gap: 4px; font-size: 10px; font-weight: 600; padding: 2px 7px; border-radius: 999px;
  background: var(--hv-core-sage-100, #e7f4ec); color: var(--hv-core-sage-700, #1f6b3f); border: 1px solid var(--hv-core-sage-300, #bfe3cc); }
.jfm-rr__stars { margin-left: auto; color: var(--v7-rating, #FFB52E); font-size: 13px; }
.jfm-rr__body { font-size: 12.5px; color: var(--v7-muted-sub, #33455e); line-height: 1.45; }
.jfm-rr__photos { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 2px; scroll-snap-type: x mandatory; }
.jfm-rr__photo { flex: 0 0 auto; width: 64px; height: 64px; border-radius: 8px; object-fit: cover; cursor: pointer; scroll-snap-align: start; border: 1px solid var(--hv-color-border-subtle, #eef2f7); }
.jfm-rr__reply { margin-left: 14px; border-left: 2px solid var(--hv-color-border-default, #e4eaf1); padding: 4px 0 4px 12px; }
.jfm-rr__reply-who { font-size: 11px; font-weight: 600; color: var(--v7-ink, #00102E); }
.jfm-rr__reply-body { font-size: 12px; color: var(--v7-muted, #52617a); line-height: 1.45; }
.jfm-rr__helpful { all: unset; box-sizing: border-box; cursor: pointer; align-self: flex-start; font-size: 11.5px; font-weight: 500; color: var(--v7-muted, #52617a);
  display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px; border-radius: 999px; border: 1px solid var(--hv-color-border-default, #e4eaf1); }
.jfm-rr__helpful.is-on { color: var(--hv-core-brand-600, #533afd); border-color: var(--hv-core-brand-600, #533afd); background: color-mix(in srgb, var(--hv-core-brand-600, #533afd) 8%, #fff); }

/* states */
.jfm-rr__state { background: #fff; border: 1px dashed var(--hv-color-border-default, #e4eaf1); border-radius: 12px; padding: 28px 20px; text-align: center; color: var(--v7-muted, #52617a); font-size: 13px; }
.jfm-rr__skel { height: 130px; border-radius: 12px; background: linear-gradient(90deg, #eef2f7 25%, #f6f8fb 37%, #eef2f7 63%); background-size: 400% 100%; animation: jfm-skel 1.4s ease infinite; }
@keyframes jfm-skel { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }

/* sticky mobile write CTA */
.jfm-rr__sticky { display: none; }

/* photo lightbox */
.jfm-rr__lightbox { position: fixed; inset: 0; background: rgba(6,27,49,.86); z-index: 1000; display: grid; place-items: center; padding: 24px; }
.jfm-rr__lightbox-img { max-width: min(92vw, 900px); max-height: 84vh; border-radius: 12px; }
.jfm-rr__lightbox-nav { position: absolute; top: 50%; transform: translateY(-50%); background: rgba(255,255,255,.92); border: 0; width: 40px; height: 40px; border-radius: 50%; cursor: pointer; font-size: 18px; }

/* Write Review (JT3) */
.jfm-wr__backdrop { position: fixed; inset: 0; background: rgba(6,27,49,.5); z-index: 1000; display: grid; place-items: center; padding: 18px; }
.jfm-wr { width: min(520px, 100%); background: #fff; border-radius: 20px; padding: 22px; max-height: 92vh; overflow: auto; display: flex; flex-direction: column; gap: 14px; }
.jfm-wr__stars { display: flex; gap: 4px; }
.jfm-wr__star { all: unset; cursor: pointer; font-size: 30px; line-height: 1; color: var(--hv-color-border-default, #e4eaf1); }
.jfm-wr__star.is-on { color: var(--v7-rating, #FFB52E); }
.jfm-wr__textarea { font: inherit; font-size: 13.5px; width: 100%; box-sizing: border-box; min-height: 110px; padding: 12px; border-radius: 12px; border: 1px solid var(--hv-color-border-default, #e4eaf1); resize: vertical; }
.jfm-wr__photos { display: flex; flex-wrap: wrap; gap: 8px; }
.jfm-wr__thumb { width: 64px; height: 64px; border-radius: 8px; object-fit: cover; border: 1px solid var(--hv-color-border-subtle, #eef2f7); }
.jfm-wr__note { font-size: 11.5px; color: var(--v7-muted, #52617a); }
/* action buttons hug their content + sit bottom-right (don't stretch full width) */
.jfm-wr > button.hv-button, .jfm-wr > a.hv-button { align-self: flex-end; }

@media (max-width: 760px) {
  .jfm-rr__summary { grid-template-columns: 1fr; text-align: center; }
  .jfm-rr__grid { grid-template-columns: 1fr; }
  .jfm-rr__sheet { position: fixed; left: 0; right: 0; bottom: 0; z-index: 1001; border-radius: 18px 18px 0 0; box-shadow: 0 -8px 30px rgba(6,27,49,.18); flex-direction: column; align-items: stretch; }
  .jfm-rr__sheet-title { display: flex; justify-content: space-between; align-items: center; font-weight: 600; color: var(--v7-ink, #00102E); }
  .jfm-rr__sticky { position: sticky; bottom: 12px; z-index: 5; display: flex; justify-content: center; }
  .jfm-rr__cta-inline { display: none; }
}

/* ══ Static Bento gallery (.jfm-bento) — matches reference experience-detail.html
   5-tile grid: 1 big left (2fr, full height) + 2×2 small right. No effects; click
   opens the shared gallery. Radius uses the in-scale lg12 (reference 14px → 12). ══ */
.jfm-bento-stage { width: 100%; }
.jfm-bento { width: 100%; min-width: 0; display: grid; grid-template-columns: 2fr 1fr 1fr; grid-template-rows: 1fr 1fr; gap: 8px; height: 440px; }
.jfm-bento__tile { position: relative; display: block; width: 100%; height: 100%; padding: 0; border: 0; cursor: pointer;
  background-color: var(--hv-paper-tint, #eef2f7); background-size: cover; background-position: center; background-repeat: no-repeat;
  border-radius: var(--hv-radius-lg12, 12px); overflow: hidden; }
.jfm-bento__tile:focus-visible { outline: 3px solid var(--hv-core-brand-600, #533afd); outline-offset: 2px; }
.jfm-bento__tile--main { grid-row: 1 / 3; }
.jfm-bento--single { grid-template-columns: 1fr; grid-template-rows: 1fr; }
.jfm-bento--single .jfm-bento__tile--main { grid-row: auto; }
.jfm-bento__more { position: absolute; bottom: 12px; right: 12px; background: rgba(6,27,49,.72); color: #fff;
  padding: 6px 12px; border-radius: var(--hv-radius-md8, 8px); font-size: 12px; font-weight: 500; backdrop-filter: blur(8px); pointer-events: none; }
.jfm-bento__count { display: none; } /* mobile-only "N photos" hint on the main tile */
.jfm-bento__placeholder { display: grid; place-items: center; gap: 10px; height: 440px; border-radius: var(--hv-radius-lg12, 12px);
  background: var(--hv-paper-tint, #eef2f7); color: var(--v7-muted, #52617a); text-align: center; }
.jfm-bento__brand { width: 46px; height: auto; color: var(--hv-core-brand-600, #533afd); opacity: .5; }
@media (max-width: 760px) {
  .jfm-bento { grid-template-columns: 1fr; grid-template-rows: 280px; height: auto; }
  .jfm-bento__tile:not(.jfm-bento__tile--main) { display: none; }
  .jfm-bento__more { display: none; }
  .jfm-bento__count { display: inline-block; }
  .jfm-bento__placeholder { height: 280px; }
}

/* ══ Booking Surface (JB1 .jfm-booking · JB2 .jfm-slots · JB4 .jfm-grab-deal) ══
   Two-way wired body TABLE ↔ sticky BOX. Pure Havenly; motion = transform/opacity
   only (global reduced-motion guard collapses it). */
/* the box column is 340px = the rail column width — every right-side box on
   a PDP shares ONE width (founder call 22 Jul) */
.jfm-booking { display: grid; grid-template-columns: 1fr 340px; gap: 22px; align-items: start; position: relative; }
.jfm-booking__body { min-width: 0; }
/* sticky box: sticks while scrolling the surface, RELEASES at the surface end
   (bounded by .jfm-booking height) — never trails into similar/footer. */
.jfm-booking__boxwrap { position: sticky; top: 128px; align-self: start; display: grid; gap: 12px; }
.jfm-booking__box { background: #fff; border: 1px solid var(--hv-color-border-default, #e4eaf1); border-radius: 14px; box-shadow: var(--v7-sh-md, 0 8px 24px rgba(6,27,49,.08)); padding: 16px; }
.jfm-booking__box-from { font-size: 12px; color: var(--v7-muted, #52617a); }
.jfm-booking__box-price { font-size: 24px; font-weight: 500; color: var(--v7-ink, #00102E); line-height: 1.1; }
.jfm-booking__sel { display: grid; gap: 8px; margin: 12px 0; }
.jfm-booking__sel-row { display: flex; justify-content: space-between; align-items: center; font-size: 12.5px; }
.jfm-booking__sel-row b { color: var(--v7-ink, #00102E); }
.jfm-booking__stepper { display: inline-flex; align-items: center; gap: 8px; }
.jfm-booking__stepbtn { all: unset; cursor: pointer; width: 26px; height: 26px; border-radius: 50%; border: 1px solid var(--hv-color-border-default, #e4eaf1); display: grid; place-items: center; font-size: 15px; color: var(--v7-ink, #00102E); }
.jfm-booking__stepbtn:disabled { opacity: .4; cursor: not-allowed; }
.jfm-booking__break { border-top: 1px solid var(--hv-color-border-subtle, #eef2f7); margin-top: 12px; padding-top: 12px; display: grid; gap: 6px; font-size: 12.5px; color: var(--v7-muted, #52617a); }
.jfm-booking__break-row { display: flex; justify-content: space-between; }
.jfm-booking__break-row.is-deal { color: var(--hv-core-orange-d3, #d97706); }
.jfm-booking__break-total { display: flex; justify-content: space-between; font-size: 15px; font-weight: 500; color: var(--v7-ink, #00102E); margin-top: 4px; }
.jfm-booking__cta { width: 100%; margin-top: 14px; }
.jfm-booking__urgency { font-size: 11.5px; color: var(--hv-core-orange-d3, #d97706); margin-top: 8px; text-align: center; }

/* date navigator */
.jfm-booking__datenav { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.jfm-booking__navbtn { all: unset; cursor: pointer; width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--hv-color-border-default, #e4eaf1); display: grid; place-items: center; color: var(--v7-ink, #00102E); }
.jfm-booking__daterange { font-size: 13px; font-weight: 500; color: var(--v7-ink, #00102E); }

/* slot table (JB2) — date rows × time columns */
.jfm-slots { display: grid; gap: 8px; }
.jfm-slots__day { border: 1px solid var(--hv-color-border-subtle, #eef2f7); border-radius: 12px; padding: 10px 12px; }
.jfm-slots__day.is-active { border-color: var(--v7-navy, #001F60); box-shadow: 0 0 0 1px var(--v7-navy, #001F60); }
.jfm-slots__day-h { display: flex; justify-content: space-between; align-items: center; font-size: 12.5px; font-weight: 500; color: var(--v7-ink, #00102E); margin-bottom: 8px; cursor: pointer; }
.jfm-slots__row { display: flex; flex-wrap: wrap; gap: 8px; }
.jfm-slot { all: unset; cursor: pointer; box-sizing: border-box; min-width: 92px; border: 1px solid var(--hv-color-border-default, #e4eaf1); border-radius: 10px; padding: 8px 10px; display: flex; flex-direction: column; gap: 3px; position: relative; background: #fff; }
.jfm-slot:hover { border-color: var(--v7-navy, #001F60); }
.jfm-slot.is-selected { border-color: var(--v7-navy, #001F60); box-shadow: 0 0 0 2px var(--v7-navy, #001F60); }
.jfm-slot.is-sold { opacity: .45; cursor: not-allowed; }
.jfm-slot__time { font-size: 12.5px; font-weight: 600; color: var(--v7-ink, #00102E); }
.jfm-slot__price { font-size: 11.5px; color: var(--v7-muted, #52617a); }
.jfm-slot__badge { align-self: flex-start; font-size: 9.5px; font-weight: 600; padding: 1px 6px; border-radius: 999px; text-transform: uppercase; letter-spacing: .03em; }
.jfm-slot__badge--deal { background: var(--hv-core-orange-d1, #ffedd5); color: var(--hv-core-orange-d4, #b45309); }
.jfm-slot__badge--best { background: var(--hv-core-bestblue, #e6efff); color: var(--v7-navy, #001F60); border: 1px solid var(--hv-core-bestblue-border, #b9ccf5); }
/* deal intensity ramp on the slot */
.jfm-slot.is-deal-1 { background: var(--hv-core-orange-d1, #fff7ed); }
.jfm-slot.is-deal-2 { background: var(--hv-core-orange-d2, #ffedd5); }
.jfm-slot.is-deal-3 { background: var(--hv-core-orange-d3, #fed7aa); }
.jfm-slot.is-deal-4 { background: var(--hv-core-orange-d4, #fdba74); }
.jfm-slot.is-deal-5 { background: var(--hv-core-orange-d5, #fb923c); }
.jfm-slot__spots { font-size: 10px; color: var(--hv-core-orange-d3, #d97706); }

/* type selector (library) */
.jfm-booking__types { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }

/* ── B2 canon chrome (.hv-bmx) — the EXPERIENCES booking matrix (locked June
   canon; visual source jfm-experience-skydive-havenly.html, behaviour
   jfm-booking-surface-spec). The grid + cells are the shipped .hv-bmatrix /
   .hv-bcell system — everything here is the chrome AROUND them, scoped under
   .hv-bmx so live PDP consumers of .hv-bmatrix are untouched. ── */
.hv-bmx { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 22px; align-items: start; }
.hv-bmx__body { min-width: 0; }
.hv-bmx-card { background: #fff; border: 1px solid var(--hv-color-border-default, #e4eaf1); border-radius: var(--hv-radius-lg12, 12px); box-shadow: var(--v7-sh-sm, 0 1px 3px rgba(6,27,49,.06)); overflow: hidden; }
.hv-bmx-card__head { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; padding: 18px 22px; border-bottom: 1px solid var(--hv-color-border-subtle, #eef2f7); }
.hv-bmx-card__t { font-size: 16px; font-weight: 500; color: var(--v7-ink, #00102E); letter-spacing: -.01em; }
.hv-bmx-card__sub { font-size: 11.5px; color: var(--v7-muted, #52617a); margin-top: 2px; }
.hv-bmx-nav { display: flex; align-items: center; gap: 8px; }
.hv-bmx-nav__btn { all: unset; cursor: pointer; box-sizing: border-box; width: 32px; height: 32px; border: 1px solid var(--hv-color-border-default, #e4eaf1); border-radius: var(--hv-radius-sm4, 6px); display: grid; place-items: center; font-size: 15px; color: var(--v7-muted-sub, #33455e); }
.hv-bmx-nav__btn:hover { border-color: var(--v7-navy, #001F60); }
.hv-bmx-nav__btn:disabled { opacity: .4; cursor: not-allowed; }
.hv-bmx-nav__btn:focus-visible { outline: 2px solid var(--hv-core-brand-600, #533afd); outline-offset: 1px; }
.hv-bmx-nav__lbl { font-size: 12px; font-weight: 500; color: var(--v7-muted-sub, #33455e); min-width: 96px; text-align: center; font-variant-numeric: tabular-nums; }
/* the card padding owns the horizontal scroll (canon .matrix); grid widened to
   the canon 150px/980px INSIDE .hv-bmx only */
.hv-bmx-card__matrix { padding: 18px 22px 22px; overflow-x: auto; }
.hv-bmx .hv-bmatrix { overflow: visible; }
.hv-bmx .hv-bmatrix__grid { grid-template-columns: 64px repeat(6, minmax(150px, 1fr)); min-width: 980px; }
.hv-bmx-colh { display: block; }
.hv-bmx-colh__d { display: block; font-size: 10px; letter-spacing: .04em; text-transform: uppercase; color: var(--v7-muted, #52617a); }
.hv-bmx-colh__n { display: block; font-size: 15px; font-weight: 500; color: var(--v7-ink, #00102E); }
/* deal urgency line (canon: italic, sits under the Adult price, ≥30% deals only) */
.hv-bmx .hv-bcell__urgency { font-size: 9px; font-style: italic; margin-top: 1px; }
.hv-bmx .hv-bcell--deal .hv-bcell__urgency { color: rgba(255,255,255,.92); }
/* optional −% headline variant (.hv-bmx--pct); June default is rail-only reveal */
.hv-bmx .hv-bcell__pcthead { font-size: 19px; font-weight: 600; color: #fff; line-height: 1; margin: 1px 0 6px; }
.hv-bmx .hv-bcell__tier-price--free { font-size: 10px; font-weight: 300; }
.hv-bmx .hv-bcell--deal .hv-bcell__tier-price--free { color: rgba(255,255,255,.8); }
/* legend */
.hv-bmx-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 18px; padding: 13px 22px; border-top: 1px solid var(--hv-color-border-subtle, #eef2f7); font-size: 11px; color: var(--v7-muted, #52617a); }
.hv-bmx-legend__item { display: inline-flex; align-items: center; gap: 6px; }
.hv-bmx-legend__ramp { display: inline-flex; gap: 2px; margin-left: 4px; }
.hv-bmx-legend__sw { width: 11px; height: 11px; border-radius: 3px; display: inline-block; }
.hv-bmx-legend__sw--best { background: #fff; border: 1px solid var(--hv-core-bestblue-border, #9ec3ee); }
.hv-bmx-legend__sw[data-d="1"] { background: var(--hv-core-orange-d1, #ff9e52); }
.hv-bmx-legend__sw[data-d="2"] { background: var(--hv-core-orange-d2, #ff8a2e); }
.hv-bmx-legend__sw[data-d="3"] { background: var(--hv-core-orange-d3, #f57600); }
.hv-bmx-legend__sw[data-d="4"] { background: var(--hv-core-orange-d4, #e06800); }
.hv-bmx-legend__sw[data-d="5"] { background: var(--hv-core-orange-d5, #c25400); }
/* rail (canon price-card): sticks within the .hv-bmx bounds, releases at the end */
.hv-bmx__railwrap { position: sticky; top: 84px; align-self: start; }
.hv-bmx-rail { background: #fff; border: 1px solid var(--hv-color-border-default, #e4eaf1); border-radius: var(--hv-radius-lg12, 12px); box-shadow: var(--v7-sh-md, 0 8px 24px rgba(6,27,49,.08)); padding: 20px; }
.hv-bmx-rail__from { font-size: 11px; color: var(--v7-muted, #52617a); }
.hv-bmx-rail__row { display: flex; align-items: baseline; gap: 8px; margin-top: 2px; }
.hv-bmx-rail__strike { font-size: 16px; color: var(--v7-muted, #52617a); text-decoration: line-through; }
.hv-bmx-rail__price { font-size: 26px; font-weight: 500; color: var(--v7-ink, #00102E); letter-spacing: -.02em; line-height: 1.1; }
.hv-bmx-rail__unit { font-size: 11px; color: var(--v7-muted, #52617a); margin-top: 2px; }
.hv-bmx-rail__sec { font-size: 10px; font-weight: 400; letter-spacing: .04em; text-transform: uppercase; color: var(--v7-muted, #52617a); margin: 16px 0 6px; }
.hv-bmx-tier { display: flex; align-items: center; justify-content: space-between; padding: 7px 0; font-size: 13px; color: var(--v7-ink, #00102E); }
.hv-bmx-tier + .hv-bmx-tier { border-top: 1px solid var(--hv-color-border-subtle, #eef2f7); }
.hv-bmx-tier__age { font-size: 11px; color: var(--v7-muted, #52617a); }
.hv-bmx-rail__sum { display: flex; align-items: center; justify-content: space-between; gap: 12px; background: var(--hv-paper-tint, #f7f9fc); border-radius: var(--hv-radius-md8, 8px); padding: 12px 14px; margin-top: 16px; }
.hv-bmx-rail__meta { font-size: 11px; color: var(--v7-muted, #52617a); line-height: 1.5; }
.hv-bmx-rail__total { font-size: 19px; font-weight: 500; color: var(--v7-ink, #00102E); font-variant-numeric: tabular-nums; }
.hv-bmx-rail__saved { font-size: 11px; color: var(--hv-core-orange-ink, #c25400); }
.hv-bmx-rail__attr { font-size: 11px; color: var(--v7-muted, #52617a); margin: 10px 0 0; line-height: 1.5; }
/* ONE-BOX Week/Month (bridge pdp-exp-shell-canon-fix-v1): head gains a controls
   cluster (B4 view switch + pager); the stage stacks BOTH views in one grid
   cell — the inactive view is visibility-hidden, so the card's bounding box is
   identical across views by construction (no measuring). */
.hv-bmx-card__controls { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.hv-bmx-card__stage { display: grid; padding: 18px 22px 22px; }
.hv-bmx-card__stage > * { grid-area: 1 / 1; min-width: 0; }
.hv-bmx-card__stage > [data-inactive] { visibility: hidden; pointer-events: none; }
.hv-bmx-card__stage .hv-bmx-card__matrix { padding: 0; }
/* month grid inside the one box: allow tall busy days, keep the evpage look */
.hv-bmx-card__stage .evpage__day { min-height: 84px; }

/* ── PDP v2 shell bits (experience PDP): scroll-spy tabs + AI chip ── */
/* section tabs — LINE tabs like the bento lightbox (founder call 22 Jul):
   plain labels, active = navy + underline bar; the bar sticks 12px BELOW the
   TopBar (never flush against it). */
.pdp-spy { position: sticky; top: 72px; z-index: 30; display: flex; gap: 18px; overflow-x: auto;
  background: color-mix(in srgb, #fff 92%, transparent); backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--hv-color-border-subtle, #eef2f7); padding: 0; margin: 4px 0 18px; }
.pdp-spy__link { flex: 0 0 auto; position: relative; font-size: 13px; font-weight: 300; color: var(--v7-muted, #52617a);
  padding: 11px 2px 13px; text-decoration: none; }
.pdp-spy__link:hover { color: var(--v7-ink, #00102E); }
.pdp-spy__link.is-active { color: var(--v7-navy, #001F60); font-weight: 500; }
.pdp-spy__link.is-active::after { content: ''; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
  background: var(--v7-navy, #001F60); border-radius: var(--hv-radius-full, 999px); }
.pdp-spy__link:focus-visible { outline: 2px solid var(--hv-core-brand-600, #533afd); outline-offset: 1px; }
/* gold appears here and ONLY here on the page — the AI chip */
.pdp-ai-chip { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 500;
  /* #8a5a00 = the v2 prototype's locked AI-chip ink (readable on the gold-50 tint) */
  color: #8a5a00; background: var(--hv-color-ai-surface, #FFF4E0);
  border: 1px solid color-mix(in srgb, var(--hv-color-ai, #FF9F00) 45%, #fff);
  border-radius: var(--hv-radius-full, 999px); padding: 4px 12px; }
.pdp-ai-chip__spark { color: var(--hv-color-ai, #FF9F00); }
.pdp-title-rating { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 13px; color: var(--v7-muted, #52617a); margin-top: 8px; }
.pdp-title-rating__score { font-weight: 500; color: var(--v7-ink, #00102E); }
.pdp-map-addr { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap;
  font-size: 13px; color: var(--v7-muted, #52617a); margin-top: 10px; }
/* Location map — v2 fullscreen affordance (native Fullscreen API; overlay
   fallback where the API is missing). Leaflet controls run to z-1000, so the
   button sits above them. */
.pdp-map { position: relative; }
.pdp-map__fsbtn { all: unset; cursor: pointer; box-sizing: border-box; position: absolute; right: 12px; top: 12px; z-index: 1100;
  display: inline-flex; align-items: center; gap: 6px; background: #fff;
  border: 1px solid var(--hv-color-border-default, #e4eaf1); border-radius: var(--hv-radius-md8, 8px);
  padding: 7px 12px; font-size: 12.5px; font-weight: 500; color: var(--v7-ink, #00102E);
  box-shadow: 0 2px 8px rgba(6, 27, 49, .08); }
.pdp-map__fsbtn:hover { background: var(--hv-paper-tint, #f7f9fc); }
.pdp-map__fsbtn:focus-visible { outline: 2px solid var(--hv-core-brand-600, #533afd); outline-offset: 1px; }
.pdp-map--fs { position: fixed; inset: 0; z-index: 200; height: 100vh; border-radius: 0; border: none; }
.pdp-map-addr__note { color: var(--v7-muted, #52617a); }
/* operator contact card — under the sticky rail (v2 contact block); fields
   render only when the vendor/listing actually has them — never fabricated */
.pdp-opcard { margin-top: 12px; background: #fff; border: 1px solid var(--hv-color-border-default, #e4eaf1);
  border-radius: var(--hv-radius-lg12, 12px); padding: 14px 16px; display: grid; gap: 6px; }
.pdp-opcard__sec { font-size: 10px; font-weight: 500; letter-spacing: .06em; text-transform: uppercase; color: var(--v7-muted, #52617a); }
.pdp-opcard__name { font-size: 14px; font-weight: 500; color: var(--v7-ink, #00102E); }
.pdp-opcard__row { font-size: 12.5px; color: var(--v7-muted-sub, #33455e); }
/* honest-CTA note under inert (pre-Stripe) booking buttons */
.jfm-booking__soon { margin-top: 8px; font-size: 11.5px; text-align: center; color: var(--v7-muted, #52617a); }
/* restaurant slot rows use the SAME .hv-bcell boxes as the experience
   calendar (founder call 22 Jul); the time is the cell's headline */
.jfm-slots__row .hv-bcell { flex: 0 0 auto; min-width: 132px; }
.hv-bcell__timehd { font-size: 15px; font-weight: 500; line-height: 1.2; margin-bottom: 2px; }
/* Mapbox GL canvas fills the pdp-map frame */
.pdp-map__gl { width: 100%; height: 100%; }
/* v2 panes: anchors land below the sticky tabs; consistent section rhythm */
.pdp-pane { scroll-margin-top: 128px; margin-top: var(--hv-space-10, 40px); }

/* ── Week geometry (bridge exp-matrix-geometry-fullwidth-v1, founder-approved
   20 Jul prototype): Mon→Sun calendar week · 40px STICKY time gutter with
   vertical bottom-to-top labels · proportional columns repeat(7, minmax(96px,
   1fr)) — the full week fits the container on desktop (no horizontal scroll);
   below the 96px floor the grid scrolls and the gutter + corner stay pinned. ── */
.hv-bmx-w7 { overflow-x: auto; padding-bottom: 10px; }
.hv-bmx-w7__grid { display: grid; grid-template-columns: 40px repeat(7, minmax(96px, 1fr)); gap: 8px; min-width: min-content; }
.hv-bmx-w7__corner, .hv-bmx-w7__gut { position: sticky; left: 0; z-index: 2; background: #fff; }
.hv-bmx-w7__gut { display: flex; align-items: center; justify-content: center; }
.hv-bmx-w7__gut span { writing-mode: vertical-rl; transform: rotate(180deg); font-size: 11px; font-weight: 500;
  color: var(--v7-muted-sub, #33455e); letter-spacing: .02em; font-variant-numeric: tabular-nums; }
.hv-bmx-w7__day { text-align: center; padding-bottom: var(--hv-space-2, 8px); }
.hv-bmx-w7__dow { display: block; font-size: 10px; letter-spacing: .04em; text-transform: uppercase; color: var(--v7-muted, #52617a); }
.hv-bmx-w7__num { display: inline-block; font-size: 15px; font-weight: 500; color: var(--v7-ink, #00102E); padding: 0 4px 2px; }
/* today marker — rating yellow (#F5B301, the locked stars value), not AI gold */
.hv-bmx-w7__day.is-today .hv-bmx-w7__num { border-bottom: 2px solid #F5B301; }
/* compressed cells for the narrower proportional columns */
.hv-bmx-w7 .hv-bcell { padding: var(--hv-space-2, 8px); }
.hv-bmx-w7 .hv-bcell__roundel { padding: 2px 8px; margin-bottom: var(--hv-space-2, 8px); }

/* head refinements (founder call 20 Jul): title LEFT · pager CENTER · toggle
   RIGHT; the pager label opens a month/year picker on the canonical pop
   surface. Remaining spaces render on every bookable cell (real spots_left). */
.hv-bmx-card__head--3z { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; }
.hv-bmx-nav--center { position: relative; justify-self: center; }
.hv-bmx-card__views { justify-self: end; }
/* FIXED pager: the label has a constant width so the ‹ › buttons never move as
   the period text changes; the date picker is a SEPARATE calendar button. */
.hv-bmx-nav__lbl--fixed { width: 148px; text-align: center; flex: 0 0 auto; }
.hv-bmx-nav__calbtn { margin-left: 4px; color: var(--v7-muted-sub, #33455e); }
.hv-bmx-nav__caret { font-size: 9px; color: var(--v7-muted, #52617a); }
/* no scrim: outside-click close is a document-level pointerdown listener in the
   component — a fixed scrim gets trapped by transformed ancestors (.jfm-fade-up). */
.hv-bmx-mnav { position: absolute; top: calc(100% + 8px); left: 50%; transform: translateX(-50%); z-index: 99;
  background: #fff; border: 1px solid var(--hv-color-border-default, #e4eaf1); border-radius: var(--hv-radius-lg12, 12px);
  box-shadow: var(--v7-sh-md, 0 8px 24px rgba(6,27,49,.14)); padding: 12px 14px; display: grid; gap: 10px; min-width: 264px; }
.hv-bmx-mnav__head { all: unset; cursor: pointer; box-sizing: border-box; display: inline-flex; align-items: center; gap: 6px;
  justify-content: center; font-size: 12.5px; font-weight: 500; color: var(--v7-ink, #00102E);
  padding: 5px 10px; border-radius: var(--hv-radius-md8, 8px); }
.hv-bmx-mnav__head:hover { background: var(--hv-paper-tint, #f7f9fc); }
.hv-bmx-mnav__head:focus-visible { outline: 2px solid var(--hv-core-brand-600, #533afd); outline-offset: 1px; }
.hv-bmx-mnav__grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px; }
.hv-bmx-mnav__grid--years { grid-template-columns: repeat(3, 1fr); }
.hv-bmx-mnav__grid--days { grid-template-columns: repeat(7, 1fr); gap: 3px; }
.hv-bmx-mnav__dow { font-size: 10px; font-weight: 500; color: var(--v7-muted, #52617a); text-align: center; padding-bottom: 2px; }
.hv-bmx-mnav__m { all: unset; cursor: pointer; box-sizing: border-box; text-align: center; font-size: 12px; font-weight: 500;
  color: var(--v7-ink, #00102E); padding: 7px 0; border-radius: var(--hv-radius-md8, 8px); }
.hv-bmx-mnav__m--day { padding: 5px 0; font-variant-numeric: tabular-nums; }
.hv-bmx-mnav__m:hover { background: var(--hv-paper-tint, #f7f9fc); }
.hv-bmx-mnav__m:disabled { color: var(--hv-color-text-quiet, #95a4ba); cursor: not-allowed; background: none; }
.hv-bmx-mnav__m.is-on { background: var(--v7-navy, #001F60); color: #fff; }
/* today in the picker's day grid — the locked rating-yellow marker */
.hv-bmx-mnav__m.is-today { box-shadow: inset 0 -2px 0 #F5B301; }
.hv-bmx-mnav__m:focus-visible { outline: 2px solid var(--hv-core-brand-600, #533afd); outline-offset: 1px; }
.hv-bmx-mnav__foot { display: flex; justify-content: space-between; gap: 8px; border-top: 1px solid var(--hv-color-border-subtle, #eef2f7); padding-top: 10px; }
.hv-bmx-mnav__quick { all: unset; cursor: pointer; box-sizing: border-box; font-size: 12px; font-weight: 500; color: var(--hv-color-interactive, #2779A7);
  padding: 5px 10px; border-radius: var(--hv-radius-md8, 8px); }
.hv-bmx-mnav__quick:hover { background: var(--hv-paper-tint, #f7f9fc); }
.hv-bmx-mnav__quick:disabled { color: var(--hv-color-text-quiet, #95a4ba); cursor: not-allowed; background: none; }
.hv-bmx-mnav__quick:focus-visible { outline: 2px solid var(--hv-core-brand-600, #533afd); outline-offset: 1px; }
/* month-mode day strip — the clicked day's sessions in the SAME cell boxes as
   the weekly grid */
.hv-bmx-daystrip { margin-top: 14px; border: 1px solid var(--hv-color-border-subtle, #eef2f7); border-radius: var(--hv-radius-lg12, 12px); padding: 12px 14px; }
.hv-bmx-daystrip__head { display: flex; justify-content: space-between; align-items: center; font-size: 12.5px; font-weight: 500; color: var(--v7-ink, #00102E); margin-bottom: 10px; }
.hv-bmx-daystrip__count { font-weight: 300; color: var(--v7-muted, #52617a); }
.hv-bmx-daystrip__row { display: flex; flex-wrap: wrap; gap: 8px; }
.hv-bmx-daystrip__row .hv-bcell { flex: 0 0 auto; min-width: 150px; }
/* remaining spaces — honest scarcity from real spots_left */
.hv-bcell__spots { font-size: 9.5px; margin-top: 2px; color: var(--hv-core-orange-ink, #c25400); }
.hv-bcell--deal .hv-bcell__spots { color: rgba(255,255,255,.92); }
/* empty day boxes are inert — no hover affordance (founder call 20 Jul) */
.hv-bcell--empty:hover { border-color: var(--hv-color-border-subtle, #eef2f7); box-shadow: none; transform: none; }
@media (max-width: 760px) {
  .hv-bmx-card__head--3z { grid-template-columns: 1fr; justify-items: start; row-gap: 10px; }
  .hv-bmx-nav--center, .hv-bmx-card__views { justify-self: start; }
}

/* ── PDP placement (same task): `children` sit beside the STICKY rail whose
   bounded release ends at row 1; the Bookings section spans the FULL content
   width in row 2 (grid-column 1/-1) — the box can never overlap the grid. ── */
.pdp-v2grid { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 22px; align-items: start; }
.pdp-v2grid__main { grid-column: 1; grid-row: 1; min-width: 0; }
/* no rail (restaurant/stay — the booking surface carries the right column) */
.pdp-v2grid__main--span { grid-column: 1 / -1; }
.pdp-v2grid__rail { grid-column: 2; grid-row: 1; align-self: stretch; }
/* the rail sticks below the sticky tab bar (72px bar offset + ~44px tabs);
   boxes inside share ONE consistent 12px gap (founder call 22 Jul) */
.pdp-v2grid__sticky { position: sticky; top: 128px; display: grid; gap: 12px; }
.pdp-v2grid__sticky > * { margin-top: 0; margin-bottom: 0; }
.pdp-v2grid__full { grid-column: 1 / -1; grid-row: 2; min-width: 0; }
@media (max-width: 920px) {
  .pdp-v2grid { grid-template-columns: 1fr; }
  .pdp-v2grid__main { grid-column: 1; grid-row: 1; }
  .pdp-v2grid__rail { grid-column: 1; grid-row: 2; }
  .pdp-v2grid__sticky { position: static; }
  .pdp-v2grid__full { grid-column: 1; grid-row: 3; }
}

/* stars — LOCKED 19 Jul: steel base + rating-yellow fill clipped to the average.
   #F5B301 is deliberately NOT the AI gold #FF9F00 (gold = the AI acted). */
.hv-bmx-stars { position: relative; display: inline-block; font-size: 15px; letter-spacing: 1px; line-height: 1; color: #8FA1B8; }
.hv-bmx-stars__fill { position: absolute; inset: 0; overflow: hidden; white-space: nowrap; color: #F5B301; }
@media (max-width: 920px) {
  .hv-bmx { grid-template-columns: 1fr; }
  .hv-bmx__railwrap { position: static; }
}

/* ── JB5 Deal Calendar (.jfm-dealcal) — the deal system in the EVENT-CALENDAR style.
   Grid chrome comes from the B6 .evpage__monthwrap family (one calendar look);
   only the session chips + availability states are new. Deal = orange ramp only,
   Best Price = white + blue (no green on deals — green is Verified). ── */
.jfm-dealcal__head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.jfm-dealcal .evpage__day { min-height: 84px; }
.jfm-dealcal .evpage__num:disabled { cursor: default; }
.jfm-dealcal__day--avail { background: #fff; }
.jfm-dealcal__day--avail:hover { background: var(--hv-paper-tint, #f7f9fc); }
.jfm-dealcal__day--selected { box-shadow: inset 0 0 0 2px var(--v7-navy, #001F60); border-radius: 2px; }

/* session chip in a month cell: time left, deal %/best/price right */
.jfm-dcchip { all: unset; cursor: pointer; box-sizing: border-box; display: flex; align-items: center; justify-content: space-between; gap: 4px;
  width: 100%; max-width: 100%; min-width: 0; padding: 2px 6px; border-radius: var(--hv-radius-sm4, 6px);
  border: 1px solid var(--hv-color-border-default, #e4eaf1); background: #fff; font-size: 10.5px; }
.jfm-dcchip:hover { border-color: var(--v7-navy, #001F60); }
.jfm-dcchip:focus-visible { outline: 2px solid var(--hv-core-brand-600, #533afd); outline-offset: 1px; }
.jfm-dcchip.is-selected { border-color: var(--v7-navy, #001F60); box-shadow: 0 0 0 1.5px var(--v7-navy, #001F60); }
.jfm-dcchip__t { font-weight: 600; color: var(--v7-ink, #00102E); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.jfm-dcchip__v { font-weight: 600; white-space: nowrap; color: var(--v7-muted, #52617a); }
/* deal heat — darker = bigger discount. Dark navy ink on every step (same as the
   shipped .jfm-slot ramp) so 10.5px text stays WCAG AA on the whole ladder. */
.jfm-dcchip[data-d] { border-color: transparent; }
.jfm-dcchip[data-d] .jfm-dcchip__t, .jfm-dcchip[data-d] .jfm-dcchip__v { color: var(--v7-ink, #00102E); }
.jfm-dcchip[data-d="1"] { background: var(--hv-core-orange-d1, #ff9e52); }
.jfm-dcchip[data-d="2"] { background: var(--hv-core-orange-d2, #ff8a2e); }
.jfm-dcchip[data-d="3"] { background: var(--hv-core-orange-d3, #f57600); }
.jfm-dcchip[data-d="4"] { background: var(--hv-core-orange-d4, #e06800); }
.jfm-dcchip[data-d="5"] { background: var(--hv-core-orange-d5, #c25400); }
.jfm-dcchip--best { border-color: var(--hv-core-bestblue-border, #9ec3ee); }
.jfm-dcchip--best .jfm-dcchip__v { color: var(--hv-core-bestblue, #2f6fc4); }
.jfm-dcchip--sold { opacity: .45; cursor: not-allowed; }
.jfm-dcchip--sold .jfm-dcchip__v { text-decoration: line-through; }

/* legend + selected-day session strip */
.jfm-dealcal__legend { display: flex; align-items: center; gap: 8px; margin-top: 10px; font-size: 11.5px; color: var(--v7-muted, #52617a); flex-wrap: wrap; }
.jfm-dealcal__legend-chip { width: auto; flex: 0 0 auto; pointer-events: none; }
.jfm-dealcal__legend-label { margin-left: 6px; }
.jfm-dealcal__legend-dot { width: 14px; height: 14px; border-radius: var(--hv-radius-sm4, 6px); display: inline-block; }
.jfm-dealcal__legend-dot[data-d="1"] { background: var(--hv-core-orange-d1, #ff9e52); }
.jfm-dealcal__legend-dot[data-d="2"] { background: var(--hv-core-orange-d2, #ff8a2e); }
.jfm-dealcal__legend-dot[data-d="3"] { background: var(--hv-core-orange-d3, #f57600); }
.jfm-dealcal__legend-dot[data-d="4"] { background: var(--hv-core-orange-d4, #e06800); }
.jfm-dealcal__legend-dot[data-d="5"] { background: var(--hv-core-orange-d5, #c25400); }
.jfm-dealcal__daybar { margin-top: 14px; }

@media (max-width: 640px) {
  /* month cells get tight on phones — keep chips readable, drop the price value */
  .jfm-dealcal .evpage__day { min-height: 64px; padding: 4px; }
  .jfm-dcchip__v { display: none; }
  .jfm-dcchip { justify-content: center; }
}

/* grab deal (JB4 · Path B) */
.jfm-grab-deal { max-width: 360px; background: #fff; border: 1px solid var(--hv-color-border-default, #e4eaf1); border-radius: 16px; padding: 18px; box-shadow: var(--v7-sh-md, 0 8px 24px rgba(6,27,49,.08)); }
.jfm-grab-deal__disc { font-size: 30px; font-weight: 500; color: var(--hv-core-orange-d4, #b45309); line-height: 1; }
.jfm-grab-deal__title { font-size: 15px; font-weight: 600; color: var(--v7-ink, #00102E); margin: 8px 0 4px; }
.jfm-grab-deal__terms { font-size: 12px; color: var(--v7-muted, #52617a); line-height: 1.5; }
.jfm-grab-deal__meta { display: flex; justify-content: space-between; font-size: 11.5px; color: var(--v7-muted, #52617a); margin: 12px 0; }
.jfm-grab-deal__claimed { height: 6px; border-radius: 999px; background: var(--hv-color-border-subtle, #eef2f7); overflow: hidden; margin-bottom: 12px; }
.jfm-grab-deal__claimed-fill { height: 100%; background: var(--hv-core-orange-d4, #fb923c); border-radius: 999px; }
.jfm-grab-deal__code { font-family: var(--hv-font-mono, ui-monospace, monospace); font-size: 19px; font-weight: 600; letter-spacing: .12em; text-align: center; color: var(--v7-ink, #00102E); background: var(--hv-core-orange-d1, #fff7ed); border: 1px dashed var(--hv-core-orange-d4, #fdba74); border-radius: 10px; padding: 12px; }

@media (max-width: 860px) {
  .jfm-booking { grid-template-columns: 1fr; }
  /* box → bottom bar that opens a sheet */
  .jfm-booking__boxwrap { position: static; }
  .jfm-booking__box--mobilebar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 40; border-radius: 16px 16px 0 0; box-shadow: 0 -8px 30px rgba(6,27,49,.18); display: flex; align-items: center; justify-content: space-between; }
  .jfm-booking__box--sheet { position: fixed; left: 0; right: 0; bottom: 0; z-index: 41; border-radius: 18px 18px 0 0; max-height: 86vh; overflow: auto; }
}

/* ══ Batch 3 Deal&Reward (JD2/3/4) + Batch 5 AI&Micro (JA1-4) ══════════════
   Brand thread: Deal=orange honesty (real data only), Verified=sage, Gold=AI only.
   All motion transform/opacity; the global reduced-motion guard collapses it. */

/* JA1 · AI gold-shimmer summary (.jfm-ai-summary) — gold reserved to AI voice */
.jfm-ai-summary { position: relative; overflow: hidden; border-radius: 14px; padding: 16px 18px;
  background: linear-gradient(135deg, color-mix(in srgb, var(--hv-color-ai, #FF9F00) 10%, #fff), #fff);
  border: 1px solid color-mix(in srgb, var(--hv-color-ai, #FF9F00) 28%, #fff); }
.jfm-ai-summary::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 30%, color-mix(in srgb, var(--hv-color-ai, #FF9F00) 30%, #fff) 50%, transparent 70%);
  transform: translateX(-100%); animation: jfm-shimmer 1.5s var(--jfm-ease-out) 1 both; pointer-events: none; }
.jfm-ai-summary__label { display: inline-flex; align-items: center; gap: 5px; font-size: 10.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .06em; color: var(--hv-color-ai-ink, #b45309); }
.jfm-ai-summary__body { font-size: 13px; line-height: 1.5; color: var(--v7-muted-sub, #33455e); margin-top: 6px; }

/* JA2 · Save-heart pop (.jfm-heart) */
.jfm-heart { all: unset; cursor: pointer; display: inline-grid; place-items: center; width: 34px; height: 34px;
  border-radius: 50%; background: rgba(255,255,255,.9); box-shadow: 0 2px 8px rgba(6,27,49,.14); color: var(--v7-muted, #52617a); }
.jfm-heart.is-saved { color: var(--hv-heart-pressed, #FF0000); }
.jfm-heart.is-saved svg { fill: currentColor; }
.jfm-heart.is-saved.is-animating { animation: jfm-heart-pop var(--jfm-dur-normal) var(--jfm-ease-spring); }

/* JA3 · Verified mark (.jfm-verified-stamp) — JUST the sage scalloped icon (no chip, no
   text). Scales in (M6) on first viewport entry; reduced-motion guard collapses it. */
.jfm-verified-stamp { display: inline-flex; vertical-align: middle; line-height: 0; }
.jfm-verified-stamp.is-in { animation: jfm-scale-in var(--jfm-dur-normal) var(--jfm-ease-spring) both; }

/* JA5 · Scalloped verified/claimed badge (.jfm-scallop) — scalloped disc + white
   tick + masked shimmer sweep. SAGE=verified, GOLD=claimed (gold = premium/AI only).
   Colour drives the disc via currentColor; the shine rides the EXISTING jfm-shimmer
   keyframe behind a CSS mask shaped to the scallop silhouette (no library, no Tailwind).
   Sits inline to the RIGHT of a listing name (vertical-align: middle) and scales to a
   showcase size via --jfm-scallop-size. Reduced-motion → shine hidden, static badge. */
.jfm-scallop {
  --jfm-scallop-size: 18px;
  --jfm-scallop-mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2022%2022'%3E%3Cpath%20d='M20.396%2011c-.018-.646-.215-1.275-.57-1.816-.354-.54-.852-.972-1.438-1.246.223-.607.27-1.264.14-1.897-.131-.634-.437-1.218-.882-1.687-.47-.445-1.053-.75-1.687-.882-.633-.13-1.29-.083-1.897.14-.273-.587-.704-1.086-1.245-1.44S11.647%201.62%2011%201.604c-.646.017-1.273.213-1.813.568s-.969.854-1.24%201.44c-.608-.223-1.267-.272-1.902-.14-.635.13-1.22.436-1.69.882-.445.47-.749%201.055-.878%201.688-.13.633-.08%201.29.144%201.896-.587.274-1.087.705-1.443%201.245-.356.54-.555%201.17-.574%201.817.02.647.218%201.276.574%201.817.356.54.856.972%201.443%201.245-.224.606-.274%201.263-.144%201.896.13.634.433%201.218.877%201.688.47.443%201.054.747%201.687.878.633.132%201.29.084%201.897-.136.274.586.705%201.084%201.246%201.439.54.354%201.17.551%201.816.569.647-.016%201.276-.213%201.817-.567s.972-.854%201.245-1.44c.604.239%201.266.296%201.903.164.636-.132%201.22-.447%201.68-.907.46-.46.776-1.044.908-1.681s.075-1.299-.165-1.903c.586-.274%201.084-.705%201.439-1.246.354-.54.551-1.17.569-1.816z'%20fill='%23000'/%3E%3C/svg%3E");
  position: relative;
  display: inline-flex;
  vertical-align: middle;
  flex: 0 0 auto;
  width: var(--jfm-scallop-size);
  height: var(--jfm-scallop-size);
  line-height: 0;
}
.jfm-scallop--verified { color: var(--hv-core-steel-500, #2779A7); }
.jfm-scallop--claimed  { color: var(--hv-core-gold-500, #FF9F00); }
.jfm-scallop > svg { width: 100%; height: 100%; display: block; }
.jfm-scallop__check { stroke: #fff; }
/* shine: a static masked layer (clipped to the scallop) holding a moving gradient.
   The MASK stays put; only the inner sweep translates → the shine never leaks past
   the scalloped edge. */
.jfm-scallop__shine {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  -webkit-mask: var(--jfm-scallop-mask) center / contain no-repeat;
          mask: var(--jfm-scallop-mask) center / contain no-repeat;
}
.jfm-scallop__shine::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, .9) 50%, transparent 70%);
  transform: translateX(-100%);
  animation: jfm-shimmer 2.8s var(--jfm-ease-out) infinite;
}
@media (prefers-reduced-motion: reduce) {
  .jfm-scallop__shine { display: none; }
}

/* JA4 · City ken-burns hero (.jfm-kenburns) */
.jfm-kenburns { position: relative; overflow: hidden; border-radius: 16px; }
.jfm-kenburns__img { width: 100%; height: 100%; object-fit: cover; display: block; animation: jfm-ken-burns 12s var(--jfm-ease-out) alternate infinite; }
.jfm-kenburns__overlay { position: absolute; inset: 0; background: linear-gradient(0deg, rgba(6,27,49,.6), transparent 55%); display: flex; align-items: flex-end; padding: 16px; }
.jfm-kenburns__name { color: #fff; font-size: 22px; font-weight: 500; line-height: 1.1; }
.jfm-kenburns__sub { color: rgba(255,255,255,.85); font-size: 12px; }

/* JD2 · QR check-in ticket (.jfm-qr-ticket) */
.jfm-qr-ticket { display: grid; grid-template-columns: 1fr auto; gap: 0; max-width: 420px; background: #fff;
  border: 1px solid var(--hv-color-border-default, #e4eaf1); border-radius: 16px; overflow: hidden; box-shadow: var(--v7-sh-md, 0 8px 24px rgba(6,27,49,.08)); }
.jfm-qr-ticket__main { padding: 16px 18px; }
.jfm-qr-ticket__kind { font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; color: var(--hv-core-brand-600, #533afd); }
.jfm-qr-ticket__title { font-size: 15px; font-weight: 600; color: var(--v7-ink, #00102E); margin: 4px 0; }
.jfm-qr-ticket__meta { font-size: 12px; color: var(--v7-muted, #52617a); }
.jfm-qr-ticket__code { font-family: var(--hv-font-mono, ui-monospace, monospace); font-size: 13px; letter-spacing: .08em; color: var(--v7-ink, #00102E); margin-top: 8px; }
.jfm-qr-ticket__stub { border-left: 2px dashed var(--hv-color-border-default, #e4eaf1); padding: 16px; display: grid; place-items: center; gap: 6px; background: var(--hv-paper-tint, #f7f9fc); }
.jfm-qr-ticket__qr { width: 104px; height: 104px; }
.jfm-qr-ticket__qr svg { width: 100%; height: 100%; }
.jfm-qr-ticket__scan { font-size: 9.5px; color: var(--v7-muted, #52617a); text-align: center; }

/* JD3 · Deal urgency meter (.jfm-urgency) — real data only, orange ramp */
.jfm-urgency { display: flex; flex-direction: column; gap: 6px; }
.jfm-urgency__row { display: flex; justify-content: space-between; align-items: baseline; font-size: 11.5px; color: var(--hv-core-orange-d3, #d97706); font-weight: 500; }
.jfm-urgency__track { height: 7px; border-radius: 999px; background: var(--hv-color-border-subtle, #eef2f7); overflow: hidden; }
.jfm-urgency__fill { height: 100%; border-radius: 999px; background: var(--hv-core-orange-d4, #fb923c); transition: width .6s var(--jfm-ease-out); }
.jfm-urgency__fill.is-hot { background: var(--hv-core-orange-d5, #f97316); }
.jfm-urgency__time { font-variant-numeric: tabular-nums; }

/* JD4 · Rewards tier ladder (.jfm-tier-ladder) */
.jfm-tier-ladder { display: flex; flex-direction: column; gap: 14px; }
.jfm-tier-ladder__head { display: flex; justify-content: space-between; align-items: baseline; }
.jfm-tier-ladder__tier { font-size: 16px; font-weight: 600; color: var(--v7-ink, #00102E); }
.jfm-tier-ladder__pts { font-size: 12px; color: var(--v7-muted, #52617a); }
.jfm-tier-ladder__rail { position: relative; display: flex; justify-content: space-between; }
.jfm-tier-ladder__rail::before { content: ""; position: absolute; top: 9px; left: 0; right: 0; height: 3px; background: var(--hv-color-border-subtle, #eef2f7); border-radius: 999px; }
.jfm-tier-ladder__progress { position: absolute; top: 9px; left: 0; height: 3px; background: var(--hv-core-brand-600, #533afd); border-radius: 999px; transition: width .7s var(--jfm-ease-out); }
.jfm-tier-ladder__node { position: relative; display: flex; flex-direction: column; align-items: center; gap: 6px; z-index: 1; }
.jfm-tier-ladder__dot { width: 20px; height: 20px; border-radius: 50%; background: #fff; border: 3px solid var(--hv-color-border-default, #e4eaf1); }
.jfm-tier-ladder__node.is-reached .jfm-tier-ladder__dot { background: var(--hv-core-brand-600, #533afd); border-color: var(--hv-core-brand-600, #533afd); }
.jfm-tier-ladder__node.is-current .jfm-tier-ladder__dot { box-shadow: 0 0 0 4px color-mix(in srgb, var(--hv-core-brand-600, #533afd) 22%, #fff); }
.jfm-tier-ladder__lbl { font-size: 9.5px; color: var(--v7-muted, #52617a); text-align: center; max-width: 56px; }
.jfm-tier-ladder__node.is-reached .jfm-tier-ladder__lbl { color: var(--v7-ink, #00102E); font-weight: 500; }
.jfm-tier-ladder__note { font-size: 11px; color: var(--v7-muted, #52617a); }
@media (max-width: 520px){ .jfm-tier-ladder__lbl { font-size: 8.5px; } .jfm-qr-ticket { grid-template-columns: 1fr; } .jfm-qr-ticket__stub { border-left: 0; border-top: 2px dashed var(--hv-color-border-default, #e4eaf1); } }

/* ══ Events Calendar (.evpage) — THE canonical events-calendar component (B6) ════
   Used by the /events page (B8) and the /library showcase. Havenly tokens only;
   reuses the C5 EventCard in Grid view. Reduced-motion guard collapses the transitions.
   (Supersedes the retired .evcal stub.) */
.evpage { display: flex; flex-direction: column; gap: 14px; width: 100%; }

/* header: mode toggle + period LEFT · prev/next RIGHT */
.evpage__head { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.evpage__headl { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; min-width: 0; }
.evpage__views { display: inline-flex; flex-wrap: wrap; gap: 3px; background: var(--hv-color-border-subtle, #eef2f7); padding: 3px; border-radius: var(--hv-radius-full, 999px); }
.evpage__view { all: unset; cursor: pointer; font-size: 12.5px; font-weight: 500; color: var(--v7-muted, #52617a); padding: 6px 13px; border-radius: var(--hv-radius-full, 999px);
  transition: background var(--jfm-dur-fast, 150ms) var(--jfm-ease-out), color var(--jfm-dur-fast, 150ms) var(--jfm-ease-out); }
.evpage__view:hover { color: var(--v7-ink, #00102E); }
.evpage__view.is-on { background: #fff; color: var(--v7-navy, #001F60); box-shadow: 0 1px 3px rgba(6,27,49,.12); }
.evpage__view:focus-visible { outline: 2px solid var(--hv-core-brand-600, #533afd); outline-offset: 1px; }
.evpage__period { font-size: 17px; font-weight: 500; color: var(--v7-ink, #00102E); }
.evpage__nav { display: inline-flex; gap: 6px; }
.evpage__navbtn { all: unset; cursor: pointer; width: 34px; height: 34px; border-radius: var(--hv-radius-md8, 8px); border: 1px solid var(--hv-color-border-default, #e4eaf1);
  display: grid; place-items: center; font-size: 17px; color: var(--v7-ink, #00102E); background: #fff; }
.evpage__navbtn:hover { border-color: var(--v7-navy, #001F60); }

/* filters */
.evpage__filters { display: flex; flex-direction: column; gap: 9px; }
.evpage__search { font: inherit; font-size: 13px; padding: 9px 13px; border-radius: var(--hv-radius-full, 999px); border: 1px solid var(--hv-color-border-default, #e4eaf1); max-width: 340px; }
.evpage__search:focus-visible { outline: 2px solid var(--hv-core-brand-600, #533afd); outline-offset: 1px; }
.evpage__chiprow { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.evpage__chip { all: unset; cursor: pointer; box-sizing: border-box; height: var(--hv-chip-h, 32px); display: inline-flex; align-items: center; padding: 0 12px; border-radius: var(--hv-radius-full, 999px);
  font-size: 12px; font-weight: 500; text-transform: capitalize; color: var(--v7-muted, #52617a); border: 1px solid var(--hv-color-border-default, #e4eaf1); background: #fff; opacity: .82;
  transition: opacity var(--jfm-dur-fast, 150ms) var(--jfm-ease-out); }
.evpage__chip:hover { opacity: 1; }
.evpage__chip.is-on { opacity: 1; box-shadow: inset 0 0 0 1.5px currentColor; }
.evpage__chip--city { color: var(--v7-navy, #001F60); }
.evpage__chip--city.is-on { background: var(--v7-navy, #001F60); color: #fff; border-color: var(--v7-navy, #001F60); }
.evpage__chip:focus-visible { outline: 2px solid var(--hv-core-brand-600, #533afd); outline-offset: 1px; }

/* shared bits */
.evpage__time { font-size: 12.5px; font-weight: 600; color: var(--v7-navy, #001F60); font-variant-numeric: tabular-nums; }
.evpage__ltitle { font-size: 13.5px; color: var(--v7-ink, #00102E); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.evpage__lcity { font-size: 12px; color: var(--v7-muted, #52617a); }
.evpage__empty { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 40px 20px; text-align: center; color: var(--v7-muted, #52617a); font-size: 13.5px;
  border: 1px dashed var(--hv-color-border-default, #e4eaf1); border-radius: var(--hv-radius-lg12, 12px); }

/* ── MONTH ── */
.evpage__monthwrap { border: 1px solid var(--hv-color-border-default, #e4eaf1); border-radius: var(--hv-radius-lg12, 12px); overflow: hidden; touch-action: pan-y; }
.evpage__dow { display: grid; grid-template-columns: repeat(7, 1fr); background: var(--hv-color-border-subtle, #eef2f7); }
.evpage__dow span { font-size: 11px; font-weight: 600; color: var(--v7-muted, #52617a); text-align: center; padding: 9px 0; }
.evpage__grid-m { display: grid; grid-template-columns: repeat(7, 1fr); }
/* cells are content-sized (grid auto rows) so busy days grow taller, capped by showing
   ≤2 timed events as rows and collapsing 3+ into a stack + "+N more". */
/* min-width:0 defeats the grid min-content floor so cells never exceed their 1fr track —
   without it the last (Sunday) column's card overflows past the grid edge and clips.
   overflow:hidden keeps any card fully inside its cell. */
.evpage__day { box-sizing: border-box; min-width: 0; overflow: hidden; min-height: 104px; border-top: 1px solid var(--hv-color-border-subtle, #eef2f7); border-left: 1px solid var(--hv-color-border-subtle, #eef2f7);
  padding: 6px; display: flex; flex-direction: column; gap: 5px; align-items: stretch; }
.evpage__day:nth-child(7n+1) { border-left: 0; }
.evpage__day--muted { background: #fcfdfe; }
.evpage__day--muted .evpage__num { color: var(--hv-color-text-quiet, #95a4ba); }
.evpage__num { all: unset; cursor: pointer; align-self: flex-start; font-size: 12px; color: var(--v7-muted-sub, #33455e); font-weight: 500; }
.evpage__num:focus-visible { outline: 2px solid var(--hv-core-brand-600, #533afd); outline-offset: 1px; border-radius: 4px; }
.evpage__day--today .evpage__num { background: var(--v7-navy, #001F60); color: #fff; border-radius: 999px; width: 21px; height: 21px; display: grid; place-items: center; }

/* all-day / multi-day pill — drawn above timed events, full width, not counted in the cap */
.evpage__allday { display: block; font-size: 10px; font-weight: 600; padding: 2px 7px; border-radius: var(--hv-radius-sm4, 6px);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* event CARD — left colour bar (category tint) + thumbnail + time + title.
   Shared by Month cells and the Week grid. --evt-tint is set per-event in TSX. */
.evpage__card { display: flex; align-items: stretch; box-sizing: border-box; width: 100%; max-width: 100%; min-width: 0;
  background: #fff; border: 1px solid var(--hv-color-border-subtle, #eef2f7);
  border-radius: 7px; overflow: hidden; text-decoration: none; box-shadow: 0 1px 2px rgba(6,27,49,.06); }
.evpage__card:hover { border-color: var(--evt-tint, var(--v7-navy, #001F60)); }
.evpage__card-bar { flex: 0 0 4px; background: var(--evt-tint, var(--v7-navy, #001F60)); }
.evpage__card-main { min-width: 0; flex: 1; padding: 4px 7px 5px; display: flex; flex-direction: column; gap: 1px; }
/* taller, image-forward thumbnail in month cells; Week overrides --evp-img-h compact. */
.evpage__card-img { width: 100%; height: var(--evp-img-h, 92px); object-fit: cover; border-radius: 4px; margin-bottom: 4px; background: var(--hv-paper-tint, #eef2f7); }
.evpage__card-time { font-size: 10px; font-weight: 600; color: var(--v7-navy, #001F60); }
.evpage__card-title { font-size: 11.5px; color: var(--v7-ink, #00102E); line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* compact event ROW — tint dot + time + title on one line, under the lead card in busy
   cells. Same content box as the card (border-box, full width, min-width:0) so it aligns
   and never overflows the Sunday/last column. */
.evpage__row { display: flex; align-items: center; gap: 6px; box-sizing: border-box; width: 100%; max-width: 100%; min-width: 0;
  padding: 2px 4px; border-radius: 5px; text-decoration: none; }
.evpage__row:hover { background: var(--hv-paper-tint, #f7f9fc); }
.evpage__row:focus-visible { outline: 2px solid var(--hv-core-brand-600, #533afd); outline-offset: 1px; }
.evpage__row-dot { flex: 0 0 7px; width: 7px; height: 7px; border-radius: 50%; background: var(--evt-tint, var(--v7-navy, #001F60)); }
.evpage__row-time { flex: 0 0 auto; font-size: 10.5px; font-weight: 600; color: var(--v7-navy, #001F60); }
.evpage__row-title { min-width: 0; flex: 1; font-size: 11px; color: var(--v7-ink, #00102E); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* "+N more" — full-width chip under the rows → opens the day agenda */
.evpage__more { all: unset; cursor: pointer; box-sizing: border-box; display: block; width: 100%; text-align: left;
  font-size: 11px; font-weight: 600; color: var(--v7-navy, #001F60); padding: 3px 7px; border-radius: 6px;
  border: 1px solid var(--hv-color-border-subtle, #eef2f7); background: var(--hv-paper-tint, #f7f9fc); }
.evpage__more:hover { border-color: var(--v7-navy, #001F60); }
.evpage__more:focus-visible { outline: 2px solid var(--hv-core-brand-600, #533afd); outline-offset: 1px; }

/* ── WEEK ── */
.evpage__weekwrap { border: 1px solid var(--hv-color-border-default, #e4eaf1); border-radius: var(--hv-radius-lg12, 12px); overflow: hidden; touch-action: pan-y; }
.evpage__week-head { display: grid; grid-template-columns: 52px repeat(7, 1fr); border-bottom: 1px solid var(--hv-color-border-subtle, #eef2f7); }
.evpage__week-gut { display: block; }
.evpage__week-dh { display: flex; flex-direction: column; align-items: center; gap: 1px; padding: 8px 0; font-size: 11px; color: var(--v7-muted, #52617a); border-left: 1px solid var(--hv-color-border-subtle, #eef2f7); }
.evpage__week-dh b { font-size: 15px; color: var(--v7-ink, #00102E); font-weight: 500; }
.evpage__week-dh.is-today b { background: var(--v7-navy, #001F60); color: #fff; border-radius: 999px; width: 23px; height: 23px; display: grid; place-items: center; }
.evpage__week-body { display: grid; grid-template-columns: 52px repeat(7, 1fr); max-height: 460px; overflow-y: auto; position: relative; overscroll-behavior: contain; scroll-behavior: smooth; }
.evpage__week-axis { display: flex; flex-direction: column; }
.evpage__week-hour { height: 44px; position: relative; }
.evpage__week-hour span { position: absolute; top: -7px; right: 6px; font-size: 10px; color: var(--hv-color-text-quiet, #95a4ba); }
.evpage__week-col { position: relative; border-left: 1px solid var(--hv-color-border-subtle, #eef2f7); }
.evpage__week-slot { height: 44px; border-top: 1px solid var(--hv-color-border-subtle, #eef2f7); }
/* week event = the SAME .evpage__card; this only positions it on the time axis and uses a
   compact image height so Month and Week share one card design. */
/* week card: tall + image-forward (matches month) when the gap to the next event allows;
   height is set inline per-event so consecutive-hour cards never overlap. The image
   FLEX-FILLS the space left after the time + title, so the title is always visible no
   matter how tall the card is (no clipping). */
.evpage__week-ev { position: absolute; box-sizing: border-box; width: auto; }
.evpage__week-ev .evpage__card-main { height: 100%; box-sizing: border-box; }
.evpage__week-ev .evpage__card-img { flex: 1 1 0; height: auto; min-height: 0; }
.evpage__week-ev .evpage__card-title { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
/* slim variant — packed hours: drop the image, keep bar + time + title on one tidy line */
.evpage__week-ev--slim .evpage__card-img { display: none; }
.evpage__week-ev--slim .evpage__card-title { -webkit-line-clamp: 1; }
.evpage__week-ev--slim .evpage__card-main { justify-content: center; }

/* busy hour stack — same treatment as a month cell (lead card + compact rows + "+N more"),
   floated above the time grid so the cluster reads as one tidy group. */
.evpage__week-grp { position: absolute; left: 0; width: calc(100% - 3px); z-index: 2; box-sizing: border-box;
  display: flex; flex-direction: column; gap: 3px; padding: 3px; background: #fff;
  border: 1px solid var(--hv-color-border-subtle, #eef2f7); border-radius: 8px; box-shadow: 0 3px 10px rgba(6,27,49,.14); }
.evpage__week-grp-lead { --evp-img-h: 74px; }
.evpage__week-grp-lead .evpage__card-title { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }

/* ── DAY / LIST ── */
.evpage__agenda, .evpage__list { display: flex; flex-direction: column; gap: 10px; }
.evpage__list { gap: 16px; }
.evpage__slot { display: grid; grid-template-columns: 64px 1fr; gap: 12px; align-items: start; padding: 12px 14px; border: 1px solid var(--hv-color-border-default, #e4eaf1);
  border-radius: var(--hv-radius-md8, 8px); text-decoration: none; }
.evpage__slot:hover { border-color: var(--v7-navy, #001F60); }
.evpage__slottitle { font-size: 14px; font-weight: 500; color: var(--v7-ink, #00102E); }
.evpage__slotmeta { font-size: 11.5px; color: var(--v7-muted, #52617a); margin-top: 3px; display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.evpage__lgroup { display: flex; flex-direction: column; gap: 6px; }
.evpage__lgh { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; color: var(--v7-muted, #52617a); }
.evpage__lrow { display: grid; grid-template-columns: 64px 1fr auto auto; gap: 10px; align-items: center; padding: 9px 12px; border-radius: var(--hv-radius-md8, 8px);
  border: 1px solid var(--hv-color-border-subtle, #eef2f7); text-decoration: none; }
.evpage__lrow:hover { border-color: var(--v7-navy, #001F60); }

/* ── GRID (category carousels of C5 EventCard) ── */
.evpage__grid { display: flex; flex-direction: column; gap: 22px; }
.evpage__gsection { display: flex; flex-direction: column; gap: 10px; }
.evpage__gh { display: flex; align-items: center; gap: 8px; }
.evpage__gcount { font-size: 12px; color: var(--v7-muted, #52617a); }
.evpage__carousel { display: flex; gap: 14px; overflow-x: auto; padding-bottom: 6px; scroll-snap-type: x mandatory; }
.evpage__gcard { flex: 0 0 auto; scroll-snap-align: start; }

/* ── SUMMARY ── */
.evpage__summary { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.evpage__sblock { display: flex; flex-direction: column; gap: 10px; }
.evpage__sh { font-size: 12.5px; font-weight: 600; color: var(--v7-ink, #00102E); }
.evpage__sgrid { display: flex; flex-wrap: wrap; gap: 8px; }
.evpage__sstat { display: inline-flex; align-items: center; gap: 6px; padding: 6px 9px; border: 1px solid var(--hv-color-border-subtle, #eef2f7); border-radius: var(--hv-radius-md8, 8px); font-size: 12.5px; }
.evpage__sstat b { color: var(--v7-ink, #00102E); }
.evpage__snext { display: grid; grid-template-columns: 60px 1fr auto; gap: 10px; align-items: center; padding: 8px 0; border-top: 1px solid var(--hv-color-border-subtle, #eef2f7); text-decoration: none; }

/* ── day-detail sheet (from Month click) ── */
.evpage__sheet-scrim { position: fixed; inset: 0; z-index: 1000; background: rgba(6,27,49,.5); display: flex; align-items: flex-end; justify-content: center; }
.evpage__sheet { width: min(560px, 100%); max-height: 80vh; overflow: auto; background: #fff; border-radius: 18px 18px 0 0; padding: 18px; display: flex; flex-direction: column; gap: 10px; }
.evpage__sheet-h { display: flex; align-items: center; justify-content: space-between; font-size: 15px; color: var(--v7-ink, #00102E); }
.evpage__sheet-x { all: unset; cursor: pointer; width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; color: var(--v7-muted, #52617a); border: 1px solid var(--hv-color-border-default, #e4eaf1); }
/* desktop: the day agenda is a right-side DRAWER; mobile keeps the bottom-sheet. */
@keyframes jfm-drawer-in { from { transform: translateX(100%); } to { transform: translateX(0); } }
@media (min-width: 640px) {
  .evpage__sheet-scrim { align-items: stretch; justify-content: flex-end; }
  .evpage__sheet { width: min(420px, 100%); max-height: 100%; height: 100%; border-radius: 0; animation: jfm-drawer-in var(--jfm-dur-normal) var(--jfm-ease-out) both; }
}

@media (max-width: 820px) {
  .evpage__summary { grid-template-columns: 1fr; }
  .evpage__week-body, .evpage__week-head { grid-template-columns: 44px repeat(7, 1fr); }
}
@media (max-width: 560px) {
  /* mobile month = compact: cards collapse to thin colour bars (tap the day → bottom-sheet) */
  .evpage__day { min-height: 60px; padding: 4px; gap: 3px; }
  .evpage__card { border-radius: 4px; }
  .evpage__card-img, .evpage__card-title { display: none; }
  .evpage__card-main { padding: 0; }
  .evpage__card-time { font-size: 9px; padding: 2px 4px; }
  /* compact rows collapse to dot + time (title hidden) to fit the narrow cell */
  .evpage__row-title { display: none; }
  .evpage__row { padding: 1px 3px; }
  .evpage__row-time { font-size: 9px; }
  .evpage__more { font-size: 9px; padding: 2px 4px; text-align: center; }
  .evpage__lrow { grid-template-columns: 56px 1fr; }
  .evpage__lrow .hv-evtcat, .evpage__lrow .evpage__lcity { display: none; }
  .evpage__period { font-size: 15px; }
}

.evpage__by { color: var(--v7-muted, #52617a); }
.evpage__by b { font-weight: 600; color: var(--v7-ink, #00102E); }

/* ── MSF (Mobile Search + Filter) motion ── */
/* Staged fullscreen search takeover entrance (transform+opacity only). */
@keyframes jfm-takeover-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
.jfm-takeover-in { animation: jfm-takeover-in var(--jfm-dur-normal) var(--jfm-ease-out) both; }
/* Filter-section collapse/expand (available for any future accordion use in
   the mobile filter sheet; the sheet itself reuses jfm-sheet-up above). */
@keyframes jfm-section-expand { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } }
.jfm-section-expand { animation: jfm-section-expand var(--jfm-dur-fast) var(--jfm-ease-out) both; }

/* matrix-card cells (week grid + month day strip) hover with a CONTAINED
   shadow — the card clips overflow, and the DS pop shadow (32px blur) was
   getting cut at the card edge (founder call 22 Jul) */
.hv-bmx-card .hv-bcell:hover { box-shadow: 0 6px 16px rgba(6, 27, 49, .14); }
.hv-bmx-card .hv-bcell[aria-pressed="true"]:hover {
  box-shadow: inset 0 0 0 1px var(--hv-color-action-primary), 0 6px 16px rgba(6, 27, 49, .14); }
