/* ══════════════════════════════════════════════════════════════════════════
   Sedona Itinerary Builder — Frontend stylesheet

   RECONSTRUCTED CSS BASELINE. The original builder.css from production was
   not included in this build. This baseline defines:
     - The 9 brand CSS variables (red rock palette)
     - Layout primitives (grids, cards, hero)
     - Animations (pulse, spin, fade, shimmer)
     - Mobile/desktop responsive toggles
     - Print/no-print classes

   If you have access to the production builder.css, replace this file with
   the original to get a pixel-perfect match to sedonaready.com.
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Sedona red rock palette */
  --sib-canyon:     #C4532B;   /* Primary brand accent (rust) */
  --sib-terracotta: #7D3418;   /* Darker rust — mountain back-layer + sticky-bar accents */
  --sib-gold:       #C4882B;   /* Muted highlight */
  --sib-sand:       #F4F0EA;   /* Secondary surface */
  --sib-sage:       #6b8068;   /* Saved-state semantic green — UNCHANGED */
  --sib-cream:      #FBF9F6;   /* Page background (bone-white) */
  --sib-ink:        #2D2D2D;   /* Body text (charcoal) */
  --sib-shadow:     #1F1D1B;   /* Headlines / deep accents */
  --sib-muted:      #8A827A;   /* Captions/labels (warm-gray) */
  --sib-link:       #2B5C8A;   /* Steel blue — links only (NEW token) */
  --sib-border:     #E7E1D8;   /* Soft dividers (NEW token) */
  --sib-sand-2:     #F4F0EA;   /* Secondary surface variant (NEW — was silently undefined; resolves 5 broken sites) */
}

/* ─── Builder root ──────────────────────────────────────────────────────── */

.sib-builder-root {
  /* Inherit the host theme's body font (Astra on production) so the builder
     reads as a native section of the page rather than a bolted-on widget.
     Display headings keep Georgia via .sib-font-display / .sib-hero-title /
     .sib-section-title / .sib-day-theme / .sib-day-number — those are
     intentional editorial accents. */
  font-family: inherit;
  color: var(--sib-ink);
  background: var(--sib-cream);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

.sib-builder-root * { box-sizing: border-box; }

.sib-builder-root button {
  font-family: inherit;
  cursor: pointer;
}

/* Form controls don't inherit font-family by default — opt them in so date
   inputs and the textareas read in the host theme's body font. */
.sib-builder-root input,
.sib-builder-root textarea,
.sib-builder-root select {
  font-family: inherit;
  font-size: inherit;
}

.sib-builder-root a { color: var(--sib-canyon); }

.sib-font-display {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 700;
  letter-spacing: -0.02em;
}

/* ─── Hero ─────────────────────────────────────────────────────────────── */

.sib-hero-content { position: relative; }
.sib-hero-meta { width: 100%; }
.sib-hero-title { font-family: Georgia, serif; }
.sib-hero-lede { line-height: 1.6; }
.sib-hero-saved-btn:hover { background: rgba(184, 84, 45, 0.08); }

/* Inviting "Start with who's traveling →" pill in the hero. Canyon-red text
   on cream, soft border, hover deepens the fill. Replaces the older
   "↓ Begin below" passive label with something clickable that smooth-scrolls
   to the segment grid. */
.sib-hero-begin-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  border-radius: 999px;
  padding: 0.75rem 1.5rem;
  font-size: 0.95rem;
  font-weight: 600;
  background: var(--sib-cream);
  color: var(--sib-canyon);
  border: 1px solid rgba(184, 84, 45, 0.35);
  cursor: pointer;
  transition: background 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
  font-family: inherit;
}
.sib-hero-begin-btn:hover {
  background: rgba(184, 84, 45, 0.08);
  border-color: var(--sib-canyon);
}
.sib-hero-begin-btn:active {
  transform: scale(0.98);
}

/* ─── Main ─────────────────────────────────────────────────────────────── */

.sib-main { padding: 3rem 1.5rem 5rem; }

/* ─── Form progress indicator (4 segments, pinned below hero) ──────────────
   Four discrete 4px segments separated by 2px gaps. Each fills canyon-red
   independently as the corresponding form section gets a valid answer. The
   container spans the same max-width as the hero/main, so the bar visually
   anchors the form below it. */

.sib-progress {
  max-width: 72rem;
  margin: 0 auto;
  padding: 0 1.5rem;
}
.sib-progress-segments {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 2px;
}
.sib-progress-seg {
  height: 4px;
  background: rgba(43, 24, 16, 0.08);
  border-radius: 2px;
  transition: background 0.35s ease;
}
.sib-progress-seg--done {
  background: var(--sib-canyon);
}

.sib-section-number {
  display: inline-block;
  font-size: 0.7rem;
  letter-spacing: 0.25em;
  color: var(--sib-canyon);
  margin-bottom: 0.5rem;
  text-transform: uppercase;
}

.sib-section-title {
  font-family: Georgia, serif;
  font-size: clamp(1.5rem, 3vw, 2rem);
  margin-bottom: 0.5rem;
  color: var(--sib-shadow);
}

.sib-section-subtitle {
  color: var(--sib-muted);
  margin-bottom: 1.5rem;
  font-size: 0.95rem;
}

/* ─── Segment grid ─────────────────────────────────────────────────────── */

.sib-segment-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1rem;
  margin-bottom: 2rem;
}

@media (max-width: 640px) {
  .sib-segment-grid { grid-template-columns: 1fr 1fr; gap: 0.75rem; }
  .sib-segment-id-row { flex-direction: column; gap: 0.5rem; }
}

.sib-segment-icon-wrap {
  width: 3rem;
  height: 3rem;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(184, 84, 45, 0.08);
  color: var(--sib-canyon);
  margin-bottom: 0.75rem;
}

.sib-segment-name {
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--sib-shadow);
  margin-bottom: 0.25rem;
}

.sib-segment-tagline { font-size: 0.8rem; color: var(--sib-muted); }
.sib-segment-blurb {
  font-size: 0.875rem;
  color: var(--sib-ink);
  margin-top: 0.5rem;
  line-height: 1.5;
}

/* Segment cards default to the icon-only layout for backward compatibility
   (sets padding inline). When a card has an image we override layout: image
   spans the card edge-to-edge at the top, body sits below with its own
   padding. The icon doubles as a small circular badge in the image corner. */

.sib-segment-card {
  border-radius: 0.75rem;
  padding: 1.25rem;
  text-align: left;
  cursor: pointer;
  overflow: hidden;
}
/* No-image branch — icon-beside-name row inside .sib-segment-card-body.
   Base rule reproduces the prior inline style; mobile override (in the
   segment @media block below) stacks icon above name so the name has
   full card content width and stops clipping on narrow viewports. */
.sib-segment-id-row {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  margin-bottom: 0.5rem;
}
.sib-segment-card--has-image {
  padding: 0;
}
.sib-segment-image {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: var(--sib-sand);
  overflow: hidden;
  border-radius: 0.75rem 0.75rem 0 0;
}
.sib-segment-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.sib-segment-image-badge {
  position: absolute;
  bottom: 0.5rem;
  right: 0.5rem;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 999px;
  background: var(--sib-canyon);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
}
.sib-segment-card--has-image .sib-segment-card-body {
  padding: 1rem 1.25rem 1.25rem;
}

/* ─── Selectable controls — unified border-accent pattern ──────────────────
   Cards, segmented buttons, and multi-select chips all use the same visual
   language for selection: a 2px canyon-red outline + a faint warm tint
   background. Text colors NEVER change between selected/unselected — keeping
   readability identical regardless of state.

   Rationale: the previous fill-on-select treatment (canyon-red background
   with white/cream text) was unreadable for segment cards in v1.0.2 because
   the inline-style text colors (cream) sat against a faint CSS-tinted
   background (rgba canyon-red @ 0.08 over white), producing near-white text
   on near-white background. Switching everything to outline-only resolves
   the contrast bug AND makes the UI feel consistent across all chip groups.

   `outline` is used (not `border-width: 2`) so the layout never shifts when
   selection toggles. */

.sib-card {
  background: white;
  border: 1px solid rgba(43, 24, 16, 0.12);
  border-radius: 0.75rem;
  transition: border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease, transform 0.18s ease;
  color: var(--sib-ink);
  font: inherit;
}
.sib-card:hover {
  border-color: rgba(184, 84, 45, 0.4);
}
.sib-card.sib-active {
  border-color: var(--sib-canyon);
  background: white;
  outline: 2px solid var(--sib-canyon);
  outline-offset: -2px;
  box-shadow: 0 0 0 1px rgba(184, 84, 45, 0.15);
  transform: scale(1.02);
}

/* ─── Segmented buttons (Duration, Season, Pace, Budget, Starting Point) */

.sib-seg-btn {
  background: white;
  border: 1px solid rgba(43, 24, 16, 0.14);
  border-radius: 0.5rem;
  color: var(--sib-ink);
  font-size: 0.875rem;
  padding: 0.625rem 0.75rem;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
  font-family: inherit;
}
.sib-seg-btn:hover {
  border-color: var(--sib-canyon);
  background: rgba(184, 84, 45, 0.04);
}
.sib-seg-btn.sib-active {
  border-color: var(--sib-canyon);
  background: white;
  color: var(--sib-ink);
  font-weight: 600;
  outline: 2px solid var(--sib-canyon);
  outline-offset: -2px;
  box-shadow: 0 0 0 1px rgba(184, 84, 45, 0.15);
}

/* ─── Multi-select chips (Interests, Accessibility) ────────────────────────
   Pill-shaped chips with a pseudo-element prefix ("+" inactive, "✓" active)
   so the checkbox-style affordance is visually distinct from the radio-style
   .sib-seg-btn groups above. Both selected states share the same outline
   accent for visual consistency. */

.sib-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: white;
  border: 1px solid rgba(43, 24, 16, 0.14);
  border-radius: 999px;
  color: var(--sib-ink);
  font-size: 0.85rem;
  padding: 0.4rem 0.85rem;
  margin: 0 0.25rem 0.4rem 0;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
  font-family: inherit;
}
.sib-chip::before {
  content: "+";
  font-weight: 700;
  color: var(--sib-muted);
  font-size: 0.95rem;
  line-height: 1;
}
.sib-chip:hover {
  border-color: var(--sib-canyon);
  background: rgba(184, 84, 45, 0.04);
}
.sib-chip:hover::before { color: var(--sib-canyon); }
.sib-chip.sib-active {
  border-color: var(--sib-canyon);
  background: white;
  color: var(--sib-ink);
  outline: 2px solid var(--sib-canyon);
  outline-offset: -2px;
  box-shadow: 0 0 0 1px rgba(184, 84, 45, 0.15);
}
.sib-chip.sib-active::before {
  content: "✓";
  color: var(--sib-canyon);
}

/* ─── Interest chip category groups ────────────────────────────────────────
   Four categories, each chip gets a 3px left border in its category color so
   users can scan by interest type. Category headers are small uppercase
   letter-spaced muted labels above each group. */

.sib-interest-group {
  margin-bottom: 1.25rem;
}
.sib-interest-group:last-child { margin-bottom: 0; }
.sib-interest-group-label {
  font-size: 0.65rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--sib-muted);
  margin-bottom: 0.5rem;
  font-weight: 600;
}

.sib-chip--outdoor     { border-left: 3px solid #5A7E61; }
.sib-chip--cultural    { border-left: 3px solid #A88040; }
.sib-chip--wellness    { border-left: 3px solid #8B7A9E; }
.sib-chip--distinctive { border-left: 3px solid var(--sib-canyon); }

/* When a category chip is selected, the canyon-red outline takes precedence
   over the left-border accent visually (outline draws on top). Keep the
   accent visible by letting the left-border stay its category color rather
   than overriding to canyon-red. */

/* ─── Itinerary body layout — default stacked ─────────────────────────────
   .sib-itinerary-main holds days + pack/avoid. .sib-itinerary-rail wraps
   the bookings section. By default they stack vertically (rail below main)
   — this is the safe production layout. The experimental sticky variant
   below activates only when the feature flag is on AND viewport ≥ 1100px. */

.sib-itinerary-output .sib-itinerary-body {
  display: block;
}

.sib-itinerary-output .sib-itinerary-rail--empty {
  display: none;
}

/* ─── Experimental sticky rail (phase 2 #5) ────────────────────────────────
   Gated by SIB_Plugin::DEFAULTS['enable_sticky_rail'] which surfaces as
   feature_flags.sticky_rail through /config and featureFlags.stickyRail in
   the inline SIB_CONFIG. The React side appends .sib-experimental-sticky-
   rail to .sib-itinerary-output when the flag is true.

   Below 1100px the grid never activates regardless of flag state — rail
   falls back to its natural stacked position.

   KNOWN INTERACTIONS:
     position:sticky requires no ancestor with overflow:hidden, transform,
     filter, or perspective. The plugin's own DOM is clean, but the host
     theme (Astra) and any page-builder wrapper (Elementor) can introduce
     such ancestors. If sticky doesn't engage on a given site, the most
     likely culprit is one of those wrappers — debug via DevTools by
     setting position:sticky on any ancestor and watching for the rail to
     fix to the viewport. */

@media (min-width: 1100px) {
  .sib-itinerary-output.sib-experimental-sticky-rail .sib-itinerary-body {
    display: grid;
    grid-template-columns: 1fr 340px;
    gap: 48px;
    align-items: start;
  }

  .sib-itinerary-output.sib-experimental-sticky-rail .sib-itinerary-rail {
    position: sticky;
    top: 24px;
    align-self: start;
    max-height: calc(100vh - 48px);
    overflow-y: auto;
  }

  /* When the rail is the empty placeholder (no bookings to show), drop
     back to a single column on desktop too — the grid's second column
     would otherwise leave a gap of 340px next to the days. */
  .sib-itinerary-output.sib-experimental-sticky-rail .sib-itinerary-body:has(.sib-itinerary-rail--empty) {
    display: block;
  }

  /* In sticky mode the bookings grid shrinks to 1-up (the rail is narrow).
     The viator widgets stack vertically inside the rail. */
  .sib-itinerary-output.sib-experimental-sticky-rail .sib-bookings-grid {
    grid-template-columns: 1fr;
  }
}

/* ─── Sticky form CTA bar ──────────────────────────────────────────────────
   Persistent CTA shown only while a segment is chosen and the itinerary
   hasn't been generated yet. Two responsive modes:

   Desktop (>640px): centered floating pill bounded by the form's max-width.
   Background cream + soft top shadow gives lift off the page background.

   Mobile (≤640px): full-width bar pinned to the viewport bottom. No
   border-radius so it edge-to-edges the screen on phones, which matches
   how iOS/Android system sticky CTAs render. */

.sib-stickybar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 1.5rem;
  padding: 0 1.5rem;
  z-index: 90;
  pointer-events: none;
}
.sib-stickybar-inner {
  pointer-events: auto;
  max-width: 70rem;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.75rem 1rem 0.75rem 1.25rem;
  background: var(--sib-cream);
  border: 1px solid rgba(43, 24, 16, 0.08);
  border-radius: 999px;
  box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.06), 0 8px 24px rgba(0, 0, 0, 0.08);
}
.sib-stickybar-summary {
  flex: 1;
  min-width: 0;
  font-size: 0.875rem;
  color: var(--sib-ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sib-stickybar-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  background: var(--sib-canyon);
  color: white;
  border: none;
  border-radius: 999px;
  padding: 0.625rem 1.25rem;
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.18s ease, transform 0.15s ease;
  font-family: inherit;
  flex-shrink: 0;
}
.sib-stickybar-cta:hover { background: #9c4424; }
.sib-stickybar-cta:active { transform: scale(0.98); }
.sib-stickybar-cta:disabled {
  background: var(--sib-sand);
  color: var(--sib-muted);
  cursor: not-allowed;
}

@media (max-width: 640px) {
  .sib-stickybar {
    bottom: 0;
    padding: 0;
  }
  .sib-stickybar-inner {
    border-radius: 0;
    padding: 0.75rem 1rem;
    border-left: none;
    border-right: none;
    border-bottom: none;
    border-top: 1px solid rgba(43, 24, 16, 0.08);
  }
}

/* ─── Saved-itineraries drawer ─────────────────────────────────────────────
   Slide-in panel from the right. Hidden by default — .sib-open transitions
   it into view. Without these rules the <aside> + backdrop rendered inline
   at the bottom of the page (Bug #3 in 1.0.1). */

.sib-drawer-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(26, 14, 8, 0.45);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s ease, visibility 0.2s ease;
  z-index: 998;
}
.sib-drawer-backdrop.sib-open {
  opacity: 1;
  visibility: visible;
}
.sib-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(420px, 92vw);
  background: var(--sib-cream);
  box-shadow: -8px 0 24px rgba(0, 0, 0, 0.18);
  transform: translateX(100%);
  transition: transform 0.25s ease;
  z-index: 999;
  overflow-y: auto;
}
.sib-drawer.sib-open {
  transform: translateX(0);
}

/* ─── Trip shape grid ──────────────────────────────────────────────────── */

.sib-trip-shape-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1rem;
}

.sib-dates-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

@media (max-width: 640px) {
  .sib-dates-grid { grid-template-columns: 1fr; }
}

/* v1.1.0 — each picker is a vertical stack: eyebrow on top, date input
   center, formatted day/date label below (when a date is selected). */
.sib-date-field {
  display: flex;
  flex-direction: column;
}

.sib-date-eyebrow {
  font-size: 0.75rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--sib-muted);
  margin-bottom: 0.75rem;
}

.sib-date-label {
  margin-top: 0.5rem;
  font-size: 0.8125rem;
  font-style: italic;
  color: var(--sib-canyon);
}

/* ─── Itinerary output — modern day cards ──────────────────────────────────
   Phase 2 design polish. Banded full-bleed canyon-red day headers from
   1.0.5- replaced with contained cards: white background, 1px sand border,
   16px radius, and a 4px canyon-red left accent rendered via inset
   box-shadow (border-left would step against the rounded corners). The
   second shadow layer is a soft lift off the page. */

.sib-itinerary-output .sib-day-card {
  background: white;
  border: 1px solid var(--sib-sand);
  border-radius: 16px;
  padding: 32px;
  margin: 0;
  overflow: hidden;
  box-shadow: inset 4px 0 0 var(--sib-canyon), 0 2px 12px rgba(0, 0, 0, 0.04);
}

@media (min-width: 768px) {
  .sib-itinerary-output .sib-day-card {
    padding: 48px;
  }
}

.sib-itinerary-output .sib-day-cards {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

@media (min-width: 768px) {
  .sib-itinerary-output .sib-day-cards {
    gap: 32px;
  }
}

/* Day heading — moved INSIDE the card (no banded header). The day number
   sits as small-caps editorial label; the theme title is display serif. */
.sib-itinerary-output .sib-day-eyebrow {
  font-family: Georgia, serif;
  font-style: italic;
  font-size: 13px;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: var(--sib-canyon);
  margin: 0 0 8px;
}

.sib-itinerary-output .sib-day-theme {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 26px;
  line-height: 1.15;
  color: var(--sib-shadow);
  margin: 0;
  font-weight: 600;
}

@media (min-width: 768px) {
  .sib-itinerary-output .sib-day-theme {
    font-size: 32px;
  }
}

/* ─── Day hero images (phase 2 #2) ─────────────────────────────────────────
   16:9 image at top of each day card when an attachment is tagged either
   day-{character} or sib-fallback-day. Image breaks out of the card's
   padding via negative margins so it spans edge-to-edge; the card's
   overflow:hidden + 16px radius clip the image to rounded TOP corners only.

   Two title variants:
     --overlay: short titles (≤60 chars) overlaid on the image with a
                bottom-to-top gradient mask (transparent → rgba black 45%).
     --below:  long titles render in standard heading position below the
                image (the <header> renders normally).
*/
.sib-itinerary-output .sib-day-hero {
  position: relative;
  width: calc(100% + 64px);
  margin: -32px -32px 24px;
  aspect-ratio: 16 / 9;
  background: var(--sib-sand);
  overflow: hidden;
  border-radius: 16px 16px 0 0;
}

@media (min-width: 768px) {
  .sib-itinerary-output .sib-day-hero {
    width: calc(100% + 96px);
    margin: -48px -48px 32px;
  }
}

.sib-itinerary-output .sib-day-hero img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.sib-itinerary-output .sib-day-hero--overlay::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0) 55%);
  pointer-events: none;
}

.sib-itinerary-output .sib-day-hero-overlay {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 24px;
  z-index: 1;
}

@media (min-width: 768px) {
  .sib-itinerary-output .sib-day-hero-overlay { padding: 32px; }
}

.sib-itinerary-output .sib-day-eyebrow--on-image {
  color: rgba(255, 255, 255, 0.85);
}

.sib-itinerary-output .sib-day-theme--on-image {
  color: white;
}

/* Legacy .sib-slot-icon kept for backward compatibility with any saved
   itineraries that might still render through it; new output uses .sib-slot-row. */
.sib-slot-icon {
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(184, 84, 45, 0.08);
  color: var(--sib-canyon);
  flex-shrink: 0;
}

/* ─── Slot rows (phase 2) ──────────────────────────────────────────────────
   Per-slot rendering inside the day card. Time label on the left in a fixed
   100px column; content on the right. No nested card chrome — rows ARE the
   content of the day card. */

.sib-itinerary-output .sib-day-body {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.sib-itinerary-output .sib-slot-row {
  display: grid;
  grid-template-columns: 100px 1fr;
  gap: 24px;
  align-items: baseline;
}

@media (max-width: 640px) {
  .sib-itinerary-output .sib-slot-row {
    grid-template-columns: 1fr;
    gap: 16px;
  }
}

.sib-itinerary-output .sib-slot-time {
  text-align: left;
}
.sib-itinerary-output .sib-slot-time-label {
  font-size: 13px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--sib-canyon);
  font-weight: 600;
}
.sib-itinerary-output .sib-slot-time-value {
  font-size: 13px;
  color: var(--sib-muted);
  margin-top: 2px;
}

.sib-itinerary-output .sib-slot-content { min-width: 0; }

.sib-itinerary-output .sib-slot-title-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 4px;
}
.sib-itinerary-output .sib-slot-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 20px;
  line-height: 1.2;
  color: var(--sib-shadow);
  margin: 0;
  font-weight: 600;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
@media (min-width: 768px) {
  .sib-itinerary-output .sib-slot-title { font-size: 22px; }
}

.sib-itinerary-output .sib-slot-location {
  font-size: 13px;
  font-style: italic;
  color: var(--sib-canyon);
  margin-bottom: 6px;
}

.sib-itinerary-output .sib-slot-desc {
  font-size: 16px;
  line-height: 1.5;
  color: var(--sib-ink);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Inline "Book →" text link inside the description — canyon-red, no button
   chrome. The description is line-clamped, so the link sits at the natural
   end of whichever line the text ends on. */
.sib-itinerary-output .sib-slot-book {
  color: var(--sib-canyon);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.sib-itinerary-output .sib-slot-book:hover { text-decoration: underline; }

.sib-itinerary-output .sib-slot-tip {
  margin-top: 8px;
  display: flex;
  gap: 6px;
  align-items: flex-start;
  font-size: 13px;
  line-height: 1.5;
  color: var(--sib-muted);
}
.sib-itinerary-output .sib-slot-tip strong { color: var(--sib-canyon); }

.sib-swap-btn {
  font-size: 13px;
  color: var(--sib-muted);
  background: transparent;
  border: 1px solid transparent;
  padding: 4px 8px;
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
  cursor: pointer;
  font-family: inherit;
}
.sib-swap-btn:hover {
  background: rgba(184, 84, 45, 0.06);
  border-color: rgba(184, 84, 45, 0.2);
  color: var(--sib-canyon);
}

/* ─── Booking CTA ──────────────────────────────────────────────────────── */

.sib-book-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  background: var(--sib-canyon);
  color: white;
  border: none;
  border-radius: 0.5rem;
  padding: 0.5rem 0.875rem;
  font-size: 0.8rem;
  font-weight: 600;
  text-decoration: none;
  transition: background 0.15s ease;
}

.sib-book-btn:hover { background: #9c4424; }

/* Legacy .sib-viator-block kept for backward compat with any saved
   itineraries that might reach the old render path. Phase 2 output uses
   .sib-booking-card under .sib-bookings-grid. */
.sib-viator-block {
  margin-top: 1rem;
  padding: 1rem;
  background: rgba(212, 160, 86, 0.08);
  border-left: 3px solid var(--sib-gold);
  border-radius: 0.375rem;
}

/* ─── Curated Experiences section (v1.1.0) ────────────────────────────────
   Three live Viator embed cards ranked by relevance to the visitor's
   segment/interests/itinerary. Viator owns the card interior (price, image,
   book button); this stylesheet provides the wrapping chrome — heading,
   subline, grid, optional name+blurb above each widget. */

.sib-itinerary-output .sib-bookings {
  margin: 0;
  padding: 64px 0 0;
  border-top: 0;
}

.sib-itinerary-output .sib-bookings-header {
  max-width: 720px;
  margin: 0 auto 32px;
  text-align: left;
}

.sib-itinerary-output .sib-bookings-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 32px;
  line-height: 1.1;
  color: var(--sib-shadow);
  margin: 0 0 8px;
  font-weight: 600;
}

.sib-itinerary-output .sib-bookings-subhead {
  font-size: 16px;
  color: var(--sib-muted);
  margin: 0;
}

.sib-itinerary-output .sib-curated-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
}

@media (min-width: 768px) {
  .sib-itinerary-output .sib-curated-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1100px) {
  .sib-itinerary-output .sib-curated-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.sib-itinerary-output .sib-curated-card {
  background: white;
  border: 1px solid var(--sib-sand);
  border-radius: 12px;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  transition: border-color 0.2s ease;
}

.sib-itinerary-output .sib-curated-card:hover {
  border-color: rgba(184, 84, 45, 0.45);
}

.sib-itinerary-output .sib-curated-card-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 18px;
  line-height: 1.25;
  color: var(--sib-shadow);
  margin: 0;
  font-weight: 600;
}

.sib-itinerary-output .sib-curated-card-blurb {
  font-size: 14px;
  font-style: italic;
  color: var(--sib-muted);
  line-height: 1.45;
  margin: 0 0 4px;
}

/* Viator's live widget renders into this container. We don't enforce a
   height — Viator's widget sizes itself; we just give it a clean band of
   space and a subtle separator above it. */
.sib-itinerary-output .sib-curated-card-widget {
  margin-top: 4px;
  padding-top: 12px;
  border-top: 1px solid var(--sib-sand);
}

/* Print-only fallback: live widgets are JS embeds with no static markup,
   so they print blank. Hide the live widgets in print and show this
   simple text list instead. .sib-print-only is hidden on screen by
   default; the @media print rule below shows it. */
.sib-print-only { display: none; }

.sib-itinerary-output .sib-print-experiences {
  list-style: none;
  padding: 0;
  margin: 0 0 24px;
}

.sib-itinerary-output .sib-print-experiences li {
  font-size: 14px;
  line-height: 1.5;
  margin: 0 0 4px;
  color: #000;
}

.sib-itinerary-output .sib-print-experiences-heading {
  font-weight: 600;
  margin-bottom: 8px !important;
}

/* ─── Browse-by-category (tier 2, restored v1.1.1) ─────────────────────────
   Restored from v1.0.9. Editorial preview-card grid + a stack of live
   Viator category embed widgets, both keyed on the visitor's
   bookableCategories. Sits below the Curated Experiences grid inside the
   same .sib-bookings section, separated by .sib-bookings-tier-2-header. */

.sib-itinerary-output .sib-bookings-tier-2 {
  margin-top: 56px;
  padding-top: 40px;
  border-top: 1px solid var(--sib-sand);
}

.sib-itinerary-output .sib-bookings-tier-2-header {
  max-width: 720px;
  margin: 0 auto 24px;
  text-align: left;
}

.sib-itinerary-output .sib-bookings-tier-2-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 22px;
  line-height: 1.2;
  color: var(--sib-shadow);
  margin: 0 0 6px;
  font-weight: 600;
}

.sib-itinerary-output .sib-bookings-tier-2-subhead {
  font-size: 14px;
  color: var(--sib-muted);
  margin: 0;
}

.sib-itinerary-output .sib-bookings-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}

@media (min-width: 768px) {
  .sib-itinerary-output .sib-bookings-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1100px) {
  .sib-itinerary-output .sib-bookings-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.sib-itinerary-output .sib-booking-card {
  background: white;
  border: 1px solid var(--sib-sand);
  border-radius: 12px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: border-color 0.2s ease;
}

.sib-itinerary-output .sib-booking-card:hover {
  border-color: rgba(184, 84, 45, 0.45);
}

.sib-itinerary-output .sib-booking-card-image {
  width: 100%;
  aspect-ratio: 16 / 9;
  background: var(--sib-sand);
  overflow: hidden;
}

.sib-itinerary-output .sib-booking-card-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.sib-itinerary-output .sib-booking-card-image-fallback {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, var(--sib-sand) 0%, var(--sib-sand-2) 100%);
  color: var(--sib-canyon);
}

.sib-itinerary-output .sib-booking-card-body {
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1;
}

.sib-itinerary-output .sib-booking-card-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 20px;
  line-height: 1.2;
  color: var(--sib-shadow);
  margin: 0;
  font-weight: 600;
}

.sib-itinerary-output .sib-booking-card-desc {
  font-size: 14px;
  font-style: italic;
  color: var(--sib-muted);
  line-height: 1.5;
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.sib-itinerary-output .sib-booking-card-meta {
  font-size: 13px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--sib-canyon);
  margin-top: auto;
  padding-top: 8px;
}

.sib-itinerary-output .sib-booking-card-link {
  font-size: 16px;
  color: var(--sib-canyon);
  text-decoration: none;
  font-weight: 600;
  margin-top: 4px;
}

.sib-itinerary-output .sib-booking-card-link:hover {
  text-decoration: underline;
}

/* Live Viator category widgets — render below the editorial grid. */
.sib-itinerary-output .sib-bookings-widgets {
  margin-top: 56px;
  display: flex;
  flex-direction: column;
  gap: 48px;
}

.sib-itinerary-output .sib-bookings-widget {
  scroll-margin-top: 24px;
}

.sib-itinerary-output .sib-bookings-widget-eyebrow {
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: 13px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--sib-canyon);
  margin-bottom: 8px;
}

.sib-inline-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  color: var(--sib-canyon);
  font-size: 0.875rem;
  text-decoration: none;
}

.sib-inline-cta:hover { text-decoration: underline; }

/* ─── Weather strip ────────────────────────────────────────────────────── */

.sib-weather-strip {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0.75rem;
  background: rgba(250, 246, 237, 0.6);
  border-radius: 0.5rem;
  margin-bottom: 1.5rem;
}

.sib-weather-day {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0.5rem 0.75rem;
  gap: 0.25rem;
  font-size: 0.8rem;
  color: var(--sib-ink);
  min-width: 4rem;
}

/* ─── Map ──────────────────────────────────────────────────────────────── */

.sib-map-wrap {
  position: relative;
  width: 100%;
  /* Reduced from 24rem in phase 2 #6 — the overview map no longer dominates
     the page now that each day card has its own inline 'Today's stops'
     line for fast scanning. */
  height: 17rem;
  border-radius: 0.75rem;
  overflow: hidden;
  border: 1px solid rgba(43, 24, 16, 0.08);
  margin-bottom: 1.5rem;
  scroll-margin-top: 24px;
}

.sib-map-marker {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  background: var(--sib-canyon);
  color: white;
  font-weight: 700;
  font-size: 0.75rem;
  border-radius: 999px;
  box-shadow: 0 2px 6px rgba(0,0,0,0.2);
  border: 2px solid white;
}

/* Marker pulse — applied for ~1.1s when the user clicks an inline stop name
   in a day card. Scales up + glows canyon-red so the matching day's marker
   on the overview map is unmistakable. */
@keyframes sib-marker-pulse-kf {
  0%   { transform: scale(1);    box-shadow: 0 2px 6px rgba(0,0,0,0.2); }
  35%  { transform: scale(1.45); box-shadow: 0 0 0 8px rgba(184,84,45,0.45), 0 2px 6px rgba(0,0,0,0.2); }
  100% { transform: scale(1);    box-shadow: 0 2px 6px rgba(0,0,0,0.2); }
}
.sib-map-marker.sib-map-marker--pulse {
  animation: sib-marker-pulse-kf 1s ease-out;
}

/* ─── Today's stops inline list (phase 2 #6) ───────────────────────────────
   Single text line between the day's header and slot rows. Each stop name
   is a clickable button that scrolls to the overview map and pulses the
   matching day marker. Truncates to 5 stops + "and N more" beyond 6. */
.sib-itinerary-output .sib-stops-line {
  padding: 18px 0;
  border-top: 1px solid rgba(43, 24, 16, 0.06);
  border-bottom: 1px solid rgba(43, 24, 16, 0.06);
  margin-bottom: 24px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--sib-muted);
}
.sib-itinerary-output .sib-stops-label {
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--sib-canyon);
  font-weight: 600;
  margin-right: 6px;
}
.sib-itinerary-output .sib-stops-link {
  background: transparent;
  border: none;
  padding: 0;
  font: inherit;
  color: var(--sib-ink);
  cursor: pointer;
  border-bottom: 1px solid transparent;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.sib-itinerary-output .sib-stops-link:hover {
  color: var(--sib-canyon);
  border-bottom-color: var(--sib-canyon);
}
.sib-itinerary-output .sib-stops-sep { color: rgba(43, 24, 16, 0.35); }
.sib-itinerary-output .sib-stops-more { color: var(--sib-muted); font-style: italic; }

/* Mobile: stack the day-card "Today's stops:" line as a centered column —
   label on its own first line, then each stop name centered on its own
   line below. The inline separators (.sib-stops-sep, "·") are hidden in
   this layout because they'd become standalone "·" lines between stops.
   The "and N more" suffix stays visible and renders as the final centered
   line. Desktop base rules above are unchanged. */
@media (max-width: 640px) {
  .sib-itinerary-output .sib-stops-line {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
  }
  .sib-itinerary-output .sib-stops-sep {
    display: none;
  }
}

.sib-map-overlay-pill {
  position: absolute;
  top: 0.75rem;
  left: 0.75rem;
  padding: 0.375rem 0.75rem;
  background: white;
  border-radius: 999px;
  font-size: 0.75rem;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

/* ─── Action bar ───────────────────────────────────────────────────────── */

.sib-action-bar {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid rgba(43, 24, 16, 0.08);
}

/* Mobile: stack action buttons in a single full-width column. Desktop base
   rule (display:flex; flex-wrap:wrap; justify-content:center) is unchanged
   and continues to lay out the buttons inline on ≥641px. The width:100%
   on direct button children is required because the three secondary
   buttons have no inline `display` and would otherwise stay at intrinsic
   content width even under `align-items: stretch`. */
@media (max-width: 640px) {
  .sib-action-bar {
    flex-direction: column;
    align-items: stretch;
  }
  /* Full-width per the stack rationale, AND uniformly centered icon+label.
     Save/Book carry inline display:flex + align-items:center but no inline
     justify-content — the justify-content here reaches them. The three
     secondary buttons (Calendar/Print/Start Over) have no inline display
     declared, so display:flex here converts them to flex containers and
     justify-content:center centers their icon+label inside the now
     full-width button. All five buttons end up centered uniformly. */
  .sib-action-bar > button {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}

/* ─── Day-card fade-up (phase 2 #9) ────────────────────────────────────────
   IntersectionObserver in App.jsx adds .sib-fade-pending to each day card
   on mount, then removes it (and adds .sib-visible) when the card enters
   the viewport. CSS handles the actual transition. Slot rows within the
   card stagger by 60ms per index (max 240ms for the 4th row).

   Disabled wholesale under prefers-reduced-motion: reduce — the entire
   block sits inside a no-preference media query so reduced-motion users
   see cards in their default visible state immediately. */

@media (prefers-reduced-motion: no-preference) {
  .sib-itinerary-output .sib-day-card {
    transition: opacity 400ms ease-out, transform 400ms ease-out;
  }
  .sib-itinerary-output .sib-day-card.sib-fade-pending {
    opacity: 0;
    transform: translateY(8px);
  }
  .sib-itinerary-output .sib-day-card .sib-slot-row {
    transition: opacity 400ms ease-out, transform 400ms ease-out;
  }
  .sib-itinerary-output .sib-day-card.sib-fade-pending .sib-slot-row {
    opacity: 0;
    transform: translateY(8px);
  }
  .sib-itinerary-output .sib-day-card .sib-slot-row:nth-child(1) { transition-delay: 0ms; }
  .sib-itinerary-output .sib-day-card .sib-slot-row:nth-child(2) { transition-delay: 60ms; }
  .sib-itinerary-output .sib-day-card .sib-slot-row:nth-child(3) { transition-delay: 120ms; }
  .sib-itinerary-output .sib-day-card .sib-slot-row:nth-child(4) { transition-delay: 180ms; }
}

/* ─── Closing quote (phase 2 polish) ───────────────────────────────────────
   Solid canyon-red full-width block — no dot pattern, no gradients. Large
   editorial serif quote in italic white, with a small horizontal rule
   separating the attribution. Pulls the eye out of the itinerary content
   and provides a closing emotional beat. */

.sib-itinerary-output .sib-closing {
  margin: 64px -1.5rem 0;
  padding: 64px 1.5rem;
  background: var(--sib-canyon);
  color: white;
  text-align: center;
}

@media (min-width: 768px) {
  .sib-itinerary-output .sib-closing {
    padding: 96px 1.5rem;
  }
}

.sib-itinerary-output .sib-closing-quote {
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: 28px;
  line-height: 1.35;
  color: white;
  max-width: 720px;
  margin: 0 auto;
  padding: 0;
  quotes: none;
}

@media (min-width: 768px) {
  .sib-itinerary-output .sib-closing-quote {
    font-size: 40px;
  }
}

.sib-itinerary-output .sib-closing-rule {
  width: 60px;
  height: 1px;
  margin: 32px auto 0;
  background: rgba(255, 255, 255, 0.3);
}

.sib-itinerary-output .sib-closing-attribution {
  font-size: 12px;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.8);
  margin-top: 16px;
  font-weight: 500;
}

/* ─── Animations ───────────────────────────────────────────────────────── */

@keyframes sib-pulse {
  0%, 100% { opacity: 1; transform: translateY(0); }
  50%      { opacity: 0.5; transform: translateY(2px); }
}

.sib-pulse-dot { animation: sib-pulse 1.5s ease-in-out infinite; }

@keyframes sib-spin-kf { to { transform: rotate(360deg); } }
.sib-spin { animation: sib-spin-kf 0.8s linear infinite; }

@keyframes sib-fade-up-kf {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

.sib-fade-up { animation: sib-fade-up-kf 0.4s ease-out both; }

/* Personalization micro-moment between section 01 and 02 — one-line
   acknowledgement of the chosen segment that uses the segment's own tagline.
   Soft sand background with a canyon-red left accent so it reads as
   "we heard you" without competing with the form sections themselves. */
.sib-personalization {
  margin: -1rem 0 2rem;
  padding: 0.75rem 1rem;
  background: rgba(232, 212, 184, 0.35);
  border-left: 3px solid var(--sib-canyon);
  border-radius: 0.25rem;
  font-size: 0.95rem;
  line-height: 1.5;
}

/* One-shot pulse on click for any selectable (.sib-card/.sib-chip/.sib-seg-btn).
   Adds a brief scale + shadow flash for tactile feedback. Toggled in JSX by a
   click delegate that adds .sib-pulse-once for ~220ms.

   Default fill-mode (none) means the transform reverts to whatever rule
   matches after the animation ends — for unselected items: identity; for
   .sib-active cards: scale(1.02). The pulse momentarily overrides the
   persistent selected-state transform; the user reads it as "click felt"
   rather than "the selected state broke". */
@keyframes sib-pulse-once-kf {
  0%   { transform: scale(1);    box-shadow: 0 0 0 0 rgba(184, 84, 45, 0); }
  50%  { transform: scale(1.04); box-shadow: 0 0 0 6px rgba(184, 84, 45, 0.22); }
  100% { transform: scale(1);    box-shadow: 0 0 0 0 rgba(184, 84, 45, 0); }
}
.sib-pulse-once {
  animation: sib-pulse-once-kf 0.2s ease-out;
}

/* ─── GenerationProgress panel (phase 2 — v1.0.7) ──────────────────────────
   Centered cream panel that renders inline below the form during an active
   generation (loading=true) or after a failure (error truthy). Replaces the
   v1.0.6 LoadingState shimmer placeholder.

   Layout from top to bottom (spec § "WHAT THE LOADING STATE LOOKS LIKE"):
     - stepped message (italic muted)
     - 24px gap
     - progress bar (6px, max-width 400, centered)
     - 8px gap
     - elapsed timer (tabular-nums)
     - 16px gap
     - cancel link (appears at 15s, 44x44 tap target via invisible padding)

   Panel container: max-width 480 desktop / full-width minus 16px mobile,
   48/24 padding, cream background, 1px sand border, 16 radius.
   Mounts with a 300ms fade-in via .sib-fade-up; --exiting class triggers a
   300ms fade-out when parent unmounts. */

.sib-builder-root .sib-progress-panel {
  margin: 3rem auto 0;
  max-width: 480px;
  width: calc(100% - 16px);
  padding: 48px 24px;
  background: var(--sib-cream);
  border: 1px solid var(--sib-sand);
  border-radius: 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  opacity: 1;
  transform: translateY(0);
  transition: opacity 300ms ease, transform 300ms ease;
}
.sib-builder-root .sib-progress-panel--exiting {
  opacity: 0;
  transform: translateY(-4px);
}

.sib-builder-root .sib-progress-message {
  font-size: 16px;
  font-style: italic;
  color: var(--sib-muted);
  margin-bottom: 24px;
  line-height: 1.4;
  /* Re-fire the fade-up keyframe whenever the message changes (parent
     supplies a key prop to remount the element). */
  animation: sib-loading-msg-kf 0.45s ease-out both;
}

.sib-builder-root .sib-progress-bar {
  width: 100%;
  max-width: 400px;
  height: 6px;
  background: var(--sib-sand);
  /* The sand variable is already a warm low-contrast color; dim it a hair
     further so the canyon-red fill reads as the focal element. */
  background-color: rgba(232, 212, 184, 0.5);
  border-radius: 3px;
  overflow: hidden;
  margin-bottom: 8px;
}

.sib-builder-root .sib-progress-bar-fill {
  height: 100%;
  width: 0%;
  background: linear-gradient(
    90deg,
    var(--sib-canyon) 0%,
    var(--sib-canyon) 90%,
    var(--sib-terracotta) 100%
  );
  border-radius: 3px;
  transition: width 600ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* Reduced-motion fill: no smooth transition — width jumps in 25% steps. */
.sib-builder-root .sib-progress-bar-fill--stepped {
  transition: none;
}

.sib-builder-root .sib-progress-timer {
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--sib-canyon);
  opacity: 0.6;
  margin-bottom: 16px;
}

.sib-builder-root .sib-progress-cancel {
  font-size: 13px;
  color: var(--sib-canyon);
  background: transparent;
  border: none;
  /* 44x44px tap target (iOS minimum). Text is 13px; padding extends the
     hit area without changing visible size. */
  padding: 12px 16px;
  min-height: 44px;
  min-width: 44px;
  cursor: pointer;
  text-decoration: none;
  font-family: inherit;
  animation: sib-fade-in-300ms 300ms ease forwards;
  opacity: 0;
}
.sib-builder-root .sib-progress-cancel:hover,
.sib-builder-root .sib-progress-cancel:focus-visible {
  text-decoration: underline;
}
.sib-builder-root .sib-progress-cancel--instant {
  animation: none;
  opacity: 1;
}

@keyframes sib-fade-in-300ms {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Brief toast shown for 4s after a cancel lands. Sits inside the
   .sib-inline-cta block below the (now re-enabled) Compose button. */
.sib-builder-root .sib-cancel-toast {
  margin-top: 1rem;
  padding: 10px 16px;
  background: var(--sib-sand);
  color: var(--sib-shadow);
  border-radius: 999px;
  font-size: 13px;
  font-style: italic;
  animation: sib-fade-in-300ms 300ms ease forwards;
}

/* Error-state variant of the same panel. The icon + heading + body
   replace the message/bar/timer/cancel stack but reuse the panel chrome. */
.sib-builder-root .sib-progress-panel--error {
  text-align: center;
}
.sib-builder-root .sib-progress-error-icon {
  width: 40px;
  height: 40px;
  border-radius: 999px;
  background: rgba(184, 84, 45, 0.1);
  color: var(--sib-canyon);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 12px;
}
.sib-builder-root .sib-progress-error-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 22px;
  line-height: 1.2;
  color: var(--sib-shadow);
  margin: 0 0 8px;
  font-weight: 600;
}
.sib-builder-root .sib-progress-error-body {
  font-size: 16px;
  line-height: 1.5;
  color: var(--sib-ink);
  margin: 0 0 20px;
  max-width: 360px;
}
.sib-builder-root .sib-progress-error-actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: center;
}
.sib-builder-root .sib-progress-retry-btn {
  background: var(--sib-canyon);
  color: white;
  border: none;
  border-radius: 999px;
  padding: 10px 24px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  transition: background 200ms ease;
}
.sib-builder-root .sib-progress-retry-btn:hover {
  background: #9c4424;
}
.sib-builder-root .sib-progress-adjust-link {
  background: transparent;
  border: none;
  color: var(--sib-canyon);
  font-size: 13px;
  cursor: pointer;
  padding: 8px 12px;
  font-family: inherit;
}
.sib-builder-root .sib-progress-adjust-link:hover,
.sib-builder-root .sib-progress-adjust-link:focus-visible {
  text-decoration: underline;
}

@media (prefers-reduced-motion: reduce) {
  .sib-builder-root .sib-progress-panel { transition: none; }
  .sib-builder-root .sib-progress-message { animation: none; }
  .sib-builder-root .sib-progress-cancel { animation: none; opacity: 1; }
  .sib-builder-root .sib-cancel-toast { animation: none; }
  /* Belt-and-suspenders: if the user toggles the preference at runtime
     (after the panel mounted with reducedMotion=false in JS), the JS path
     won't catch it but this media query will still disable the bar's
     smooth fill. */
  .sib-builder-root .sib-progress-bar-fill { transition: none; }
}

/* Loading-message fade — keyed on loadingStep in App.jsx so React remounts
   the span on every advance and the keyframe fires from 0 each time. The
   transform is a tiny lift so the swap feels intentional rather than a hard
   text flip. */
@keyframes sib-loading-msg-kf {
  0%   { opacity: 0; transform: translateY(3px); }
  100% { opacity: 1; transform: translateY(0); }
}
.sib-loading-msg {
  animation: sib-loading-msg-kf 0.45s ease-out both;
  display: inline-block;
  font-style: italic;
  opacity: 0.85;
}

@keyframes sib-shimmer-kf {
  0%   { background-position: -200px 0; }
  100% { background-position: 200px 0; }
}

.sib-shimmer {
  background: linear-gradient(90deg,
    rgba(43, 24, 16, 0.05) 0%,
    rgba(43, 24, 16, 0.12) 50%,
    rgba(43, 24, 16, 0.05) 100%);
  background-size: 400px 100%;
  animation: sib-shimmer-kf 1.2s linear infinite;
  border-radius: 0.25rem;
}

.sib-loading-line {
  height: 0.875rem;
  background: linear-gradient(90deg,
    rgba(43, 24, 16, 0.05) 0%,
    rgba(43, 24, 16, 0.12) 50%,
    rgba(43, 24, 16, 0.05) 100%);
  background-size: 400px 100%;
  animation: sib-shimmer-kf 1.2s linear infinite;
  border-radius: 0.25rem;
  margin-bottom: 0.5rem;
}

/* ─── Grain texture (background decoration) ────────────────────────────── */

.sib-builder-root .sib-rock-svg { display: block; }

/* ─── Print (v1.1.0 — itinerary-only output) ──────────────────────────────
   Goal: window.print() / Save-as-PDF produces a clean document containing
   ONLY the generated itinerary — no builder form, no site chrome, no live
   Viator widgets. Strategy: visibility:hidden on everything, then re-show
   the .sib-itinerary-output subtree and lift it to top-left of the printed
   page via absolute positioning. The Curated Experiences live widgets
   (.sib-curated-card-widget) are hidden because they're JS-rendered embeds
   that print blank; .sib-print-experiences renders a plain text list of
   the 3 recommended names in their place. */

@media print {
  /* Generic helpers, kept for backwards compatibility. */
  .sib-no-print { display: none !important; }
  .sib-builder-root { background: white; }

  /* Hide everything outside the itinerary output. */
  body * { visibility: hidden; }
  .sib-itinerary-output,
  .sib-itinerary-output * { visibility: visible; }
  .sib-itinerary-output {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    margin: 0 !important;
    padding: 0 !important;
    background: white;
    color: #000;
  }

  /* Force readable typography. */
  .sib-itinerary-output,
  .sib-itinerary-output h1,
  .sib-itinerary-output h2,
  .sib-itinerary-output h3,
  .sib-itinerary-output p,
  .sib-itinerary-output li {
    color: #000 !important;
    background: white !important;
  }

  /* Hide the live Viator embeds in print (they render via JS, paper = blank). */
  .sib-curated-card-widget,
  .sib-curated-card {
    border: none !important;
    padding: 0 !important;
  }
  .sib-curated-card-widget { display: none !important; }

  /* v1.1.1 — the restored "Browse by category" tier (preview cards + live
     category widgets) is hidden in print. The whole .sib-bookings-tier-2
     wrapper carries .sib-no-print (handled by the generic rule above), but
     repeat explicit hides here as belt-and-suspenders in case the class
     ever moves: the live category widgets won't render on paper, and the
     preview cards' images + "View on Viator →" links don't add value to a
     printed itinerary. The Curated Experiences print fallback list at the
     top already references bookings, so nothing's lost. */
  .sib-bookings-tier-2,
  .sib-bookings-grid,
  .sib-bookings-widgets { display: none !important; }

  /* Show the print-only fallback list. */
  .sib-print-only { display: block !important; }

  /* Keep day cards together when possible. */
  .sib-day-card,
  .sib-curated-card,
  .sib-bookings-header,
  .sib-closing {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  /* Suppress the action bar in print (already has .sib-no-print but
     repeat for safety in case markup ever changes). */
  .sib-action-bar { display: none !important; }

  /* Don't print link URLs as suffixes — keeps the page tidy. */
  a[href]:after { content: none !important; }
}
