/* ss-04d: ported from docs/design/venue-page-reference.html (source of truth).
   venue-restyle-02: moved off the old green --disc-* block onto the
   Midnight/Champagne brand tokens (discover-restyle-01) plus the
   genuinely Diary-shared status tokens (--free-ink/--hold-ink/
   --booked-ink -- not a --disc-* duplicate, so Booked's color actually
   propagates to the Diary through this one token, not a copy of it) and
   a few neutrals now shared with discovery too (--page-hair/--page-chip)
   plus one still venue-only (--venue-page-bg, tokens.css --
   tokens-cleanup-03). Reuses the Diary-shared shared/calendar.js renderer
   (.cal-grid/.cal-dow/.cal-cell, shared/style.css) but overrides its
   colors below rather than forking a second calendar component --
   shared/style.css/calendar.js stay untouched so the Diary's own
   calendar is unaffected. */

body {
  background: var(--venue-page-bg);
  color: var(--home-ink);
  font-family: var(--font-body);
  /* seal-tune-06: the reference already specs this guard; the live copy
     was missing it -- added to match, same fix as discovery's rail. */
  overflow-x: hidden;
}

.app {
  width: 100%;
  max-width: 480px;
  margin: 0 auto;
  min-height: 100vh;
  /* polish-04: the column is tinted now so the white section cards read as
     discrete cards (was one seamless white sheet). Hero stays full-bleed. */
  background: var(--venue-page-bg);
  /* copyright-01: was 86px, but the sticky bar measures ~96px (plus safe-area
     inset), so the new bottom copyright line sat flush under it. */
  padding-bottom: 116px; /* clears the sticky bar */
}

/* ── gallery ──────────────────────────────── */
/* polish-05: rounded bottom corners only (curves into the tint below); top
   stays square/full-bleed. overflow:hidden clips the photo/track to the
   radius -- back/share buttons (top:14px) and dots (bottom:12px) stay well
   inside the 250px bounds, so nothing gets clipped. */
.gallery {
  position: relative;
  height: 250px;
  background: #d9d4c8;
  border-bottom-left-radius: 20px;
  border-bottom-right-radius: 20px;
  overflow: hidden;
}

#gallery-photos {
  position: absolute;
  inset: 0;
}

.gallery .gallery-track {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  height: 100%;
  /* polish-06: hide scrollbar, swipe still works. */
  scrollbar-width: none;
}

.gallery .gallery-track::-webkit-scrollbar {
  display: none;
}

.gallery .gallery-track img {
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
  object-fit: cover;
  scroll-snap-align: start;
}

.gallery .noimg {
  display: grid;
  place-items: center;
  height: 100%;
  color: #a9a293;
  font-size: 12px;
  gap: 4px;
}

.navbtn {
  position: absolute;
  top: 14px;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  display: grid;
  place-items: center;
  backdrop-filter: blur(6px);
  border: none;
  cursor: pointer;
  z-index: 1;
}

.navbtn.back {
  left: 14px;
}

/* discovery-venue-polish-02: moved from the name card's top-right (polish-01)
   to bottom-right, level with the price line -- .head is position:relative,
   so this still anchors there. Still inherits .navbtn's circle/blur base +
   the ::after 48px hit-area; only the anchor point changed. top:auto clears
   the base .navbtn's top:14px -- without it, top+bottom both being set makes
   top win (CSS over-constrained resolution), stranding the button up top. */
.navbtn.share {
  top: auto;
  bottom: 16px;
  right: 16px;
  background: var(--cta);
}

/* public-fix-02 (V-04): invisible hit-area expansion to clear the 44px touch
   floor without changing the 38px visual -- 38 + 2*5 = 48. .navbtn is already
   position:absolute, so the ::after anchors to it directly. Same technique as
   .pickdate::after (cta-tune-10). */
.navbtn::after {
  content: "";
  position: absolute;
  inset: -5px;
}

.dots {
  position: absolute;
  bottom: 12px;
  left: 0;
  right: 0;
  display: flex;
  gap: 6px;
  justify-content: center;
}

.dots i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.6);
}

.dots i.on {
  background: #fff;
  width: 16px;
  border-radius: 3px;
}

/* ── head ─────────────────────────────────── */
/* polish-04: floating white card (was tucked -18px under the hero with a
   flat bottom). Now a 12px tint gap sits between the full-bleed hero and this
   card. */
.head {
  background: var(--card);
  border-radius: 18px;
  margin: 12px 12px 12px;
  position: relative;
  padding: 18px 18px 14px;
  box-shadow: 0 1px 3px rgba(20, 18, 10, .05), 0 9px 24px rgba(20, 18, 10, .045);
}

.name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 24px;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--home-ink);
}

/* discover-tune-05: the Verified pill on the gallery is gone -- an
   animated seal renders inline right after the venue name instead (see
   home.css for discovery's own 19px copy and the same "why inline-block,
   not flex" note -- a long venue name needs to line-wrap with the seal
   trailing the last word, not get shoved to the row's far edge). */
/* seal-tune-06: .sealwrap is the inline-block/vertical-align element now
   (took over .vseal's margin-left) -- a circular overflow:hidden mask so
   the shine-sweep band (.sealwrap::after) clips to the badge shape. */
.sealwrap {
  position: relative;
  display: inline-block;
  vertical-align: middle;
  margin-left: 7px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  overflow: hidden;
}

.sealwrap .vseal {
  width: 20px;
  height: 20px;
  display: block;
  margin: 0;
  animation: sealIn 0.5s cubic-bezier(0.3, 1.4, 0.4, 1) 0.3s backwards, sealWobble 7s ease-in-out 1.2s infinite;
}

.sealwrap::after {
  content: "";
  position: absolute;
  top: -25%;
  height: 150%;
  left: 0;
  width: 45%;
  background: linear-gradient(105deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 50%, rgba(255, 255, 255, 0) 100%);
  transform: translateX(-160%) skewX(-18deg);
  animation: sealShine 7s ease-in-out 1.2s infinite;
  pointer-events: none;
}

@keyframes sealShine {
  0% { transform: translateX(-160%) skewX(-18deg); }
  9%, 100% { transform: translateX(380%) skewX(-18deg); }
}

@keyframes sealWobble {
  0%, 52% { transform: rotate(0); }
  55% { transform: rotate(-10deg); }
  58% { transform: rotate(8deg); }
  61% { transform: rotate(-4deg); }
  64%, 100% { transform: rotate(0); }
}

@keyframes sealIn {
  0% { transform: scale(0) rotate(-30deg); opacity: 0; }
  70% { transform: scale(1.15) rotate(4deg); }
  100% { transform: scale(1) rotate(0); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .vseal {
    animation: none !important;
  }
  .sealwrap::after {
    display: none !important;
  }
  .sticky.attention .cta-row,
  .sticky.attention .disc-btn.call {
    animation: none !important;
  }
  .sticky.attention .disc-btn::after {
    display: none !important;
  }
}

/* discovery-venue-polish-02: the share button now sits bottom-right of .head
   (was top-right, guarded via .name's padding-right in polish-01). A long
   area/guest-range or a wide price band can run right up to -- and under --
   the button, so both lines that can share its row reserve its column instead
   (button's left edge sits 18px[.head pad] + 38px[width] + 16px[offset] = 54px
   in from .head's edge; 44px here clears it with ~10px breathing room --
   headless-verified with a long address + a 7-figure price range). */
.meta {
  color: var(--home-muted);
  font-size: 14px;
  margin-top: 6px;
  padding-right: 44px;
}

.price {
  font-size: 16px;
  font-weight: 700;
  color: var(--home-ink);
  margin-top: 8px;
  padding-right: 44px;
}

.price small {
  font-weight: 500;
  color: var(--home-muted);
  font-size: 13px;
}

/* ── date section ─────────────────────────── */
/* polish-04: section card. discovery-venue-polish-02: gold left accent bar,
   .sec ONLY (the "When is your function?" calendar card) -- .sec is unique to
   this card (About/Guidelines/Links use .about, availability uses .brk, the
   name card uses .head), so no extra scoping needed. overflow:hidden clips
   the bar to the rounded corners; the Sunday-strip pseudo on #cal-grid sits
   well inside .sec's own 18px left padding (its -3px offset is relative to
   #cal-grid, not .sec), so it stays clear of this clip -- headless-verified. */
.sec {
  background: var(--card);
  padding: 6px 18px 18px;
  border-radius: 18px;
  margin: 0 12px 12px;
  box-shadow: 0 1px 3px rgba(20, 18, 10, .05), 0 9px 24px rgba(20, 18, 10, .045);
  position: relative;
  overflow: hidden;
}

.sec::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 5px;
  background: var(--cta);
}

.sec h3 {
  color: var(--home-ink);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: -0.01em;
  margin: 16px 0 4px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

/* polish-06: icon+text as one flex group so "When is your function?" keeps
   hugging its icon while .sec h3's space-between still pushes .pickdate to
   the far right (was 2 flex children -- text + .pickdate -- now 3 would
   misplace the text in the middle; this wrapper keeps it 2). */
.sec-head {
  display: flex;
  align-items: center;
  gap: 9px;
}

/* polish-06: icon slot shared by every section heading (Availability/About/
   Guidelines/Links/calendar) -- the whole-page indent rule's gutter. */
.sec-ic {
  width: 20px;
  flex: none;
  display: flex;
  justify-content: center;
  align-items: center;
  color: var(--home-ink);
}

/* polish-06: body content indents to align under the heading TEXT (not the
   icon) -- one variable drives every section identically. */
.card-body {
  padding-left: var(--sec-indent);
}

/* cta-tune-10: two properties were leaking in from the .sec h3 parent
   this chip is nested inside (letter-spacing is CSS-inherited by
   default, so the h3's -0.01em/-0.15px computed value passed straight
   through) -- font-family was `inherit` (pulled in Bricolage Grotesque)
   and letter-spacing had no reset at all. Together these were the full
   measured cause of the ~1.65px width mismatch against discovery's
   chip flagged in disc-fix-09; explicit resets match discovery's
   actual rendering exactly. */
.pickdate {
  position: relative;
  display: flex;
  align-items: center;
  gap: 5px;
  color: var(--gold-ink);
  font-weight: 600;
  font-size: 12px;
  background: var(--gold-tint);
  padding: 5px 10px;
  border-radius: 20px;
  border: none;
  font-family: "Inter", system-ui, sans-serif;
  letter-spacing: normal;
  cursor: pointer;
}

/* cta-tune-10: invisible expanded hit area restores the 44px touch
   floor (disc-fix-09 shrank the visual chip to ~27px for cross-page
   parity) without inflating the visible pill: 27 + 2*9 = 45px. */
.pickdate::after {
  content: "";
  position: absolute;
  inset: -9px;
}

.pickdate input[type="date"] {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}

/* cal-legend-move: below the grid now — centred, tighter, under a hairline
   (matches the Diary). */
.legend {
  display: flex;
  justify-content: center;
  gap: 12px;
  margin: 10px 0 2px;
  padding-top: 12px;
  border-top: 1px solid var(--page-hair);
  flex-wrap: wrap;
}

.legend span {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  color: var(--home-muted);
  font-weight: 600;
}

.legend i {
  width: 11px;
  height: 11px;
  border-radius: 3px;
}

.calhead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}

.calhead .mlabel {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 14px;
  color: var(--home-ink);
}

.calhead button {
  position: relative;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  border: 1px solid var(--page-hair);
  background: #fff;
  display: grid;
  place-items: center;
  cursor: pointer;
}

/* public-fix-02 (V-04): invisible hit-area expansion to clear the 44px touch
   floor without changing the 34px visual -- 34 + 2*5 = 44. Same technique as
   .pickdate::after (cta-tune-10); pointer-events stays default so the pseudo
   is part of the button's hit region. Inherits the disabled state's
   pointer-events:none, so a disabled ‹ doesn't capture taps. */
.calhead button::after {
  content: "";
  position: absolute;
  inset: -5px;
}

.calhead button.disabled {
  opacity: 0.32;
  pointer-events: none;
}

/* Overrides for shared/calendar.js's .cal-grid/.cal-dow/.cal-cell (also
   used by the Diary) -- shared/style.css itself is untouched, so this only
   changes the venue page's own look. */
.cal-grid {
  gap: 6px;
}

.cal-dow {
  font-size: 11px;
  color: var(--home-muted);
}

.cal-dow.wknd {
  color: var(--gold-ink);
  font-weight: 800;
}

.cal-cell {
  border-radius: 9px;
  font-size: 13px;
  font-weight: 600;
  border: 1px solid var(--page-hair);
  background: #fff;
  color: var(--home-ink);
}

.cal-cell.free {
  background: var(--free-bg);
  color: var(--free-ink);
  border-color: transparent;
}

.cal-cell.hold {
  background: var(--hold-bg);
  color: var(--hold-ink);
  border-color: transparent;
}

.cal-cell.booked {
  background: var(--booked-bg);
  color: var(--booked-ink);
  border-color: transparent;
}

/* C-07 (part-booked): single-space day_night venues only (v-app.js gates
   the roll-up) — Day = top-left half, Night = bottom-right, existing
   status tokens, number keeps --home-ink (measured ≥13.4:1 on every
   half). MUST stay before .cal-cell.past below: equal specificity, so a
   past part-booked day keeps the flat past-grey. */
.cal-cell.split-booked-free { background: linear-gradient(135deg, var(--booked-bg) 0 50%, var(--free-bg) 50% 100%); border-color: transparent; }
.cal-cell.split-free-booked { background: linear-gradient(135deg, var(--free-bg) 0 50%, var(--booked-bg) 50% 100%); border-color: transparent; }
.cal-cell.split-hold-free { background: linear-gradient(135deg, var(--hold-bg) 0 50%, var(--free-bg) 50% 100%); border-color: transparent; }
.cal-cell.split-free-hold { background: linear-gradient(135deg, var(--free-bg) 0 50%, var(--hold-bg) 50% 100%); border-color: transparent; }
.cal-cell.split-booked-hold { background: linear-gradient(135deg, var(--booked-bg) 0 50%, var(--hold-bg) 50% 100%); border-color: transparent; }
.cal-cell.split-hold-booked { background: linear-gradient(135deg, var(--hold-bg) 0 50%, var(--booked-bg) 50% 100%); border-color: transparent; }

/* placed after the status colors so it wins the tie in specificity --
   a past day always reads as non-interactive grey, never a status color. */
.cal-cell.past {
  background: #f4f2ec;
  color: #cbccc3;
  border-color: transparent;
}

.cal-cell.today {
  /* v-app.js passes highlightToday:false (ss-04e) -- this class is never
     actually applied on the venue page; kept in sync with .sel anyway. */
  outline: 2.5px solid var(--cta);
  outline-offset: 1px;
  border-color: transparent;
}

.cal-cell.sel {
  outline: 2.5px solid var(--cta);
  outline-offset: 1px;
}

.cal-loading {
  grid-column: 1 / -1;
  text-align: center;
  color: var(--home-muted);
  font-size: 13px;
  padding: 20px 0;
}

/* polish-04: light-red SUNDAY BAND behind the grid (public-only, PUBLIC calendar
   only — this file isn't loaded by the Diary). A per-cell nth-child background
   would tie .cal-cell.free/.booked (both 0,2,0) and either lose source order or
   override the status colour on Sundays; .empty cells also hide their own
   background. So the strip is a pseudo on the stable #cal-grid wrapper (survives
   the renderer's innerHTML="" rebuild), with cells lifted above it. Column-1
   width = (100% − 6×6px gaps)/7; +3px each side reaches the middle of the 6px
   gutter, aligning the band under the "S" header. */
:root {
  --sun-strip: rgba(214, 69, 69, .09);
  /* polish-06: 20px icon slot + 9px gap -- the whole-page rule. Section body
     content indents by this so it aligns under the heading TEXT, not the icon
     (icon sits in the gutter to the left). */
  --sec-indent: 29px;
}
#cal-grid {
  position: relative;
}
#cal-grid::before {
  content: "";
  position: absolute;
  z-index: 0;
  left: -3px;
  top: -3px;
  bottom: -6px;
  width: calc((100% - 36px) / 7 + 6px);
  background: var(--sun-strip);
  border-radius: 14px;
}
#cal-grid .cal-cell,
#cal-grid .cal-dow {
  position: relative;
  z-index: 1;
}


/* ── per-hall breakdown (multi-space only) ───── */
/* polish-04: section card. :empty guard — renderBreakdown() sets innerHTML=""
   for single whole-day halls, so an empty .brk must not leave a blank card. */
.brk {
  background: var(--card);
  padding: 4px 18px 20px;
  border-radius: 18px;
  margin: 0 12px 12px;
  box-shadow: 0 1px 3px rgba(20, 18, 10, .05), 0 9px 24px rgba(20, 18, 10, .045);
}
.brk:empty {
  display: none;
}

/* polish-05: header row, replaces the old muted ".on" line. .brk-title mirrors
   .about h3 exactly (font/weight/size) so "Availability" reads identically to
   "About this venue"; .brk-date carries the old muted date string. */
.brk-head {
  display: flex;
  /* polish-06: was baseline -- .brk-title is now itself a flex row (icon+text),
     so align by center instead of relying on a nested flex item's baseline. */
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 8px 0 6px;
}

.brk-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 15px;
  margin: 0;
  color: var(--home-ink);
  display: flex;
  align-items: center;
  gap: 9px;
}

.brk-date {
  color: var(--home-muted);
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
}

.brk .single-line {
  font-size: 14px;
  color: var(--home-ink);
  padding: 6px 0 4px;
}

.hall {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 13px 0;
  border-top: 1px solid var(--page-hair);
}

.hall .hn {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 15px;
  color: var(--home-ink);
}

.hall .hn small {
  display: block;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 12px;
  color: var(--home-muted);
  margin-top: 2px;
}

.chips-row {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* polish-06: colour alone carries the status now -- ".d" dot rules removed
   (chipHtml no longer renders the dot span). */
.disc-chip {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  font-weight: 700;
  padding: 6px 10px;
  border-radius: 9px;
  white-space: nowrap;
}

.disc-chip.avail {
  background: var(--free-bg);
  color: var(--free-ink);
}

.disc-chip.booked {
  background: var(--booked-bg);
  color: var(--booked-ink);
}

.disc-chip.hold {
  background: var(--hold-bg);
  color: var(--hold-ink);
}

/* ── "Also free nearby" ───────────────────── */
/* polish-04: section card. This inner .nearby only exists when there are
   nearby venues (loadNearby sets #nearby-strip innerHTML=""), so no :empty
   guard needed — the empty state renders nothing at all. */
.nearby {
  background: var(--card);
  padding: 4px 18px 20px;
  border-radius: 18px;
  margin: 0 12px 12px;
  box-shadow: 0 1px 3px rgba(20, 18, 10, .05), 0 9px 24px rgba(20, 18, 10, .045);
}

.nearby h3 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 15px;
  margin: 14px 0 12px;
  color: var(--home-ink);
}

.nrow {
  display: flex;
  gap: 12px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  padding-bottom: 2px;
}

.nrow::-webkit-scrollbar {
  display: none;
}

.ncard {
  flex: 0 0 46%;
  cursor: pointer;
  text-decoration: none;
  color: inherit;
}

.nphoto {
  aspect-ratio: 16 / 11;
  background: #d9d4c8;
  background-size: cover;
  background-position: center;
  border-radius: 14px;
  position: relative;
}

.npill {
  position: absolute;
  bottom: 8px;
  left: 8px;
  background: rgba(228, 243, 234, 0.94);
  color: var(--free-ink);
  font-size: 11px;
  font-weight: 700;
  padding: 4px 9px;
  border-radius: 14px;
}

.ncard .nn {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 14px;
  margin-top: 8px;
  line-height: 1.2;
  color: var(--home-ink);
}

/* ── about (+ pre-existing amenities/reel/disclaimer, not in the
   reference but kept per the same "preserve, restyle" call as nearby) ── */
/* polish-04: About / Guidelines / Links are now three sibling .about cards
   (the shell split), each a white section card on the tint. */
.about {
  background: var(--card);
  padding: 4px 18px 22px;
  border-radius: 18px;
  margin: 0 12px 12px;
  box-shadow: 0 1px 3px rgba(20, 18, 10, .05), 0 9px 24px rgba(20, 18, 10, .045);
}

.about h3 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 15px;
  margin: 14px 0 0;
  color: var(--home-ink);
  display: flex;
  align-items: center;
  gap: 9px;
}

.about p {
  font-size: 14px;
  color: #3f443d;
  line-height: 1.55;
  margin-top: 8px;
  /* polish-03: About + Venue guidelines are set via textContent with real
     \n intact — render the saved line breaks (no HTML/escaping concern). */
  white-space: pre-line;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}

.amenity-chip {
  background: var(--page-chip);
  border-radius: 999px;
  padding: 5px 12px;
  font-size: 12.5px;
  color: var(--home-ink);
}

/* Links row: website/social + Google Maps side by side. polish-01: borderless
   gold text-buttons (no box, no fill) — the gold + ↗ arrow carry tappability,
   with an :active opacity dip for touch feedback. */
.v-links {
  display: flex;
  gap: 10px;
  margin-top: 12px;
}

.v-links a {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: var(--gold-ink);
  font-weight: 600;
  text-decoration: none;
  padding: 8px 14px;
  font-size: 13px;
}

.v-links a:active {
  opacity: 0.55;
}

.v-links a[hidden] {
  display: none;
}

/* polish-04: moved out of the About card — now loose centered text on the
   tinted page (no white card, no border-top separator). */
.disclaimer {
  color: var(--home-muted);
  font-size: 11.5px;
  text-align: center;
  margin: 4px 12px 8px;
  padding: 4px 18px;
}
/* copyright-01: quiet copyright line at the very bottom of the venue page
   (above the sticky contact bar — sits in the scroll content). */
.site-foot {
  text-align: center;
  font: 500 11px/1.5 var(--font-body);
  color: var(--home-muted);
  opacity: .8;
  margin: 2px 12px 10px;
}

/* ── sticky contact bar ───────────────────── */
/* polish-05: rounded top corners only; hairline + blur bg follow the radius,
   position/buttons unchanged. */
.sticky {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  max-width: 480px;
  margin: 0 auto;
  /* venue-polish-03: opaque -- was rgba(255,255,255,.96) + blur, which let
     page content (notably the calendar's gold accent bar + coloured cells)
     read through when the bar overlapped it. */
  background: var(--card);
  /* venue-polish-03-fix: .sticky had NO z-index (auto), while .cal-cell/
     .cal-dow carry z-index:1 (for the Sunday-strip layering, meant to be
     local to the calendar card) -- neither .sec nor #cal-grid establishes a
     stacking context (position:relative with no z-index of their own), so
     that z-index:1 escaped the card entirely and was painting ABOVE this bar
     wherever they overlapped, regardless of its background. An opaque
     background alone couldn't fix that -- confirmed via elementFromPoint()
     returning a .cal-cell, not .sticky, at points dead-center of the bar.
     z-index:10 gives a fixed action bar comfortable headroom above any
     in-page z-index:1. */
  z-index: 10;
  border-top: 1px solid var(--page-hair);
  border-top-left-radius: 20px;
  border-top-right-radius: 20px;
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: 11px 16px;
  padding-bottom: calc(11px + env(safe-area-inset-bottom));
}

.cta-status {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--home-muted);
  text-align: center;
}

.cta-status b {
  font-weight: 700;
}

.cta-status.avail b {
  color: var(--free-ink);
}

.cta-status.hold b {
  color: var(--hold-ink);
}

.cta-status.booked b {
  color: var(--booked-ink);
}

/* public-fix-03 (V-01): on a booked date only Call drops -- WhatsApp stays for
   the "ask about other dates" recovery path (was the whole .cta-row hidden). */
.disc-btn.hidden {
  display: none;
}

/* public-fix-03 (V-01): the tappable "Next free: <date>" recovery line under a
   booked status (green = free); the muted fallback when nothing's free in the
   loaded 12-month window. */
.cta-status .next-free {
  display: block;
  margin-top: 3px;
  color: var(--free-ink);
  font-weight: 700;
  cursor: pointer;
}

.cta-status .next-free-none {
  display: block;
  margin-top: 3px;
  color: var(--home-muted);
  font-weight: 600;
}

.cta-row {
  display: flex;
  gap: 10px;
}

.cta-row.hidden {
  display: none;
}

/* polish-02: CTA urgency — 15s sequence (breathe 0-5s → shimmer across both
   buttons 5-10s → halo pulse on Call 10-15s), looping while .attention is set
   (renderCta toggles it on .sticky for non-today picks, with a reflow so the
   loop restarts per pick). Scoped to .attention so the buttons only carry
   position/overflow + the sheen pseudo while active — focus outlines stay
   intact the rest of the time. .sticky/.cta-row set no overflow, so the halo
   ring is never clipped. */
.sticky.attention .cta-row { animation: cta-breathe 15s ease-in-out infinite; }

.sticky.attention .disc-btn { position: relative; overflow: hidden; }
.sticky.attention .disc-btn::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(105deg, transparent 42%, rgba(255,255,255,.55) 50%, transparent 58%);
  transform: translateX(-140%);
  animation: cta-shimmer 15s ease-in-out infinite;
}
/* WhatsApp is white — use a soft gold sheen so the sweep reads on it too */
.sticky.attention .disc-btn.wa::after {
  background: linear-gradient(105deg, transparent 42%, rgba(201,160,74,.28) 50%, transparent 58%);
}
.sticky.attention .disc-btn.call { animation: cta-halo 15s ease-out infinite; }

@keyframes cta-breathe {
  0%{transform:scale(1)} 8%{transform:scale(1.02)} 17%{transform:scale(1)}
  25%{transform:scale(1.02)} 33%{transform:scale(1)} 100%{transform:scale(1)}
}
@keyframes cta-shimmer {
  0%,33%{transform:translateX(-140%)} 58%{transform:translateX(140%)} 100%{transform:translateX(140%)}
}
@keyframes cta-halo {
  0%,66%{ box-shadow: 0 3px 10px rgba(201, 160, 74, 0.35), 0 0 0 0 rgba(201,160,74,.5); }
  82%   { box-shadow: 0 3px 10px rgba(201, 160, 74, 0.35), 0 0 0 14px rgba(201,160,74,0); }
  90%,100%{ box-shadow: 0 3px 10px rgba(201, 160, 74, 0.35), 0 0 0 0 rgba(201,160,74,0); }
}

.disc-btn {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 13px 0;
  border-radius: 13px;
  font-family: inherit;
  font-weight: 700;
  font-size: 15px;
  cursor: pointer;
  border: none;
  text-decoration: none;
}

.disc-btn.call {
  background: var(--cta);
  color: var(--cta-on);
  box-shadow: 0 3px 10px rgba(201, 160, 74, 0.35);
}

.disc-btn.call.holdcta {
  /* on-hold state must keep its original amber look, not inherit the
     new gold text/shadow from .call above (same lesson as
     discover-restyle-01's home.css .holdcta fix). */
  background: var(--hold-ink);
  color: #fff;
  box-shadow: none;
}

/* cta-tune-10: ghost secondary -- white surface, green text/glyph, no
   border; the soft shadow is what keeps it reading as tappable now that
   the tint border is gone (founder-chosen over outline/tint variants,
   2026-07-17). Mirrors discovery's .disc-btn.wa. */
.disc-btn.wa {
  background: #fff;
  color: var(--green);
  border: none;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.1);
}

.disc-btn.wa:active {
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
  transform: translateY(0.5px);
}

.wa-ico {
  width: 17px;
  height: 17px;
}

.loading,
.empty-note,
.error-note {
  padding: 18px;
  color: var(--home-muted);
  font-size: 13px;
}
