* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: #f5f5f5;
  color: #333;
  min-height: 100vh;
}

select, input, textarea, button {
  font-family: inherit;
}

/* ---- Site nav ----
   Separate from .header below by design: account-control and page links
   used to live inside .header itself, absolutely positioned over the same
   band as the centered title -- as account-control grew (My Contracts +
   Trip Value + email + Sign out, all at once when signed in) it started
   visually colliding with the title. This bar can grow freely instead. */
.site-nav {
  background: white;
  border-bottom: 1px solid #e0e0e0;
  padding: 10px 24px;
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
  position: sticky;
  top: 0;
  z-index: 100;
}

.site-nav-brand {
  font-weight: 700;
  font-size: 1rem;
  color: var(--color-primary);
  text-decoration: none;
  letter-spacing: 0.2px;
  flex-shrink: 0;
}

.site-nav-links {
  display: flex;
  align-items: center;
  gap: 16px;
  flex: 1;
  flex-wrap: wrap;
}

.site-nav-group {
  display: flex;
  align-items: center;
  gap: 12px;
}

.site-nav-group-label {
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: #aaa;
  font-weight: 700;
}

.site-nav-divider {
  width: 1px;
  height: 16px;
  background: #e0e0e0;
}

.site-nav-links a {
  font-size: 0.82rem;
  color: #555;
  text-decoration: none;
  font-weight: 500;
  padding: 2px 0;
  border-bottom: 2px solid transparent;
}

.site-nav-links a:hover { color: var(--color-primary); }

.site-nav-links a.active {
  color: var(--color-primary);
  border-bottom-color: var(--color-primary);
  font-weight: 600;
}

/* Hamburger toggle -- hidden on desktop (.site-nav-links is always visible
   there); shown and wired up only inside the mobile media query below,
   where it collapses the whole link list instead of letting every group
   wrap onto its own line. */
.site-nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  width: 32px;
  height: 32px;
  padding: 6px;
  margin-left: auto;
  border: none;
  background: none;
  cursor: pointer;
}
.site-nav-toggle span {
  display: block;
  width: 100%;
  height: 2px;
  border-radius: 1px;
  background: var(--color-primary);
}

.account-btn, .account-link-btn {
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  padding: 6px 14px;
  border-radius: 20px;
  border: 1px solid #ddd;
  background: #f7f5fa;
  color: var(--color-primary);
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
  white-space: nowrap;
}

.account-btn:hover, .account-link-btn:hover {
  background: #ece1f7;
  border-color: var(--color-primary);
}

/* ---- Header ---- */
.header {
  background: linear-gradient(135deg, var(--color-secondary), var(--color-primary));
  color: white;
  padding: 16px 24px;
  text-align: center;
}

.header h1 {
  font-size: 1.3rem;
  font-weight: 600;
  margin-bottom: 2px;
}

.header .subtitle {
  font-size: 0.8rem;
  opacity: 0.8;
}

/* ---- Suggest a Stay return banner ----
   Shown only when arriving here via a "View This Stay" tap from
   suggest.html (app.js checks dvc_suggest_return in sessionStorage) --
   that flow has no other way back to the search results it came from,
   since navigating here overwrites the address bar entirely. */
.suggest-return-banner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 8px 24px;
  background: #f7f5fa;
  border-bottom: 1px solid #e0d5f0;
  font-size: 0.82rem;
}
.suggest-return-banner a {
  color: var(--color-primary);
  font-weight: 700;
  text-decoration: none;
}
.suggest-return-banner a:hover { text-decoration: underline; }
.suggest-return-banner button {
  border: none;
  background: none;
  color: #999;
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 2px;
}
.suggest-return-banner button:hover { color: #555; }

/* ---- Controls ---- */
/* justify-content: flex-start + the same max-width/margin as .main-layout
   below it (not center) -- otherwise Resort/Room Type visibly recenter
   and shift sideways the moment #booking-as-control/#itinerary-load-control
   flip from display:none to flex once Supabase auth resolves and there's
   contract/itinerary data to show. */
/* Desktop: a full-width white strip under the header (background and
   border run edge to edge like the header itself) whose CONTENT is padded
   in to the same 1200px column, 16px inner edge, as .main-layout below, so
   the dropdowns line up with the calendar card instead of floating in a
   narrower white box with its own edges. */
.controls {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  padding: 12px max(16px, calc((100% - 1200px) / 2 + 16px));
  background: white;
  border-bottom: 1px solid #e0e0e0;
  align-items: center;
  justify-content: flex-start;
}

/* max-width:100% is load-bearing here, not belt-and-braces: a
   .picker-trigger whose label is one long nowrap string (a full resort
   name in "Booking As") pushes this group's content-based minimum past the
   container's width, and align-items:stretch does NOT clamp a flex item
   back down to its container in that case -- every sibling group then
   stretches to the same overflowed width and the whole control bar (and
   with it the page) scrolls sideways. Capping at 100% is what actually
   forces the label to ellipsize instead. */
.control-group {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  max-width: 100%;
}

/* Toggle button only shown on mobile (see the max-width:800px override) --
   on desktop the 4 dropdowns are always visible, same as before this was
   made collapsible. */
.controls-toggle {
  display: none;
}

.controls-groups {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  width: 100%;
}

/* Hidden by default -- app.js reveals these once there's account data to
   show (a contract to book as, or a saved itinerary to load), so a signed-
   out visitor never sees an empty "Booking As" slot in the control bar. */
#booking-as-control,
#itinerary-load-control {
  display: none;
}

.control-group label {
  font-size: 0.65rem;
  text-transform: uppercase;
  font-weight: 600;
  color: #666;
  letter-spacing: 0.5px;
}

/* ---- Custom Select ---- moved to tokens.css (shared with account.html) */

/* ---- Picker Trigger ----
   Visible button for the Resort/Room Type/Booking As/Load Trip pickers
   below -- same box look as tokens.css's .custom-select-trigger, but a
   standalone button rather than nested in a .custom-select wrapper, since
   these open a bottom sheet or inline accordion instead of an absolutely-
   positioned dropdown. The underlying <select>/searchable-select elements
   stay in the DOM (hidden) as the actual state -- see the HTML comment
   above #resort-select-wrapper. */
.picker-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  min-width: 200px;
  max-width: 360px;
  padding: 6px 10px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: 0.85rem;
  font-family: inherit;
  background: var(--color-bg-card);
  background-size: cover;
  background-position: center;
  color: var(--color-text);
  cursor: pointer;
  text-align: left;
}

.picker-trigger:hover { border-color: #b39ddb; }

/* Resort trigger with art (data/resort_images.js) -- app.js sets
   background-image inline to a translucent tint wash over the resort's
   photo (same treatment/color as .controls-toggle.has-art above it in the
   drawer, so the two read as a matching pair) instead of the plain white
   .picker-trigger background. */
.picker-trigger.has-art {
  border-color: rgba(255, 255, 255, 0.6);
}

/* A photo (however tastefully tinted) is busier than a flat background, so
   dark trigger text can lose contrast against light patches of it -- a
   soft white halo (not a solid color change) keeps the text readable
   without hiding the art underneath. Applies to every art-washed trigger:
   Resort, Booking As, and the "If using your own points" owner-resort
   trigger in the cost tile. */
.picker-trigger.has-art .picker-trigger-value {
  font-weight: 700;
  text-shadow: 0 1px 3px rgba(255, 255, 255, 0.75), 0 0 1px rgba(255, 255, 255, 0.75);
}

/* Booking As trigger with an active contract reuses the exact same
   lavender-wash-over-photo look as the Resort trigger (.has-art, set via
   applyResortArtBackground() in syncBookingAsPickerTrigger()) -- a
   solid-color gradient card was tried first and didn't match once every
   resort had real art (data/resort_images.js, 2026-09-20); the photo is
   what makes the trigger recognizable at a glance now, the same way it
   does for the Resort picker. */
.booking-as-trigger-pill {
  display: inline-block;
  background: var(--color-primary-tint-bg);
  color: var(--color-primary);
  border-radius: 999px;
  padding: 2px 8px;
  font-size: 0.65rem;
  font-weight: 700;
  margin-left: 6px;
  white-space: nowrap;
  flex-shrink: 0;
}

/* flex:1 + min-width:0 is what lets the ellipsis above actually fire --
   a flex item's default min-width:auto refuses to shrink below its own
   min-content, which for nowrap text is the entire string. */
.picker-trigger-value {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- Resort Sheet Hero ----
   Shows the currently-selected resort's art (when it has any -- most don't
   yet, see data/resort_images.js) as a scene-setting banner above the
   search/list. Same [hidden]-safe rule as .picker-trigger-thumb: no
   `display` override here. */
.resort-sheet-hero {
  height: 120px;
  border-radius: 12px;
  background-size: cover;
  background-position: center;
  margin-bottom: 10px;
}

/* ---- Bottom Sheet ----
   Same overlay/backdrop mechanics as tokens.css's .modal-overlay/.modal-box
   (open/close via the .open class, dim backdrop) -- .sheet-overlay/.sheet
   just re-anchor the box to the bottom edge and slide it up instead of
   fading a centered box in, since these hold a scrollable list of cards
   (resort/contract/itinerary picks) that reads better as a native-feeling
   sheet than a small centered dialog. */
.sheet-overlay.open { align-items: flex-end; }

.modal-box.sheet {
  max-width: 100%;
  width: 100%;
  max-height: 85vh;
  border-radius: 16px 16px 0 0;
  margin: 0;
  padding: 8px 16px calc(16px + env(safe-area-inset-bottom));
  animation: sheet-slide-up 0.22s ease-out;
}

/* On desktop a full-bleed sheet turns each card into a 1500px-wide strip;
   keep it phone-sheet sized and centered. */
@media (min-width: 769px) {
  .modal-box.sheet { max-width: 560px; }
}

@keyframes sheet-slide-up {
  from { transform: translateY(100%); }
  to { transform: translateY(0); }
}

.sheet-handle {
  width: 36px;
  height: 4px;
  background: var(--color-border);
  border-radius: var(--radius-pill);
  margin: 4px auto 12px;
}

.sheet-search {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: 0.85rem;
  margin-bottom: 10px;
}

.sheet-list {
  overflow-y: auto;
  max-height: 60vh;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.sheet-empty {
  padding: 20px 4px;
  text-align: center;
  color: var(--color-text-faint);
  font-size: 0.85rem;
}

/* Resort picker rows -- plain cards, not full wallet/itinerary styling
   (17 resorts is too many for a heavy card each); white-space: normal
   (rather than the old input's forced single line) is the actual fix for
   long resort names clipping on narrow screens -- it wraps instead. */
.resort-pick-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 12px 10px;
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-sm);
  background: white;
  background-size: cover;
  background-position: center;
  text-align: left;
  white-space: normal;
  font-size: 0.85rem;
  cursor: pointer;
}

.resort-pick-row:hover,
.resort-pick-row:active { background-color: var(--color-primary-tint-bg); }

.resort-pick-row.selected {
  border-color: var(--color-primary);
  background-color: var(--color-primary-tint-bg);
  font-weight: 600;
}

/* Selected row with art (data/resort_images.js) -- app.js's
   renderResortSheetList() sets background-image inline (same lavender-wash
   helper as the trigger/drawer bar, resortArtWashCSS()) over this row only,
   since this marks WHICH resort is selected rather than which ones happen
   to have art. */
.resort-pick-row.selected.has-art {
  border-color: var(--color-primary);
}

.resort-pick-swatch {
  width: 12px;
  height: 12px;
  border-radius: 3px;
  flex-shrink: 0;
}

/* ---- Wallet mini-card (Booking As sheet) ----
   Trimmed-down cousin of account.html's full .wallet-card (this page
   doesn't load that page's script, so it isn't shared -- same duplication
   call as home.js's own deadline-status copy, see CLAUDE.md). Only what a
   picker needs to identify a contract at a glance: home resort, use year,
   and points available right now (getAvailablePoints() in app.js) -- no
   ledger steppers, deadline pill, or perk dots, those live on My Contracts. */
.wallet-mini-btn {
  display: block;
  width: 100%;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  text-align: left;
}

.wallet-mini-card {
  position: relative;
  height: 110px;
  border-radius: 14px;
  padding: 14px 16px;
  color: white;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  box-shadow: inset 0 0 0 1.5px rgba(212,175,55,0.35), 0 6px 16px rgba(0,0,0,0.2);
  background-size: cover;
  background-position: center;
  overflow: hidden;
}

.wallet-mini-card::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, rgba(255,255,255,0.16), transparent 55%);
  pointer-events: none;
}

.wallet-mini-card.selected {
  box-shadow: inset 0 0 0 2.5px #fff, 0 6px 16px rgba(0,0,0,0.2);
}

.wallet-mini-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 10px;
  position: relative;
}

.wallet-mini-name {
  font-family: "Playfair Display", Georgia, serif;
  font-weight: 700;
  font-size: 1rem;
  line-height: 1.25;
}

.wallet-mini-points-num { font-size: 1.4rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1; }
.wallet-mini-points-label { font-size: 0.55rem; font-weight: 700; letter-spacing: 1px; opacity: 0.8; }

.wallet-mini-bottom {
  display: flex;
  gap: 6px;
  position: relative;
}

.wallet-mini-pill {
  background: rgba(255,255,255,0.16);
  border-radius: 999px;
  padding: 3px 9px;
  font-size: 0.68rem;
  font-weight: 600;
}

/* "Just browsing" option -- a plain neutral card, not a gradient wallet
   face, since there's no contract to represent. */
.wallet-mini-card.browsing {
  background: #f5f5f5 !important;
  color: var(--color-text);
  box-shadow: inset 0 0 0 1.5px var(--color-border-light);
  align-items: center;
  justify-content: center;
  flex-direction: row;
  height: 56px;
  font-weight: 600;
  font-size: 0.85rem;
}

/* A white ring (the gradient cards' .selected treatment) barely shows up
   against this card's own light gray face -- use the brand color instead. */
.wallet-mini-card.browsing.selected {
  box-shadow: inset 0 0 0 2.5px var(--color-primary);
}

/* ---- Itinerary mini-card (Load Trip sheet) ----
   Same name/meta shape as itineraries.html's .itin-card, trimmed to just
   what helps pick the right trip in a sheet -- no Edit/Sync/Delete actions,
   those stay on the itineraries.html list itself. */
.itin-mini-btn {
  display: block;
  width: 100%;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  text-align: left;
}

.itin-mini-card {
  padding: 12px 14px;
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-sm);
  background: white;
}

.itin-mini-name { font-weight: 700; font-size: 0.9rem; color: var(--color-text); }
.itin-mini-meta { font-size: 0.78rem; color: var(--color-text-muted); margin-top: 4px; }

/* ---- Room Type accordion ----
   Inline (not a sheet) -- short flat list, no search needed, meant to stay
   low-friction right where Resort/Booking As live. Toggled via .open (like
   .controls-groups.open elsewhere in this file), not the [hidden]
   attribute -- an author stylesheet's `display` declaration always beats
   the UA stylesheet's `[hidden] { display: none }` regardless of
   specificity, so a plain `.room-type-grid { display: grid }` here would
   silently defeat `hidden` and render the grid open by default. */
.room-type-grid {
  display: none;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin-top: 8px;
}

.room-type-grid.open {
  display: grid;
}

.room-type-chip {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 10px 6px;
  border: 1.5px solid var(--color-border-light);
  border-radius: var(--radius-sm);
  background: white;
  cursor: pointer;
  text-align: center;
}

.room-type-chip:hover { border-color: #b39ddb; }

.room-type-chip.selected {
  border-color: var(--color-primary);
  background: var(--color-primary-tint-bg);
}

.room-type-icon { font-size: 1.3rem; line-height: 1; }
.room-type-name { font-size: 0.76rem; font-weight: 600; color: var(--color-text); overflow-wrap: anywhere; }
.room-type-sleeps { font-size: 0.66rem; color: var(--color-text-muted); }

/* Desktop: a dropdown list under the trigger, not an inline accordion --
   opened inline, 16 tiles pushed the whole control bar around (2026-10-02
   user report). Phones keep the inline 2-up tiles inside the stacked
   controls (max-width: 800px block). */
@media (min-width: 801px) {
  .room-type-control { position: relative; }
  .room-type-grid.open {
    display: block;
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 60;
    margin-top: 4px;
    min-width: 100%;
    width: max-content;
    max-width: 440px;
    max-height: min(420px, 60vh);
    overflow-y: auto;
    padding: 4px;
    background: white;
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-md);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.14);
  }
  .room-type-grid .room-type-chip {
    flex-direction: row;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 7px 10px;
    border: 0;
    border-radius: var(--radius-sm);
    text-align: left;
  }
  .room-type-grid .room-type-chip:hover { background: #f5f0fb; }
  .room-type-grid .room-type-icon { font-size: 1rem; }
  .room-type-grid .room-type-name { flex: 1; font-size: 0.85rem; font-weight: 500; }
  .room-type-grid .room-type-chip.selected .room-type-name { font-weight: 700; }
  .room-type-grid .room-type-sleeps { font-size: 0.75rem; white-space: nowrap; }
}

/* ---- Searchable Select ---- */
.searchable-select {
  position: relative;
  min-width: 360px;
}

.searchable-select input {
  width: 100%;
  padding: 6px 10px;
  border: 1px solid #ccc;
  border-radius: 6px;
  font-size: 0.85rem;
  background: white;
  cursor: pointer;
}

.searchable-select input:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 2px rgba(74, 20, 140, 0.15);
  cursor: text;
}

.searchable-select.open input {
  border-radius: 6px 6px 0 0;
}

.searchable-dropdown {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: white;
  border: 1px solid var(--color-primary);
  border-top: none;
  border-radius: 0 0 6px 6px;
  max-height: 260px;
  overflow-y: auto;
  z-index: 100;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.searchable-dropdown.open {
  display: block;
}

.searchable-option {
  padding: 8px 10px;
  font-size: 0.85rem;
  cursor: pointer;
  border-bottom: 1px solid #f0f0f0;
}

.searchable-option:last-child {
  border-bottom: none;
}

.searchable-option:hover {
  background: #f3e5f5;
}

.searchable-option.active {
  background: #ede7f6;
  font-weight: 600;
}

/* ---- Month Navigation ---- */
.month-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 4px 0 2px;
}

.month-nav button {
  background: var(--color-primary);
  color: white;
  border: none;
  border-radius: 6px;
  padding: 6px 12px;
  font-size: 0.95rem;
  cursor: pointer;
  transition: background 0.15s;
}

.month-nav button:hover {
  background: var(--color-primary-hover);
}

.month-nav .month-label {
  font-size: 1rem;
  font-weight: 600;
  min-width: 140px;
  text-align: center;
}

/* ---- Main Layout: Calendar Left, Summary Right ---- */
.main-layout {
  display: flex;
  gap: 20px;
  max-width: 1200px;
  margin: 16px auto;
  padding: 0 16px;
  align-items: flex-start;
}

.calendar-side {
  flex: 1;
  min-width: 0;
  transition: flex 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

.summary-side {
  width: 300px;
  flex-shrink: 0;
  position: sticky;
  top: 16px;
}

/* ---- Review mode: a complete stay collapses the calendar into a trip
   rail and lets the summary side expand into a wider insights grid. See
   renderLayoutMode() in app.js. ---- */
.calendar-side.collapsed {
  flex: 0 0 270px;
}

.summary-side.expanded {
  width: auto;
  flex: 1;
}

/* Trip rail fades/slides in on every display:none -> "" toggle in
   renderLayoutMode() -- CSS animations restart automatically whenever an
   element re-enters the render tree, so no JS trigger is needed here. */
@keyframes fadeInRail {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}
#trip-rail-view {
  animation: fadeInRail 0.2s ease-out;
}

/* ---- Trip Rail (collapsed calendar in review mode) ---- */
.trip-card {
  background: white;
  border-radius: 10px;
  padding: 16px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.trip-resort-label {
  font-size: 0.65rem;
  text-transform: uppercase;
  font-weight: 700;
  color: #999;
  letter-spacing: 0.5px;
}

.trip-resort-name {
  font-size: 0.9rem;
  font-weight: 700;
  color: #333;
  margin-top: 2px;
}

.trip-room-name {
  font-size: 0.72rem;
  color: #777;
  margin-top: 1px;
}

.trip-dates {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid #eee;
}

.trip-date-label {
  font-size: 0.6rem;
  text-transform: uppercase;
  font-weight: 600;
  color: #888;
}

.trip-date-value {
  font-size: 0.82rem;
  font-weight: 700;
  color: #333;
  margin-top: 1px;
}

.trip-arrow {
  color: #ccc;
  font-size: 1rem;
}

/* A real 7-column grid, like the full calendar -- fixed equal-width
   columns regardless of row fill (a flex-wrap approach lets a partial
   last row's items stretch to fill it), with leading empty cells so each
   column consistently represents the same day of the week. */
.trip-strip-header {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  margin-top: 10px;
}

.trip-strip-dow {
  font-size: 0.55rem;
  font-weight: 700;
  color: #999;
  text-align: center;
  text-transform: uppercase;
}

.trip-strip {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
  margin-top: 4px;
}

.trip-strip-day {
  min-width: 0;
  border: 1px solid transparent;
  border-radius: 4px;
  padding: 5px 2px;
  text-align: center;
}

/* Context days just outside the stay -- dimmed and faintly filled so they read as
   "not part of this stay yet" rather than a real night; clicking one
   extends check-in/check-out to include it (adjustTripEdge() in app.js).
   The dimming is applied to just the number/points text, NOT the chip
   itself -- opacity on the chip would also wash out its .trip-tooltip
   child (opacity applies to the whole rendered subtree, including a
   tooltip that's separately set to opacity:1 when shown), making the
   hover label hard to read. */
.trip-strip-day.context {
  cursor: pointer;
}

.trip-strip-day.context .trip-strip-num,
.trip-strip-day.context .trip-strip-pts {
  opacity: 0.5;
}

.trip-strip-day.context:hover .trip-strip-num,
.trip-strip-day.context:hover .trip-strip-pts {
  opacity: 0.85;
}

/* The first/last real night -- still a normal-looking night, just
   clickable to shrink the stay by removing it. */
.trip-strip-day.editable {
  cursor: pointer;
}

.trip-strip-day.editable:hover {
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2);
}

/* Compact variant of .tooltip-card for the trip-strip chips -- hugs a
   short "Add this night" / "Remove this night" label instead of the
   crowd/event tooltips' fixed 210px width. */
.trip-tooltip {
  width: auto;
  white-space: nowrap;
  padding: 6px 10px;
  font-size: 0.68rem;
  font-weight: 600;
  color: #333;
}

.trip-strip-hint {
  font-size: 0.58rem;
  color: #aaa;
  text-align: center;
  margin-top: 6px;
}

.trip-strip-num {
  font-size: 0.58rem;
  color: #888;
}

.trip-strip-pts {
  font-size: 0.78rem;
  font-weight: 700;
}

.trip-total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid #eee;
}

.trip-total-label {
  font-size: 1.1rem;
  font-weight: 700;
  color: #444;
}

.trip-total-value {
  font-size: 1.3rem;
  font-weight: 700;
  color: #333;
}

.edit-dates-btn {
  display: block;
  width: 100%;
  margin-top: 14px;
  padding: 9px;
  background: white;
  border: 1.5px solid var(--color-primary);
  color: var(--color-primary);
  border-radius: 8px;
  font-size: 0.82rem;
  font-weight: 700;
  text-align: center;
  cursor: pointer;
}

.edit-dates-btn:hover {
  background: var(--color-primary-tint-bg);
}

/* ---- Selection Hint ---- */
.selection-hint {
  text-align: center;
  font-size: 0.8rem;
  color: #666;
  padding: 6px 0;
  font-style: italic;
}

.selection-hint .checkin-date {
  font-weight: 600;
  color: var(--color-secondary);
  font-style: normal;
}

/* ---- Calendar ---- */
/* The month navigator and hint are the calendar card's header, not loose
   elements above it -- so on desktop the card's top edge sits level with
   the first summary card (Resort Alerts / Your Stay) beside it. */
.calendar-card {
  background: white;
  border-radius: 10px;
  padding: 8px 12px 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
}

.day-header {
  text-align: center;
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  color: #888;
  padding: 6px 0;
}

/* A soft all-round border in the season color (set per cell in app.js)
   keeps neighboring days apart without a heavy one-side accent. */
.day-cell {
  border: 1px solid transparent;
  border-radius: 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform 0.1s, box-shadow 0.1s;
  position: relative;
  padding: 8px 2px;
  min-height: 60px;
}

.day-cell:hover:not(.empty) {
  transform: scale(1.05);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  z-index: 1;
}

.day-cell.empty {
  cursor: default;
  background: transparent;
}

/* Holds the hero point cost plus the cash rate right under it (the
   SUN-THU/FRI-SAT sub-label stays dropped -- the column header already
   conveys weekday vs. weekend), centered in the cell. */
.day-body {
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* Date number, crowd badge, and event icon each claim their own corner of
   .day-cell (top-left / top-right / bottom-right) so none of the three can
   ever collide, regardless of which combination is present on a given day. */
.day-cell .day-number {
  position: absolute;
  top: 3px;
  left: 5px;
  font-size: 0.65rem;
  font-weight: 600;
  color: rgba(0, 0, 0, 0.5);
}

.day-cell .day-points {
  font-size: 1.05rem;
  font-weight: 700;
}

.day-cell .day-cash {
  font-size: 0.58rem;
  font-weight: 600;
  color: #999;
  letter-spacing: -0.3px;
  margin-top: 1px;
}

.day-cash.prior-year {
  color: #bbb;
  font-style: italic;
}

.day-cell .day-crowd {
  position: absolute;
  top: 3px;
  right: 3px;
  font-size: 0.5rem;
  font-weight: 700;
  line-height: 1;
  padding: 1px 4px;
  border-radius: 999px;
}

/* The 🎉 marker -- app.js only renders this for genuinely date-specific
   events (a ticketed party, a race morning), not for every day of a
   multi-week festival/seasonal window, so it stays a meaningful flag
   rather than calendar-wide noise. */
.day-cell .day-event {
  position: absolute;
  bottom: 3px;
  right: 3px;
  font-size: 0.65rem;
  line-height: 1;
}

/* ---- Crowd level color scale (Undercover Tourist, 1-10) ---- */
.crowd-pill {
  display: inline-block;
  padding: 1px 6px;
  border-radius: 999px;
  font-weight: 700;
  color: white;
}

.crowd-low { background: var(--color-good); }
.crowd-moderate { background: #f9a825; }
.crowd-busy { background: var(--color-warning); }
.crowd-heavy { background: #d84315; }
.crowd-extreme { background: var(--color-danger); }

/* ---- Hover Tooltip ---- moved to tokens.css (shared with account.html) */

/* "(!)" flag for estimated (not observed) cash rates -- see estimateBadgeHTML()
   in app.js. Reset text-transform/letter-spacing/white-space back to normal on
   the tooltip since those otherwise inherit from whatever all-caps, nowrap
   label it's sitting next to (.cost-tile-label, .trip-resort-name) straight
   into the nested tooltip. */
.estimate-badge {
  display: inline-block;
  margin-left: 4px;
  font-weight: 700;
  color: var(--color-warning);
}

/* "incl. tax" under Disney's cash price: tap/hover for the deals caveat. */
.tax-note {
  text-decoration: underline dotted;
  text-underline-offset: 2px;
}

.estimate-tooltip {
  width: 200px;
  text-align: left;
  text-transform: none;
  white-space: normal;
  letter-spacing: normal;
  font-size: 0.7rem;
  font-weight: 400;
  color: #555;
  line-height: 1.4;
}

.crowd-tooltip-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding-bottom: 6px;
  margin-bottom: 6px;
  border-bottom: 1px solid #eee;
}

.crowd-tooltip-date {
  font-size: 0.78rem;
  font-weight: 700;
  color: #333;
}

.crowd-tooltip-sub {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 0.68rem;
  color: #777;
  margin-bottom: 8px;
  text-transform: none;
}

.crowd-tooltip-season {
  font-weight: 700;
  color: var(--color-good);
  letter-spacing: 0.5px;
}

.crowd-tooltip-parks {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.park-flag {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.68rem;
  color: #333;
}

.park-flag-icon {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  font-size: 0.58rem;
  font-weight: 700;
  color: white;
}

.park-flag.recommended .park-flag-icon { background: var(--color-good); }
.park-flag.busy .park-flag-icon { background: var(--color-warning); }

.park-flag-name {
  flex: 1;
}

.park-flag-tag {
  font-size: 0.58rem;
  font-weight: 600;
  color: #999;
  white-space: nowrap;
}

.crowd-tooltip-empty {
  font-size: 0.65rem;
  color: #999;
  font-style: italic;
}

.crowd-tooltip-footer {
  margin-top: 8px;
  padding-top: 6px;
  border-top: 1px solid #f0f0f0;
  font-size: 0.55rem;
  color: #aaa;
  text-align: right;
}

/* ---- Event Tooltip (calendar cell special-event hover) ---- */
.event-tooltip {
  width: 220px;
}

.event-tooltip-header {
  font-size: 0.72rem;
  font-weight: 700;
  color: #333;
  padding-bottom: 6px;
  margin-bottom: 6px;
  border-bottom: 1px solid #eee;
}

.event-tooltip-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.event-tooltip-item-name {
  font-size: 0.68rem;
  font-weight: 700;
  color: #333;
}

.event-tooltip-item-desc {
  font-size: 0.64rem;
  color: #777;
  margin-top: 2px;
}

.event-tooltip-footer {
  margin-top: 8px;
  padding-top: 6px;
  border-top: 1px solid #f0f0f0;
  font-size: 0.55rem;
  color: #aaa;
  text-align: right;
}

/* ---- Period Tooltip (calendar cell travel-period hover) ---- */
.period-tooltip {
  width: 170px;
}

.period-tooltip-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.period-tooltip-date {
  font-size: 0.72rem;
  font-weight: 700;
  color: #333;
}

.period-tooltip-pill {
  font-size: 0.62rem;
  font-weight: 700;
  color: white;
  padding: 2px 7px;
  border-radius: 999px;
  white-space: nowrap;
}

.period-tooltip-sub {
  margin-top: 5px;
  font-size: 0.65rem;
  color: #888;
}

/* ---- Stay Comparison (distribution widgets) ---- */
.dist-subtitle {
  font-size: 0.68rem;
  color: #888;
  margin-top: -6px;
  margin-bottom: 10px;
}

.compare-range-picker {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-bottom: 10px;
}

.compare-range-label {
  font-size: 0.65rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  color: #999;
  margin-right: 2px;
}

.compare-range-select {
  font-size: 0.72rem;
  border: 1px solid #ddd;
  border-radius: 6px;
  padding: 2px 4px;
  color: #333;
  background: white;
}

.compare-range-sep {
  color: #bbb;
  font-size: 0.72rem;
}

.dist-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 18px;
  margin-bottom: 4px;
}

.dist-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 6px;
}

.dist-title {
  font-size: 0.75rem;
  font-weight: 600;
  color: #555;
}

.dist-current {
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--color-primary);
}

.dist-chart {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 44px;
}

.dist-bar-anchor {
  flex: 1;
  min-width: 0;
  height: 100%;
  display: flex;
  align-items: flex-end;
}

.dist-bar {
  width: 100%;
  background: #ede7f6;
  border-radius: 4px 4px 0 0;
}

.dist-bar.current {
  background: var(--color-primary);
}

.dist-tooltip {
  width: 150px;
  text-align: center;
  font-size: 0.68rem;
  font-weight: 600;
  color: #333;
  line-height: 1.35;
}

.dist-axis {
  display: flex;
  justify-content: space-between;
  font-size: 0.6rem;
  color: #aaa;
  margin-top: 3px;
}

.dist-callout {
  font-size: 0.7rem;
  color: #555;
  margin-top: 6px;
}

.dist-callout strong {
  color: var(--color-primary);
}

/* ---- Better Alternatives ---- */
.alt-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 10px;
}

.alt-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 5px;
  padding: 10px 12px;
  border: 1px solid #eee;
  border-radius: 10px;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
  min-width: 0;
}

.alt-card:hover,
.alt-card:focus {
  background: #f9f5fc;
  border-color: #ce93d8;
  outline: none;
}

.alt-badge {
  color: white;
  font-size: 0.6rem;
  font-weight: 700;
  padding: 4px 7px;
  border-radius: 999px;
  white-space: nowrap;
}

.alt-dates {
  font-size: 0.78rem;
  font-weight: 600;
  color: #333;
}

.alt-note {
  font-size: 0.68rem;
  color: #777;
}

.alt-resort {
  font-size: 0.65rem;
  font-weight: 700;
  color: var(--color-primary);
}

.alt-card-empty {
  cursor: default;
  background: #fafafa;
}

.alt-card-empty:hover {
  background: #fafafa;
  border-color: #eee;
}

.alt-badge.muted {
  background: #ccc;
}

/* ---- Find Alternatives button + modal ---- */
.card-header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
  padding-bottom: 6px;
  border-bottom: 1px solid #eee;
}

/* Beats the later, equal-specificity `.summary-card h3` rule (source order
   would otherwise let that one win and re-add its own border-bottom under
   just the "Stay Insights" text, on top of .card-header-row's own border
   under the whole row -- two gray lines instead of one). */
.summary-card .card-header-row h3 {
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: none;
}

.find-alt-btn {
  width: 100%;
  margin-top: 10px;
  padding: 10px;
  background: white;
  color: var(--color-primary);
  border: 1.5px solid var(--color-primary);
  border-radius: 8px;
  font-size: 0.82rem;
  font-weight: 700;
  cursor: pointer;
}

.card-header-row .find-alt-btn {
  width: auto;
  margin-top: 0;
  padding: 6px 14px;
  flex-shrink: 0;
  white-space: nowrap;
}

.find-alt-btn:hover {
  background: var(--color-primary-tint-bg);
}

/* ---- Modal (.modal-overlay/.modal-box) ---- moved to tokens.css (shared with account.html) */

.alt-cross-toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.75rem;
  color: #555;
  margin: 10px 0;
  cursor: pointer;
}

/* Selected state */
.day-cell.selected {
  outline: 3px solid var(--color-secondary);
  outline-offset: -1px;
  box-shadow: 0 1px 6px rgba(26, 35, 126, 0.25);
}

/* Check-in marker -- the solid vs. dashed outline (plus the "Sun, Sep 20 —
   Thu, Sep 24" line above the grid) already distinguishes check-in from
   check-out without needing a text label in the corner. Defined standalone
   (not just an outline-color override layered on .selected) because the
   check-in day only picks up .selected once a check-out date completes the
   range -- until then this is the only rule marking it, and a color-only
   override with no outline width/style set anywhere else was invisible. */
.day-cell.checkin {
  outline: 3px solid var(--color-good);
  outline-offset: -1px;
  box-shadow: 0 1px 6px rgba(26, 35, 126, 0.25);
}

/* Check-out marker */
.day-cell.checkout {
  outline: 3px dashed var(--color-danger);
  outline-offset: -1px;
  background: rgba(183, 28, 28, 0.06) !important;
}

/* ---- Legend ---- */
/* Consolidates what used to be 3 separate .legend boxes (Travel Period,
   Crowd Level, Special Events) into one bar with divider rules between
   groups -- source links moved out into their own muted line below,
   reclaiming the vertical space 3 full boxes used to take. */
.legend-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 14px;
  padding: 10px 14px;
  margin-top: 6px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
}

.legend-group {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.legend-divider {
  color: #ddd;
  font-weight: 300;
}

.legend-sources {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 4px;
  font-size: 0.6rem;
  color: #ccc;
}
.legend-sources .source-link { margin-left: 0; }

.legend-title {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  color: #888;
  letter-spacing: 0.5px;
  margin-right: 4px;
}

.legend-items {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 0.72rem;
  color: #555;
}

.legend-swatch {
  width: 12px;
  height: 12px;
  border-radius: 3px;
  flex-shrink: 0;
}

.legend-note {
  font-size: 0.68rem;
  color: #888;
  white-space: nowrap;
}

.source-link {
  font-size: 0.6rem;
  color: #aaa;
  text-decoration: none;
  margin-left: auto;
  white-space: nowrap;
}

.source-link:hover {
  color: var(--color-primary);
  text-decoration: underline;
}

/* Owner value color in summary */
.summary-row .row-value.owner {
  color: var(--color-primary);
}

/* ---- Action Buttons (between settings and summary) ---- */
#action-buttons {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* Room between the button stack (… Save Itinerary) and the summary card below it. */
#action-buttons:not(:empty) {
  margin-bottom: 12px;
}

#action-buttons:empty {
  display: none;
}

/* ---- Summary Panel (right side) ---- */
#summary {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.summary-card {
  background: white;
  border-radius: 10px;
  padding: 14px 16px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  min-width: 0;
}

.summary-card h3 {
  font-size: 0.8rem;
  font-weight: 600;
  color: #333;
  margin-bottom: 10px;
  padding-bottom: 6px;
  border-bottom: 1px solid #eee;
}

.summary-dates-display {
  margin-bottom: 10px;
}

.summary-dates-display .date-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 4px 0;
}

.summary-dates-display .date-label {
  font-size: 0.7rem;
  text-transform: uppercase;
  font-weight: 600;
  color: #888;
}

.summary-dates-display .date-value {
  font-size: 0.85rem;
  font-weight: 600;
  color: #333;
}

.summary-divider {
  height: 1px;
  background: #eee;
  margin: 8px 0;
}

.summary-stats {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.summary-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}

.summary-row .row-label {
  font-size: 0.8rem;
  color: #666;
}

.summary-row .row-value {
  font-size: 1rem;
  font-weight: 700;
  color: var(--color-secondary);
  white-space: nowrap;
  flex-shrink: 0;
}

.summary-row .row-value.cash {
  color: var(--color-good);
  display: inline-flex;
  align-items: center;
}

.summary-row .row-value .save-amount {
  min-width: 70px;
  text-align: right;
}

.summary-row .row-value.rack {
  color: var(--color-danger);
}

.cost-per-point {
  font-size: 0.65rem;
  font-weight: 600;
  color: #888;
  margin-left: 6px;
}

.summary-row .row-value .savings-badge {
  display: inline-block;
  font-size: 0.65rem;
  font-weight: 600;
  background: var(--color-good-bg);
  color: var(--color-good);
  padding: 2px 6px;
  border-radius: 4px;
  margin-left: 6px;
  vertical-align: middle;
  min-width: 42px;
  text-align: center;
}

.summary-section-label {
  font-size: 0.65rem;
  text-transform: uppercase;
  font-weight: 600;
  color: #aaa;
  letter-spacing: 0.5px;
  margin-top: 8px;
  margin-bottom: 2px;
}

/* ---- Cost Comparison tiles ---- */
.cost-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 14px;
  margin-top: 6px;
}

.cost-tile {
  min-width: 0;
  padding: 10px 12px;
  border: 1px solid #eee;
  border-radius: 10px;
}

.cost-tile-label {
  font-size: 0.65rem;
  text-transform: uppercase;
  font-weight: 600;
  color: #777;
  letter-spacing: 0.5px;
  margin-bottom: 4px;
}

.cost-tile-value {
  font-size: 1.15rem;
  font-weight: 700;
}

.cost-tile-value.rack { color: var(--color-danger); }
.cost-tile-value.owner { color: var(--color-primary); }
.cost-tile-value.cash { color: var(--color-good); }

.cost-tile-sub {
  font-size: 0.68rem;
  color: #666;
  margin-top: 2px;
}

/* Owner-resort trigger inside the "If using your own points" cost tile --
   same .picker-trigger look as the Resort/Booking As pickers (it opens
   #owner-resort-sheet, the same hero+search+swatch-row sheet as the main
   Resort picker), just sized down to fit a narrow tile instead of the
   wider top control bar. */
.cost-tile-trigger {
  min-width: 0;
  max-width: 100%;
  margin-bottom: 6px;
  padding: 4px 6px;
  font-size: 0.68rem;
}

.cost-tile-rate-input {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-bottom: 6px;
  font-size: 0.75rem;
  color: #555;
}

.cost-tile-rate-input input[type="number"] {
  width: 46px;
  padding: 3px 5px;
  border: 1px solid #ddd;
  border-radius: 6px;
  font-size: 0.75rem;
  text-align: right;
}

.cost-tile-rate-input input[type="number"]:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 2px rgba(74, 20, 140, 0.15);
}

/* "Use or rent?" line under the Cost Comparison tiles (dvc-rental.js). */
.use-or-rent {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 12px;
  margin-top: 12px;
  padding: 10px 12px;
  border-radius: 8px;
  font-size: 0.8rem;
  line-height: 1.4;
  background: var(--color-good-bg);
  color: #2e4d32;
}
.use-or-rent p { margin: 0; flex: 1 1 240px; }
.use-or-rent.rent { background: #fff6e0; color: #6b4a00; }
.use-or-rent.close { background: #f4f1f8; color: #444; }
.use-or-rent a { font-weight: 700; color: var(--color-primary); white-space: nowrap; text-decoration: none; }
.use-or-rent a:hover { text-decoration: underline; }

/* The shared $/pt editor (dvc-point-value.js) under the tiles. */
.cost-point-value {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid #eee;
}

.cost-tile-savings {
  margin-top: 6px;
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--color-good);
}

.cost-tile-savings.costs-more { color: var(--color-danger, #b71c1c); }

.cost-tile-savings .savings-badge {
  display: inline-block;
  font-size: 0.65rem;
  font-weight: 600;
  background: var(--color-good-bg);
  color: var(--color-good);
  padding: 2px 6px;
  border-radius: 4px;
}

.summary-row.total {
  padding-top: 10px;
  border-top: 2px solid var(--color-secondary);
  margin-top: 4px;
}

.summary-row.total .row-label {
  font-weight: 600;
  color: #333;
}

.summary-row.total .row-value {
  font-size: 1.3rem;
}

.summary-nightly {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid #eee;
}

.summary-nightly h4 {
  font-size: 0.7rem;
  text-transform: uppercase;
  font-weight: 600;
  color: #888;
  margin-bottom: 0;
  letter-spacing: 0.5px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  user-select: none;
}

.summary-nightly h4::after {
  content: "\25B6";
  font-size: 0.55rem;
  transition: transform 0.15s;
}

.summary-nightly.open h4::after {
  transform: rotate(90deg);
}

.summary-nightly h4:hover {
  color: var(--color-primary);
}

.nightly-rows {
  display: none;
  margin-top: 6px;
}

.summary-nightly.open .nightly-rows {
  display: block;
}

.nightly-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 3px 0;
  font-size: 0.75rem;
}

.nightly-row .night-date {
  color: #555;
  flex: 1;
}

.nightly-row .night-points {
  font-weight: 600;
  color: var(--color-secondary);
  min-width: 48px;
  text-align: right;
}

.nightly-row .night-cash {
  color: var(--color-danger);
  font-size: 0.65rem;
  min-width: 52px;
  text-align: right;
}

.summary-empty {
  color: #999;
  font-style: italic;
  font-size: 0.85rem;
  text-align: center;
  padding: 24px 12px;
}

/* ---- Booking As (contract personalization) ---- */
.contract-eligibility {
  font-size: 0.8rem;
  margin-top: 10px;
  padding: 8px 10px;
  border-radius: 6px;
}

.contract-eligibility.contract-ok {
  color: var(--color-good);
  background: var(--color-good-bg);
}

.contract-eligibility.contract-warn {
  color: #7a4a00;
  background: var(--color-warning-bg);
}

.contract-eligibility.contract-blocked {
  color: var(--color-danger);
  background: var(--color-danger-bg);
}

.contract-points {
  font-size: 0.78rem;
  color: #666;
  margin-top: 6px;
  padding: 6px 10px;
}

.contract-points.contract-points-over {
  color: var(--color-danger);
  background: var(--color-warning-bg);
  border-radius: 6px;
  font-weight: 600;
}

.summary-empty.small {
  padding: 8px 4px;
  text-align: left;
  font-size: 0.72rem;
}

/* ---- Resort Alerts (construction/refurbishment) ---- */
/* auto-fit so entries sit two-up once the card is wide enough (it spans
   the full Booking Outlook + Crowd Forecast width in review mode) and
   collapse to a single column in narrower layouts (before a stay is
   picked, or in split-stay mode) without a separate rule per layout. */
.resort-alert-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 8px;
}

.resort-alert {
  border-radius: 6px;
  padding: 8px 10px;
  background: #f7f7f7;
}

.resort-alert.overlaps-stay {
  background: var(--color-warning-bg);
}

.resort-alert-badge {
  display: inline-block;
  font-size: 0.6rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--color-warning);
  margin-bottom: 3px;
}

.resort-alert-location {
  font-size: 0.76rem;
  font-weight: 700;
  color: #333;
}

.resort-alert-dates {
  font-size: 0.66rem;
  color: #888;
  margin-top: 1px;
}

.resort-alert-desc {
  font-size: 0.72rem;
  color: #555;
  margin-top: 4px;
  line-height: 1.35;
}

.resort-alert-footer {
  display: block;
  margin-top: 8px;
  font-size: 0.6rem;
  color: #aaa;
  text-align: right;
  text-decoration: none;
}

.resort-alert-footer:hover {
  color: var(--color-primary);
  text-decoration: underline;
}

/* ---- Special Events & Festivals (buildSpecialEventsHTML()) ---- */
.special-event-group-label {
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: #999;
  margin: 10px 0 6px;
}

.special-event-group-label:first-of-type {
  margin-top: 0;
}

.special-event-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 8px;
}

.special-event {
  border-radius: 6px;
  padding: 8px 10px;
  background: #f7f7f7;
}

.special-event.ticketed {
  background: var(--color-primary-tint-bg, #f3ecfb);
}

.special-event-badge {
  display: inline-block;
  font-size: 0.6rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--color-primary);
  margin-bottom: 3px;
}

.special-event-name {
  font-size: 0.76rem;
  font-weight: 700;
  color: #333;
}

.special-event-dates {
  font-size: 0.66rem;
  color: #888;
  margin-top: 1px;
}

.special-event-desc {
  font-size: 0.72rem;
  color: #555;
  margin-top: 4px;
  line-height: 1.35;
}

.special-event-empty {
  font-size: 0.72rem;
  color: #999;
  font-style: italic;
}

/* ---- Value Score ---- */
.value-score-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 8px;
}

.value-score-badge {
  flex-shrink: 0;
  min-width: 54px;
  height: 46px;
  padding: 0 10px;
  border-radius: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
}

.value-score-num {
  font-size: 1.25rem;
  font-weight: 800;
}

.value-score-body {
  min-width: 0;
}

.value-score-label {
  font-size: 0.85rem;
  font-weight: 700;
  color: #333;
}

.value-tooltip {
  width: 200px;
}

.value-tooltip-title {
  font-size: 0.75rem;
  font-weight: 700;
  color: #333;
  margin-bottom: 4px;
}

.value-tooltip-desc {
  font-size: 0.68rem;
  color: #777;
  line-height: 1.35;
}

.value-score-desc {
  font-size: 0.66rem;
  color: #888;
  margin-top: 1px;
}

.no-cash-note {
  font-size: 0.72rem;
  color: #999;
  font-style: italic;
  margin-top: 8px;
}

.prior-year-note {
  font-size: 0.65rem;
  color: #999;
  font-style: italic;
  margin-top: 2px;
}


.summary-compare {
  display: block;
  width: 100%;
  margin-top: 10px;
  padding: 9px;
  background: white;
  border: 1.5px solid var(--color-primary);
  color: var(--color-primary);
  border-radius: 8px;
  font-size: 0.82rem;
  font-weight: 700;
  cursor: pointer;
  text-align: center;
  text-decoration: none;
  box-sizing: border-box;
}

.summary-compare:hover {
  background: var(--color-primary-tint-bg);
}

.summary-clear {
  display: block;
  width: 100%;
  margin-top: 10px;
  padding: 9px;
  background: white;
  border: 1.5px solid var(--color-primary);
  color: var(--color-primary);
  border-radius: 8px;
  font-size: 0.82rem;
  font-weight: 700;
  cursor: pointer;
}

.summary-clear:hover {
  background: var(--color-primary-tint-bg);
}

/* ---- Contract personalization: dates outside this contract's current
   booking window (11mo home / 7mo elsewhere), or a resort it can never
   book. Dimmed but still clickable -- unlike the old Booking Window
   dropdown, this is informational, not a hard gate, since someone may
   reasonably want to see what a date would cost even before they can
   actually book it. ---- */
.day-cell.contract-not-yet-bookable {
  opacity: 0.4;
}

.day-cell.contract-not-yet-bookable::after {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    135deg,
    rgba(0,0,0,0.035),
    rgba(0,0,0,0.035) 4px,
    transparent 4px,
    transparent 9px
  );
  pointer-events: none;
}

/* Past dates: greyscale + dimmed so a stale month view (or paging back to
   an earlier month) can't be mistaken for still-bookable dates -- distinct
   from .contract-not-yet-bookable's diagonal-stripe treatment above, since
   that's "not yet", this is "no longer". Still clickable, same reasoning:
   someone may want to check what a past date cost for historical reference. */
.day-cell.past-date {
  opacity: 0.4;
  filter: grayscale(1);
}

/* No chart for this night (Lakeshore Lodge before it opens): not pickable. */
.day-cell.no-points {
  background: #f4f4f4;
  border-color: #e4e4e4;
  opacity: 0.6;
  cursor: default;
}

.day-not-open {
  font-size: 0.7rem;
  font-weight: 600;
  color: #777;
  text-align: center;
  line-height: 1.1;
}

/* ---- Split Stay: Calendar ---- */
.day-cell.prev-segment {
  opacity: 0.45;
  pointer-events: none;
  outline: 2px solid #888;
  outline-offset: -1px;
}

/* ---- Split Stay: Summary ---- */
.segment-block {
  padding: 8px 0;
  border-bottom: 1px solid #eee;
}

.segment-block:last-of-type {
  border-bottom: none;
}

.segment-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 3px;
}

.segment-label {
  font-size: 0.6rem;
  text-transform: uppercase;
  font-weight: 700;
  color: #888;
  letter-spacing: 0.5px;
  white-space: nowrap;
}

.segment-resort {
  font-size: 0.85rem;
  font-weight: 600;
  color: #333;
}

.segment-edit {
  font-size: 0.65rem;
  color: var(--color-primary);
  cursor: pointer;
  margin-left: auto;
  font-weight: 600;
}

.segment-edit:hover {
  text-decoration: underline;
}

.segment-remove {
  font-size: 0.9rem;
  color: #bbb;
  cursor: pointer;
  line-height: 1;
  padding: 0 2px;
}

.segment-remove:hover {
  color: var(--color-danger);
}

.segment-detail {
  font-size: 0.75rem;
  color: #666;
  margin-top: 1px;
}

.segment-actions {
  display: flex;
  gap: 10px;
  margin-top: 4px;
}

.segment-compare {
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--color-primary);
  text-decoration: none;
}

.segment-compare:hover {
  text-decoration: underline;
}

.segment-nightly-toggle {
  font-size: 0.65rem;
  font-weight: 600;
  color: #888;
  cursor: pointer;
}

.segment-nightly-toggle:hover {
  color: var(--color-primary);
}

.segment-block .summary-nightly {
  margin-top: 4px;
  padding-top: 0;
  border-top: none;
}

/* Share this stay (dvc-share.js): top-right of the Your Stay / Split
   Stay card, beside its title (.card-header-row there; .card-title-row on
   the review-mode trip card, which has no rule under its label). */
.card-title-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.card-share-btn {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 0 12px;
  background: var(--color-bg-card, #fff);
  border: 1.5px solid var(--color-primary);
  border-radius: 8px;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--color-primary);
  cursor: pointer;
}
.card-share-btn:hover { background: rgba(74, 20, 140, 0.06); }

.summary-add-segment {
  display: block;
  width: 100%;
  margin-top: 10px;
  padding: 9px;
  background: white;
  border: 1.5px solid var(--color-primary);
  color: var(--color-primary);
  border-radius: 8px;
  font-size: 0.82rem;
  font-weight: 700;
  cursor: pointer;
  text-align: center;
}

.summary-add-segment:hover {
  background: var(--color-primary-tint-bg);
}

.summary-save-itinerary {
  display: block;
  width: 100%;
  margin-top: 10px;
  padding: 9px;
  background: var(--color-primary);
  border: 1.5px solid var(--color-primary);
  border-radius: 8px;
  font-size: 0.82rem;
  font-weight: 700;
  color: white;
  cursor: pointer;
  text-align: center;
}

.summary-save-itinerary:hover {
  background: var(--color-primary-active);
}
.summary-save-itinerary.secondary { background: white; color: var(--color-primary); }
.summary-save-itinerary.secondary:hover { background: var(--color-primary-tint-bg); }

/* Signed out, after tapping Save Itinerary: the sign-in cluster in place. */
.itinerary-signin { margin-top: 10px; padding: 12px; border: 1px solid var(--color-border-light); border-radius: 8px; background: var(--color-primary-tint-bg); text-align: center; }
.itinerary-signin-note { margin: 0 0 10px; font-size: 0.82rem; line-height: 1.4; color: #444; }
.itinerary-signin-btn { padding: 9px 16px; background: var(--color-primary); border: 1.5px solid var(--color-primary); border-radius: 8px; font-size: 0.82rem; font-weight: 700; color: white; cursor: pointer; }
.itinerary-signin-btn:hover { background: var(--color-primary-active); }
.itinerary-signin-cancel { display: block; margin: 10px auto 0; background: none; border: none; font-size: 0.8rem; font-weight: 700; color: var(--color-primary); cursor: pointer; }

.itinerary-save-form {
  display: flex;
  gap: 6px;
  margin-top: 10px;
}

.itinerary-save-form input {
  flex: 1;
  min-width: 0;
  padding: 7px 8px;
  border: 1px solid #ccc;
  border-radius: 6px;
  font-size: 0.8rem;
}

.itinerary-save-form input:focus {
  outline: none;
  border-color: var(--color-good);
  box-shadow: 0 0 0 2px rgba(46, 125, 50, 0.15);
}

.itinerary-save-confirm {
  padding: 7px 12px;
  background: var(--color-primary);
  border: none;
  border-radius: 8px;
  font-size: 0.82rem;
  font-weight: 700;
  color: white;
  cursor: pointer;
  white-space: nowrap;
}

.itinerary-save-confirm:hover { background: var(--color-primary-active); }
.itinerary-save-confirm:disabled { opacity: 0.6; cursor: default; }

.itinerary-save-cancel {
  padding: 7px 10px;
  background: none;
  border: 1px solid #ccc;
  border-radius: 6px;
  font-size: 0.9rem;
  color: #666;
  cursor: pointer;
}

.itinerary-save-cancel:hover { border-color: var(--color-danger); color: var(--color-danger); }

.itinerary-save-error {
  margin-top: 6px;
  font-size: 0.75rem;
  color: var(--color-danger);
}

/* ---- Responsive ---- */
@media (max-width: 800px) {
  /* Scoped to narrow viewports only -- overflow-x: auto here pairs with
     .calendar-grid's min-width below to let the grid scroll horizontally
     instead of squeezing cells illegibly. Applying it unconditionally
     (as this used to) triggers a CSS Overflow Module interop rule: when
     overflow-x is anything other than visible, a not-visible overflow-y
     computes to auto too, and visible overflow-y computes to auto as
     well (a visible/non-visible pairing isn't allowed) -- so even before
     this was scoped, overflow-y was never actually visible on desktop,
     it silently became a second auto scrollbar clipping the grid to a
     shorter-than-content height for no reason, since desktop never
     needed horizontal scroll at all. */
  .calendar-grid-scroll {
    overflow-x: auto;
    /* Explicit, not left to default: per the CSS Overflow Module interop
       rule described above, overflow-x: auto forces overflow-y to compute
       to auto as well if left unset -- turning this div into an
       independently vertically-scrollable container even though its
       height already just fits its content. On mobile, a couple of
       fractional pixels of rounding (grid gaps, cell borders) is enough
       for that phantom scroll container to register as "scrollable", so a
       touch-scroll gesture starting over the calendar sometimes gets
       consumed by this element's own scroll/rubber-band instead of the
       page's, producing a visible blank gap where the legend below should
       already be showing. overflow-y: hidden opts back out of the
       interop pairing without affecting the intended horizontal scroll. */
    overflow-y: hidden;
    /* .calendar-grid's own min-width is 0 (see below) -- this container
       never needs to scroll far enough to reveal real hidden content, only
       far enough to absorb that same rounding noise (measured as low as
       2-4px total across all 7 columns, an imperceptible sliver per cell).
       Scoped to a NARROW/harmless scroll like that, a visible scrollbar
       reads as "the calendar doesn't fit" (reported directly against a
       live mobile screenshot) even though nothing is actually being cut
       off -- hiding it keeps the sub-pixel safety valve functional
       without advertising it as if there were real content to scroll to. */
    scrollbar-width: none;
  }
  .calendar-grid-scroll::-webkit-scrollbar {
    display: none;
  }

  /* Collapsed by default: brand + toggle stay on one row, everything else
     (.site-nav-links, #account-control) is display:none until .open --
     when shown, each is width:100% so flex-wrap forces it onto its own
     new line below the row, no extra positioning needed. This replaced an
     earlier version that just stacked every nav group onto its own line
     unconditionally -- on a real phone that alone pushed the calendar
     itself almost entirely off the first screen (reported directly against
     a live screenshot: nav + header banner together ate ~35-40% of the
     viewport before any calendar content appeared). */
  .site-nav-toggle {
    display: flex;
  }

  .site-nav-links {
    display: none;
    /* .site-nav-links also has flex: 1 in the base (non-media) rule above,
       which sets flex-basis: 0% -- that wins over a plain width:100% in
       flex sizing, leaving this squeezed next to the toggle button instead
       of wrapping onto its own row. flex: 0 0 100% overrides all three
       shorthand parts so width:100% actually takes effect. Confirmed via a
       real click-through, not just written and assumed correct. */
    flex: 0 0 100%;
    width: 100%;
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
    margin-top: 4px;
    padding-top: 10px;
    border-top: 1px solid #eee;
  }

  .site-nav-group {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }

  #account-control {
    display: none;
    width: 100%;
    margin-top: 10px;
  }

  .site-nav.open .site-nav-links,
  .site-nav.open #account-control {
    display: flex;
  }
  .site-nav.open #account-control {
    display: block;
  }

  /* Header banner: shrunk specifically for narrow phones -- same reasoning
     as the nav collapse above, this was reported as eating real vertical
     space before any actual calendar content was visible. */
  .header {
    padding: 10px 20px;
  }
  .header h1 {
    font-size: 1.05rem;
  }
  .header .subtitle {
    font-size: 0.7rem;
  }

  .main-layout {
    flex-direction: column;
    /* Desktop's flex-start (top-aligned columns) leaves each stacked child
       free to size to its own content-width instead of the viewport once
       direction flips to column -- .summary-side.expanded's width:auto
       (needed on desktop so it can grow into the freed-up space next to
       the collapsed trip rail) was sizing to the two-column Insights grid's
       content width (~400px) instead of the phone's actual width, pushing
       the whole page into horizontal scroll. stretch forces every stacked
       child to the container's actual width regardless of its own content. */
    align-items: stretch;
  }

  .calendar-side {
    width: 100%;
    min-width: 0;
  }

  .summary-side {
    width: 100%;
    position: static;
  }

  .controls {
    flex-direction: column;
    align-items: stretch;
    padding: 10px 16px;
  }

  /* Collapsed by default on mobile -- the 4 stacked dropdowns were eating
     roughly half the screen before any calendar/trip content appeared
     (reported directly against a live screenshot). Doubles as the "Active
     Context Summary Bar": while collapsed, its label shows a live Resort ·
     Room Type · Booking As readout (app.js's buildActiveContextSummary())
     instead of a static placeholder, so landing on a collapsed drawer never
     leaves the calendar's point numbers unexplained. Styled as a tappable
     mini-card (tinted background, rounded corners) rather than the plain
     text-link look it had before, so it reads as its own summary control,
     not just a section label. #controls-toggle's click wiring lives in
     app.js now (it needs live calendar state), not nav.js. */
  .controls-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    min-height: 46px;
    padding: 10px 14px;
    border: 1px solid var(--color-primary-tint-bg);
    border-radius: 10px;
    background: var(--color-primary-tint-bg);
    background-size: cover;
    background-position: center;
    font-size: 0.84rem;
    font-weight: 600;
    color: var(--color-primary);
    cursor: pointer;
    text-align: left;
  }

  /* Collapsed summary bar for a resort with art (data/resort_images.js) --
     app.js's updateActiveContextBar() sets background-image inline to a
     translucent tint wash over the resort's art (same --color-primary-
     tint-bg color, just see-through) so the photo reads behind the text
     instead of replacing the flat pill look outright. The border alone
     would otherwise sit as a hard flat-purple line across a photo. */
  .controls-toggle.has-art {
    border-color: rgba(255, 255, 255, 0.5);
  }

  /* Truncates instead of wrapping -- a full "Resort Name · Room Type ·
     Contract Name" line can easily run past a narrow phone's width, and
     wrapping it would push the chevron off to its own line or grow the
     bar's height unpredictably. flex:1/min-width:0 is what lets the
     ellipsis actually take effect on a flex child. */
  #controls-toggle-label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .controls-toggle-arrow {
    flex-shrink: 0;
    transition: transform 0.15s ease;
  }

  .controls-toggle[aria-expanded="true"] .controls-toggle-arrow {
    transform: rotate(180deg);
  }

  .controls-groups {
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }

  .controls-groups.open {
    display: flex;
  }

  .month-nav {
    margin-left: 0;
    justify-content: center;
  }

  .picker-trigger {
    min-width: unset;
    max-width: unset;
    width: 100%;
  }

  .room-type-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .modal-box.sheet {
    max-height: 80vh;
  }

  /* Reworked 2026-09-18: a forced min-width (420px) made the whole week
     require horizontal scrolling to see Fri/Sat on real phones -- reported
     back as a regression ("user has to scroll left and right"), not the
     intended behavior. Shrinking every cell to actually fit the viewport
     instead, so all 7 days are visible with no scrolling needed.
     overflow-x: auto above stays as a safety net for anything narrower
     than this still manages to fit (old phones, split-screen, etc). */
  .calendar-grid {
    min-width: 0;
    padding: 4px;
    gap: 3px;
  }

  .day-cell {
    min-height: 50px;
    padding: 4px 1px;
  }

  .day-header {
    font-size: 0.58rem;
    padding: 4px 0;
  }

  .day-cell .day-points {
    font-size: 0.72rem;
  }

  .day-cell .day-number {
    font-size: 0.5rem;
    top: 2px;
    left: 3px;
  }

  .day-cell .day-cash {
    font-size: 0.46rem;
    letter-spacing: -0.2px;
  }

  .day-cell .day-crowd {
    top: 2px;
    right: 2px;
    font-size: 0.4rem;
    padding: 1px 2px;
  }

  .day-cell .day-event {
    bottom: 2px;
    right: 2px;
    font-size: 0.5rem;
  }

  /* The "|" divider only makes visual sense inline -- once .legend-group
     wraps each section onto its own row (flex-wrap on .legend-bar), a
     lone "|" character becomes its own near-empty row, which is what
     produced the large gaps reported between Travel Period/Crowd Level/
     Special Events on mobile. */
  .legend-divider {
    display: none;
  }

  .legend-bar {
    gap: 10px;
  }
}

/* ---- Availability Outlook ---- */
.availability-outlook {
}

.avail-stay-length {
  font-weight: 400;
  color: #999;
  font-size: 0.7rem;
  margin-left: 4px;
}

.avail-dot-row {
  display: flex;
  gap: 8px;
  margin: 6px 0 4px;
}

.avail-dot-col {
  display: flex;
  flex: 1;
  min-width: 0;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}

.avail-dot-label {
  font-size: 0.55rem;
  font-weight: 600;
  color: #999;
  text-transform: uppercase;
  letter-spacing: 0.2px;
}

.avail-dot {
  width: 100%;
  max-width: 34px;
  height: 22px;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Baked-in context: a 2-letter code (Ex/Gd/Fr/Lo/NL) directly in the color
   block itself, so the color alone doesn't require a tap to understand --
   see availabilityLabel()/buildAvailabilityDotsHTML() in app.js. */
.avail-dot-code {
  font-size: 0.62rem;
  font-weight: 700;
  color: white;
  text-shadow: 0 1px 1px rgba(0,0,0,0.25);
  pointer-events: none;
}

.avail-dot-excellent { background: var(--color-good); }
.avail-dot-good { background: #f9a825; }
.avail-dot-fair { background: var(--color-warning); }
.avail-dot-low { background: #d84315; }
.avail-dot-very-low { background: var(--color-danger); }

.avail-dot-tooltip {
  width: 160px;
  text-align: center;
  font-size: 0.7rem;
  font-weight: 600;
  color: #333;
}

.avail-intro {
  font-size: 0.72rem;
  color: #666;
  margin: -2px 0 6px;
}

.avail-note {
  font-size: 0.6rem;
  color: #aaa;
  margin-top: 4px;
}

.avail-note a {
  color: #aaa;
  text-decoration: underline;
}

.avail-segment {
  margin-bottom: 8px;
}

.avail-segment:last-of-type {
  margin-bottom: 0;
}

.avail-segment-name {
  font-size: 0.75rem;
  font-weight: 600;
  color: #555;
  margin-bottom: 3px;
}

/* "Confirm with Disney before you book" under the calendar's Cost Comparison */
.booking-note {
  margin: 10px 0 0;
  font-size: 0.75rem;
  color: #777;
}
