.companion {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg-soft);
}

.companion-nav {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 24px;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
}

.companion-nav .wordmark {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 20px;
  color: var(--ink);
  text-decoration: none;
}

.nav-status {
  flex: 1;
  font-size: 13px;
  color: var(--muted);
}

.back-btn {
  display: flex;
  align-items: center;
  gap: 4px;
  border: none;
  background: none;
  color: var(--muted);
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  padding: 6px 4px;
}

.back-btn:hover {
  color: var(--ink);
}

.nav-link {
  color: var(--muted);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
}

.btn-logout {
  color: var(--ink);
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: 100px;
  padding: 7px 16px;
}

.btn-logout:hover {
  background: var(--border);
}

.companion-body {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  min-height: 0;
}

@media (min-width: 960px) {
  .companion-body {
    grid-template-columns: minmax(0, 1.3fr) 340px;
    height: calc(100vh - 57px);
    /* Without a cap, this grid stretches to the full viewport width on
       very wide screens -- but .msg's own max-width (720px) doesn't
       grow with it, so the message column stays a fixed size while the
       chat-pane around it keeps expanding, leaving large empty margins
       on both sides of the actual conversation. Capping and centering
       the whole layout keeps the entire chat/map/summary group at a
       sane, still-generous width instead.
       width:100% is required here, not just max-width+margin:auto --
       .companion-body is a flex item (of .companion, flex-direction:
       column), and horizontal auto margins on a flex item trigger
       flexbox's own auto-margin space absorption, which overrides the
       default stretch behavior and shrinks the element to its
       content-driven width instead of filling available space up to
       the cap. Confirmed directly: without width:100%, this rendered
       at 960px (the grid's own min-content size) even on a 2540px
       viewport, nowhere near the intended 1600px cap. */
    width: 100%;
    max-width: 1600px;
    margin: 0 auto;
  }

  /* Activated once an itinerary with at least one geocoded activity
     exists (see markItineraryVisible/initMapPane in companion.js) --
     not a permanent 3-column grid, since grid-template-columns reserves
     track space regardless of whether a child fills it, so an always-3-
     column definition would leave a dead gap while the map-pane sits
     hidden before any trip exists. Chat stays flexible, the map gets a
     reasonable middle range, trip summary keeps its existing fixed
     width -- matching the founder's requested left/middle/right order. */
  .companion-body.has-map {
    grid-template-columns: minmax(0, 1fr) minmax(360px, 560px) 340px;
  }
}

.chat-pane {
  display: flex;
  flex-direction: column;
  min-height: 60vh;
  background: var(--bg);
}

.messages {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 28px 20px 12px;
}

.empty-state {
  max-width: 580px;
  margin: 9vh auto 0;
  text-align: center;
  color: var(--muted);
}

.empty-title {
  font-family: var(--font-display);
  font-size: 26px;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink);
  margin: 0 0 8px;
}

.empty-copy {
  font-size: 14px;
  line-height: 1.5;
  margin: 0;
}

.empty-inspiration {
  display: flex;
  justify-content: center;
  gap: 12px;
  margin-top: 32px;
  flex-wrap: wrap;
}

.empty-inspiration-chip {
  width: 118px;
  border: none;
  background: none;
  padding: 0;
  cursor: pointer;
  border-radius: 16px;
  overflow: hidden;
  transition: transform 0.2s cubic-bezier(0.22, 1, 0.36, 1);
}

.empty-inspiration-chip:hover {
  transform: translateY(-4px) scale(1.02);
}

.empty-inspiration-chip img {
  width: 118px;
  height: 128px;
  object-fit: cover;
  display: block;
  border-radius: 16px;
  box-shadow: 0 4px 14px rgba(var(--shadow-ink), 0.16);
  transition: box-shadow 0.2s ease;
}

.empty-inspiration-chip:hover img {
  box-shadow: 0 12px 26px rgba(124, 58, 237, 0.3);
}

.empty-inspiration-chip span {
  display: block;
  margin-top: 8px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink);
}

.msg {
  max-width: 720px;
  margin: 0 auto 22px;
  display: flex;
  gap: 10px;
}

.msg.user {
  flex-direction: row-reverse;
}

.msg-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  font-size: 12px;
  font-weight: 700;
}

.msg.user .msg-avatar {
  background: var(--ink);
  color: #fff;
}

.msg.assistant .msg-avatar {
  background: linear-gradient(135deg, var(--accent-dark, var(--accent)) 0%, var(--accent) 100%);
  color: #fff;
}

.msg-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.msg.user .msg-body {
  align-items: flex-end;
}

.msg-role {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--muted);
  margin: 2px 0 6px;
}

.msg-text {
  display: inline-block;
  max-width: 88%;
  font-size: 15px;
  line-height: 1.6;
  white-space: pre-wrap;
  padding: 11px 16px;
  border-radius: 16px 16px 16px 5px;
  background: var(--bg-soft);
  color: var(--ink);
}

.msg.user .msg-text {
  border-radius: 16px 16px 5px 16px;
  /* Brand-violet gradient bubble -- your own messages carry the brand
     color, giving the conversation a livelier two-tone rhythm than the
     old flat navy. */
  background: linear-gradient(135deg, var(--accent-dark, var(--accent)) 0%, var(--accent) 100%);
  color: #fff;
}

.msg-text p {
  margin: 0 0 0.8em;
}

.msg-text p:last-child {
  margin-bottom: 0;
}

.msg-text ul {
  margin: 0 0 0.8em;
  padding-left: 1.2em;
}

.msg-text strong {
  font-weight: 650;
}

/* While tokens are streaming in (bubble has text): a blinking caret at
   the write-head, exactly as before. */
.msg.assistant.pending .msg-text:not(:empty)::after {
  content: "";
  display: inline-block;
  width: 7px;
  height: 14px;
  margin-left: 2px;
  background: var(--accent);
  animation: caret 1s steps(1) infinite;
  vertical-align: text-bottom;
}

/* Before the first token arrives (bubble still empty): the bubble
   itself becomes the "processing your question" animation, exactly
   where the answer is about to appear -- a lavender shimmer sweeping
   the bubble, a soft breathing glow, and pulsing brand-violet dots.
   Pure CSS on the same .pending state the JS already sets. */
.msg.assistant.pending .msg-text:empty {
  min-width: 150px;
  background: linear-gradient(110deg, var(--bg-soft) 25%, var(--accent-bg-soft) 45%, #EDE4FF 50%, var(--accent-bg-soft) 55%, var(--bg-soft) 75%);
  background-size: 220% 100%;
  animation: thinking-shimmer 1.6s linear infinite, thinking-glow 1.8s ease-in-out infinite;
}

@keyframes thinking-shimmer {
  0% { background-position: 110% 0; }
  100% { background-position: -110% 0; }
}

@keyframes thinking-glow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(124, 58, 237, 0.12); }
  50% { box-shadow: 0 0 0 6px rgba(124, 58, 237, 0); }
}

.msg.assistant.pending .msg-text:empty::after {
  content: "";
  display: inline-block;
  width: 28px;
  height: 8px;
  background:
    radial-gradient(circle 3px at 4px 50%, var(--accent) 98%, transparent),
    radial-gradient(circle 3px at 14px 50%, var(--accent) 98%, transparent),
    radial-gradient(circle 3px at 24px 50%, var(--accent) 98%, transparent);
  animation: typing-pulse 1.1s ease-in-out infinite;
  vertical-align: middle;
}

@keyframes typing-pulse {
  0%, 100% { opacity: 0.35; }
  50% { opacity: 1; }
}

@keyframes caret {
  50% { opacity: 0; }
}

.chat-composer {
  position: relative;
  margin: 0 16px 16px;
  display: flex;
  align-items: flex-end;
  gap: 8px;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 8px 8px 8px 14px;
}

/* While typing, the composer wears the same rotating violet-pink-amber
   ring as the itinerary-generation spinner -- one shared "Seenary is
   listening/working" color language. Two painted backgrounds: the flat
   fill clipped to padding-box, the spinning conic ring clipped to the
   border area. */
.chat-composer:focus-within {
  border: 1.5px solid transparent;
  background:
    linear-gradient(var(--bg-soft), var(--bg-soft)) padding-box,
    conic-gradient(from var(--ring-angle), #7C3AED, #EC4899, #FBBF24, #7C3AED) border-box;
  animation: ring-spin 3s linear infinite;
}

.chat-composer textarea {
  flex: 1;
  border: none;
  resize: none;
  font-family: var(--font-ui);
  font-size: 15px;
  line-height: 1.45;
  padding: 8px 0;
  max-height: 140px;
  background: transparent;
  color: var(--ink);
  outline: none;
}

.send-btn {
  width: 38px;
  height: 38px;
  border: none;
  border-radius: 11px;
  background: var(--accent);
  color: #fff;
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: background var(--duration-quick) var(--ease-warm), transform var(--duration-quick) var(--ease-warm);
}

.send-btn:hover:not(:disabled) {
  background: var(--accent-dark);
  transform: scale(1.05);
}

.send-btn:active:not(:disabled) {
  transform: scale(0.96);
}

.send-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.mic-btn {
  width: 38px;
  height: 38px;
  border: 1px solid var(--border);
  border-radius: 11px;
  background: var(--bg);
  color: var(--muted);
  display: grid;
  place-items: center;
  cursor: pointer;
  flex-shrink: 0;
  transition: background var(--duration-quick) var(--ease-warm), color var(--duration-quick) var(--ease-warm),
              border-color var(--duration-quick) var(--ease-warm);
}

/* .mic-btn's own display:grid above otherwise overrides the browser's
   default [hidden] { display:none } styling, since a class selector
   and this element's hidden-attribute selector carry the same
   specificity and the class rule would win on source order alone --
   confirmed directly: setting the hidden property via JS had no visual
   effect at all until this rule was added. Needed wherever an unsupported
   browser (no SpeechRecognition at all, e.g. Firefox) hides this button. */
.mic-btn[hidden] {
  display: none;
}

.mic-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.mic-btn.mic-listening {
  background: var(--danger);
  border-color: var(--danger);
  color: #fff;
  animation: mic-pulse 1.4s var(--ease-warm) infinite;
}

@keyframes mic-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(192, 57, 43, 0.4); }
  50% { box-shadow: 0 0 0 6px rgba(192, 57, 43, 0); }
}

.mic-message {
  position: absolute;
  bottom: calc(100% + 8px);
  right: 0;
  max-width: 260px;
  background: var(--ink);
  color: var(--on-ink);
  font-size: 12px;
  line-height: 1.4;
  padding: 8px 12px;
  border-radius: 8px;
  z-index: 5;
}

.map-pane {
  padding: 16px 0 16px 12px;
  min-height: 260px;
  /* Extends the light zone across the full column, not just the map
     box itself -- so it meets .flow-pane's dark background directly,
     with no white page-background gap breaking the continuity between
     the two. Reinforces "one visual workspace, two tonal zones" rather
     than two separate, disconnected panels. */
  background: var(--bg-soft);
}

.itinerary-map {
  width: 100%;
  height: 100%;
  min-height: 260px;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-soft);
}

.map-placeholder-message {
  height: 100%;
  min-height: 260px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 24px;
  box-sizing: border-box;
}

.map-placeholder-message p {
  margin: 0 0 8px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--muted);
  max-width: 260px;
}

.map-placeholder-message strong {
  color: var(--ink);
  font-size: 14px;
}

.map-info-window {
  font-family: var(--font-ui);
  max-width: 220px;
}

.map-info-window strong {
  display: block;
  font-size: 14px;
  color: var(--ink);
  margin-bottom: 4px;
}

.map-info-window p {
  font-size: 12.5px;
  color: var(--ink);
  margin: 0 0 6px;
  line-height: 1.4;
}

.map-info-meta {
  font-size: 11px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.flow-pane {
  background: var(--ink);
  color: var(--on-ink);
  padding: 28px 22px 32px;
  overflow-y: auto;
}

.flow-kicker {
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-size: 11px;
  font-weight: 700;
  /* --accent-bright, not --accent: the base violet is tuned for
     light surfaces and loses contrast on this dark navy pane. */
  color: var(--accent-bright, var(--accent));
  margin: 0 0 8px;
}

.flow-pane h2 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 24px;
  margin: 0 0 8px;
}

.flow-lede {
  color: var(--on-ink-muted);
  font-size: 13px;
  line-height: 1.5;
  margin: 0 0 24px;
}

.saved-trips {
  margin-bottom: 24px;
  padding-bottom: 20px;
  border-bottom: 1px solid rgba(250, 247, 252, 0.14);
}

.saved-trips-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.saved-trip-row {
  display: block;
  width: 100%;
  text-align: left;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 8px;
  padding: 9px 11px;
  cursor: pointer;
  font-family: var(--font-ui);
}

.saved-trip-row:hover {
  background: rgba(255, 255, 255, 0.12);
}

.saved-trip-destination {
  font-size: 13px;
  font-weight: 600;
  color: var(--on-ink);
}

.saved-trip-dates {
  font-size: 11px;
  color: var(--on-ink-muted);
  margin-top: 1px;
}

.error-banner {
  max-width: 720px;
  margin: 0 auto 16px;
  background: var(--danger-bg);
  color: var(--danger);
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 13px;
}

/* --- Trip summary panel (replaces the old fabricated activity log) --- */
.summary-bento {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 20px;
}

.bento-card {
  position: relative;
  background: rgba(255, 255, 255, 0.05);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 16px;
  overflow: hidden;
}

/* Destination: the hero tile. A photo layer (populated by JS once a
   real destination photo resolves) sits behind a radial glow and a
   bottom scrim so the text stays legible over any photo. */
.bento-destination {
  height: 128px;
  padding: 16px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}

.bento-destination-photo {
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, #6D5AC4 0%, #B8608A 55%, #D98F5C 100%);
  background-size: cover;
  background-position: center;
}

.bento-destination-photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(20, 33, 61, 0) 20%, rgba(20, 33, 61, 0.9) 100%);
}

.bento-destination::before {
  content: "";
  position: absolute;
  inset: -30%;
  background: radial-gradient(circle at 25% 20%, rgba(167, 139, 250, 0.4), transparent 55%);
  pointer-events: none;
  z-index: 1;
}

.bento-icon-row {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--on-ink-muted);
  margin-bottom: 4px;
}

.bento-value-lg {
  position: relative;
  z-index: 2;
  font-family: var(--font-display);
  font-size: 21px;
  font-weight: 600;
  color: #fff;
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

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

.bento-tile {
  flex: 1;
  padding: 14px 16px;
  min-width: 0;
}

.bento-label {
  display: block;
  font-size: 11.5px;
  color: var(--on-ink-muted);
  margin-bottom: 4px;
}

.bento-value {
  display: block;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  color: var(--on-ink);
  line-height: 1.25;
  overflow-wrap: break-word;
}

.bento-tags {
  padding: 16px;
}

.pill-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  border-radius: 100px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.14);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--on-ink);
  max-width: 100%;
}

.pill span:last-child {
  overflow-wrap: break-word;
}

.pill.pill-accent {
  background: rgba(167, 139, 250, 0.18);
  border-color: rgba(167, 139, 250, 0.35);
}

/* Flash applied by JS the moment extraction fills a summary field in --
   a brief warm glow that draws the eye to "the companion heard that",
   anchoring the conversation to the structured panel. */
.summary-value.summary-flash {
  border-radius: 6px;
  animation: summary-flash 1.2s var(--ease-warm);
}

@keyframes summary-flash {
  0% { background: rgba(167, 139, 250, 0.5); box-shadow: 0 0 0 4px rgba(167, 139, 250, 0.5); }
  100% { background: transparent; box-shadow: 0 0 0 4px transparent; }
}

.btn-generate {
  width: 100%;
  /* Violet-to-fuchsia sweep -- the single most important action in the
     panel gets the highest-energy treatment. */
  background: linear-gradient(120deg, var(--accent-dark, var(--accent)) 0%, var(--accent) 55%, var(--pop, var(--accent)) 130%);
  color: #fff;
  border: none;
  border-radius: 10px;
  padding: 12px;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  transition: transform var(--duration-quick) var(--ease-warm),
              box-shadow var(--duration-quick) var(--ease-warm),
              opacity 0.15s;
}

.btn-generate:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 8px 22px rgba(124, 58, 237, 0.4);
}

.btn-generate:active:not(:disabled) {
  transform: translateY(0);
}

.btn-add-to-trip,
.btn-start-over {
  width: 100%;
  margin-top: 8px;
  border-radius: 10px;
  padding: 10px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}

/* The constructive next step -- visually forward */
.btn-add-to-trip {
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.35);
  color: var(--on-ink);
}
.btn-add-to-trip:hover { background: rgba(255, 255, 255, 0.2); }

/* The reset -- quieter, but clearly available */
.btn-start-over {
  background: none;
  border: 1px solid rgba(255, 255, 255, 0.22);
  color: var(--on-ink);
  opacity: 0.85;
}
.btn-start-over:hover { background: rgba(255, 255, 255, 0.08); opacity: 1; }

.btn-generate:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.generate-hint {
  font-size: 12px;
  color: var(--on-ink-muted);
  margin: 10px 0 0;
  line-height: 1.5;
}

/* --- Result cards appended into the conversation (itinerary, food) --- */
.result-card-wrap {
  max-width: 720px;
  margin: 0 auto 20px;
}

/* The shared entrance animation's fill:both leaves a permanent
   translateY(0) transform on the wrapper after it finishes -- harmless
   visually, but a transformed ancestor can interfere with the sticky
   day-nav in some engines. `backwards` keeps the entrance identical
   while releasing the transform once the animation completes. */
.result-card-wrap.anim-fade-rise {
  animation-fill-mode: backwards;
}

/* ============================================================
   Itinerary "trip timeline" -- a full visual rework of the old
   row-list. Each day is a card headed by a tilted gradient day
   badge; inside it, activities hang off a vertical gradient
   timeline as floating cards anchored by emoji nodes ringed in
   their category color. Purely presentational: every functional
   hook the JS depends on (.activity-row + data attributes, child
   order in the DOM, control/handle classes) is unchanged --
   the visual reordering below is done with flexbox `order`.
   ============================================================ */
/* --- Trip hero: the itinerary's masthead --- */
.trip-hero {
  position: relative;
  overflow: hidden;
  border-radius: 18px;
  padding: 22px 24px;
  margin-bottom: 12px;
  background: linear-gradient(120deg, var(--accent-dark, var(--accent)) 0%, var(--accent) 55%, var(--pop, var(--accent)) 120%);
  color: #fff;
  box-shadow: 0 12px 30px rgba(124, 58, 237, 0.3);
}

/* Soft decorative glows -- pure CSS, no assets. */
.trip-hero::before,
.trip-hero::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
}

.trip-hero::before {
  width: 190px;
  height: 190px;
  right: -50px;
  top: -70px;
  background: radial-gradient(circle, rgba(255, 255, 255, 0.28) 0%, transparent 70%);
}

.trip-hero::after {
  width: 140px;
  height: 140px;
  left: 30%;
  bottom: -80px;
  background: radial-gradient(circle, rgba(251, 191, 36, 0.35) 0%, transparent 70%);
}

.trip-hero-kicker {
  margin: 0 0 2px;
  font-size: 10px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: rgba(255, 255, 255, 0.75);
}

.trip-hero-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 27px;
  font-weight: 800;
  letter-spacing: -0.015em;
  line-height: 1.15;
}

.trip-hero-meta {
  margin: 6px 0 0;
  font-size: 13px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.85);
}

/* Photo-backed hero: the destination's own image under the scrim
   (inline style set in companion.js), text shadowed for legibility,
   decorative glows off so the photograph reads clean. */
.trip-hero.has-photo {
  background-size: cover;
  background-position: center;
  min-height: 150px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  text-shadow: 0 1px 10px rgba(15, 12, 41, 0.5);
}

.trip-hero.has-photo::before,
.trip-hero.has-photo::after {
  content: none;
}


/* --- Day pill navigation: pinned while the itinerary scrolls, so a
   date is always one tap away no matter how deep in the plan you are.
   Sticky against .messages (the nearest scrolling ancestor). --- */
.day-nav {
  display: flex;
  flex-wrap: wrap; /* every day stays visible and clickable on long
                      trips -- a hidden-scrollbar single row left days
                      5+ unreachable */
  gap: 8px;
  margin-bottom: 14px;
  padding: 6px;
  position: sticky;
  top: 4px;
  z-index: 5;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-radius: 18px;
  box-shadow: 0 4px 16px rgba(var(--shadow-ink), 0.08);
}

.day-nav-pill {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1.5px solid var(--border);
  background: var(--bg);
  color: var(--ink);
  border-radius: 100px;
  padding: 6px 14px 6px 6px;
  font-family: var(--font-ui);
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
  transition: color var(--duration-quick) var(--ease-warm),
              border-color var(--duration-quick) var(--ease-warm),
              background var(--duration-quick) var(--ease-warm),
              box-shadow var(--duration-quick) var(--ease-warm),
              transform var(--duration-quick) var(--ease-warm);
}

/* Numbered lavender coin inside each pill, matching the destination
   chips in high-end trip planners. */
.day-nav-num {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--accent-bg-soft);
  color: var(--accent-ink);
  font-size: 12px;
  font-weight: 800;
}

.day-nav-pill:hover {
  border-color: var(--accent);
  transform: translateY(-1px);
}

.day-nav-pill.active {
  border-color: var(--accent);
  box-shadow: 0 4px 14px rgba(124, 58, 237, 0.22);
}

.day-nav-pill.active .day-nav-num {
  background: linear-gradient(135deg, var(--accent-dark, var(--accent)) 0%, var(--accent) 100%);
  color: #fff;
}

/* Bright and open: borderless white section, soft ambient shadow --
   the activity cards inside carry their own elevation. */
.day-card-group .day-card {
  background: var(--bg);
  border: none;
  border-radius: 20px;
  padding: 20px 20px 14px;
  margin-bottom: 16px;
  box-shadow: 0 6px 24px rgba(var(--shadow-ink), 0.07);
  transition: box-shadow var(--duration-quick) var(--ease-warm);
}

.day-card-group .day-card:hover {
  box-shadow: 0 12px 32px rgba(var(--shadow-ink), 0.1);
}

/* --- Day header: tilted gradient number badge + date + stop count --- */
.day-card-title {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 18px;
  color: var(--ink);
}

.day-num {
  width: 42px;
  height: 42px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--accent-bg-soft);
  color: var(--accent-ink);
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 800;
  transition: transform var(--duration-quick) var(--ease-warm),
              background var(--duration-quick) var(--ease-warm);
}

.day-card:hover .day-num {
  transform: scale(1.08);
}

.day-title-text {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.day-label {
  font-size: 10px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--accent);
}

.day-date {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 19px;
  letter-spacing: -0.01em;
}

.day-count {
  margin-left: auto;
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--accent-ink);
  background: var(--accent-bg-soft);
  border-radius: 100px;
  padding: 4px 10px;
  flex-shrink: 0;
}

/* --- Timeline spine behind the emoji nodes --- */
.activity-list {
  position: relative;
}

.activity-list::before {
  content: "";
  position: absolute;
  z-index: 0;
  left: 22px; /* centers on the 46px-wide node column */
  top: 18px;
  bottom: 18px;
  width: 3px;
  border-radius: 2px;
  background: linear-gradient(180deg, #A78BFA 0%, #F0ABFC 55%, #FDE68A 100%);
  opacity: 0.55;
}

.activity-row {
  position: relative;
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 0 0 12px;
  background: transparent;
  border: none;
  border-radius: 12px;
}

/* Drag can now start from anywhere on the row (see the pointerdown
   handler), not just the handle icon -- so the whole row needs
   touch-action:none while it's actually draggable, or a touch-initiated
   drag from outside the handle gets inconsistently hijacked by the
   browser's own scroll handling depending on exactly where it starts.
   Scoped via :has() to only the edit-mode state, where the handle
   actually exists in the DOM -- in the closed/view-only state there's
   nothing to drag, so scrolling by touch over a row stays unaffected. */
.activity-row:has(.activity-drag-handle) {
  touch-action: none;
}

/* Category color-coding: a genuinely scannable visual system built
   from data the app already has -- each category sets one custom
   property that the node ring, the card's left edge, and the sticker
   pill all read from. */
.activity-row[data-category="sightseeing"] { --cat: #7C3AED; }
.activity-row[data-category="food"] { --cat: #EA580C; }
.activity-row[data-category="culture"] { --cat: #BE185D; }
.activity-row[data-category="nature"] { --cat: #15803D; }
.activity-row[data-category="shopping"] { --cat: #B45309; }
.activity-row[data-category="rest"] { --cat: #0891B2; }
.activity-row[data-category="transport"] { --cat: #475569; }

.activity-row[data-category="sightseeing"] .activity-category { background: #F3EEFF; color: #6D28D9; }
.activity-row[data-category="food"] .activity-category { background: #FFF3EB; color: #C2410C; }
.activity-row[data-category="culture"] .activity-category { background: #FCE8F1; color: #9D174D; }
.activity-row[data-category="nature"] .activity-category { background: #EBF8EF; color: #15803D; }
.activity-row[data-category="shopping"] .activity-category { background: #FEF3E2; color: #92400E; }
.activity-row[data-category="rest"] .activity-category { background: #E7F8FB; color: #0E7490; }
.activity-row[data-category="transport"] .activity-category { background: var(--bg-soft); color: #334155; }

/* One-time entrance stagger, applied only on the itinerary's FIRST
   render (companion.js toggles .itinerary-enter off on every
   subsequent re-render) -- reorder clicks, edits, and save-indicator
   updates all re-render this container in place, and replaying an
   entrance animation on each of those would fight the drag
   interaction and read as flicker. */
.itinerary-enter .day-card {
  animation: fade-rise-in var(--duration-entrance) var(--ease-warm) both;
}

.itinerary-enter .activity-row,
.itinerary-enter .leg-row {
  animation: fade-rise-in var(--duration-entrance) var(--ease-warm) both;
}

/* --- Timeline node: emoji in a circle ringed with the category color,
   sitting on the spine, with the time-of-day label underneath --- */
.activity-time {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-align: center;
  color: var(--muted);
  width: 46px;
  flex-shrink: 0;
  position: relative;
  z-index: 1; /* nodes sit on top of the spine */
  order: 0;
}

/* Milestone node: a small, quiet dot on the spine -- deliberately
   simple and low-contrast (the earlier dark emoji coins read too loud
   against the bright cards). */
.activity-time-emoji {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--bg);
  border: 3px solid #D8CBF5;
  box-sizing: border-box;
  transition: border-color var(--duration-quick) var(--ease-warm);
}

.activity-row:hover .activity-time-emoji {
  border-color: var(--accent);
}

/* --- Bright floating activity card: colorful category tile on the
   left (playing the role of a photo thumbnail), content beside it --- */
.activity-body {
  flex: 1;
  min-width: 0;
  order: 1;
  display: flex;
  gap: 12px;
  align-items: flex-start;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 12px 14px;
  box-shadow: 0 3px 14px rgba(var(--shadow-ink), 0.07);
  transition: transform var(--duration-quick) var(--ease-warm),
              box-shadow var(--duration-quick) var(--ease-warm);
}

.activity-row:hover .activity-body {
  transform: translateY(-2px);
  box-shadow: 0 12px 26px rgba(var(--shadow-ink), 0.12);
}

.activity-tile {
  position: relative;
  width: 54px;
  height: 54px;
  flex-shrink: 0;
  border-radius: 14px;
  background-color: var(--accent-bg-soft);
  background-size: cover;
  background-position: center;
  transition: transform var(--duration-quick) var(--ease-warm);
}

.activity-tile-badge {
  position: absolute;
  right: -4px;
  bottom: -4px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--bg);
  border: 1.5px solid var(--border);
  display: grid;
  place-items: center;
  font-size: 12px;
  line-height: 1;
}

.activity-row:hover .activity-tile {
  transform: scale(1.06) rotate(-3deg);
}

/* Per-category tile tints -- same light family as the pills below. */
.activity-row[data-category="sightseeing"] .activity-tile { background: #F3EEFF; }
.activity-row[data-category="food"] .activity-tile { background: #FFF3EB; }
.activity-row[data-category="culture"] .activity-tile { background: #FCE8F1; }
.activity-row[data-category="nature"] .activity-tile { background: #EBF8EF; }
.activity-row[data-category="shopping"] .activity-tile { background: #FEF3E2; }
.activity-row[data-category="rest"] .activity-tile { background: #E7F8FB; }
.activity-row[data-category="transport"] .activity-tile { background: var(--bg-soft); }

.activity-info {
  flex: 1;
  min-width: 0;
}

/* Where the activity happens -- sits beside the category pill so every
   stop reads "what · where" at a glance. */
.activity-place {
  display: inline-block;
  font-size: 10.5px;
  font-weight: 700;
  color: var(--muted);
  background: var(--bg-soft);
  border-radius: 100px;
  padding: 3px 10px;
  margin: 6px 0 0 6px;
}

.activity-body {
  position: relative; /* anchors the hover hint */
}

/* --- Swipe gestures: right = keep, left = remove ---
   While a card is mid-swipe, transitions come off so it tracks the
   finger 1:1; releasing lets the normal transform transition spring
   it back. The Keep/Remove labels live on the ROW, behind the card,
   and fade in once the swipe passes its intent threshold. */
.activity-row.swiping .activity-body {
  transition: none;
  cursor: grabbing;
  /* Above the row's ::after "Remove" label (pseudo-elements paint over
     unpositioned children, but a z-indexed child wins) so the labels
     always read as revealed BENEATH the sliding card. */
  z-index: 1;
}

.activity-row.swiping::after {
  content: "✕ Remove";
  position: absolute;
  top: 50%;
  right: 14px;
  transform: translateY(-50%);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--danger);
  opacity: 0;
  transition: opacity 120ms ease;
  pointer-events: none;
}

.activity-row.swipe-left::after { opacity: 1; }

.activity-row.swipe-left .activity-body {
  box-shadow: 0 12px 26px rgba(192, 57, 43, 0.2);
}

/* Card flying out after a completed remove-swipe -- the actual splice
   happens on a matching ~280ms timer in companion.js. */
.activity-row.removing {
  pointer-events: none;
}

.activity-row.removing .activity-body {
  animation: swipe-out-left 280ms var(--ease-warm) forwards;
}

@keyframes swipe-out-left {
  to {
    transform: translateX(-130%) rotate(-3deg);
    opacity: 0;
  }
}

/* The handle stays in the DOM (it's how CSS and the touch-action rule
   detect edit mode, and screen readers can still find it) but is no
   longer drawn -- a gesture can start anywhere on the row, so the icon
   was pure clutter. */
.activity-drag-handle {
  display: none;
}

.activity-drag-ghost {
  position: fixed;
  z-index: 1000;
  pointer-events: none;
  background: var(--bg);
  border-radius: 8px;
  box-shadow: 0 12px 28px rgba(var(--shadow-ink), 0.28);
  opacity: 0.95;
  transform: rotate(-1.5deg);
}

.activity-row.dragging {
  opacity: 0.4;
}

/* A colored line above or below the row being hovered during a drag,
   directly answering "place above or below a given suggestion" --
   shown via box-shadow rather than border so it doesn't shift layout
   or fight with the row's own left border-color transition. */
.activity-row.drag-over-above {
  box-shadow: 0 -2px 0 0 var(--accent);
}

.activity-row.drag-over-below {
  box-shadow: 0 2px 0 0 var(--accent);
}

.activity-remove-zone {
  display: none;
  text-align: center;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  border: 1.5px dashed var(--border);
  border-radius: 8px;
  padding: 10px;
  margin-top: 8px;
}

.activity-remove-zone.active {
  display: block;
}

.activity-remove-zone.drag-over-active {
  border-color: var(--danger);
  color: var(--danger);
  background: var(--danger-bg);
}

/* A single joyful "+" coin instead of the old dull dashed bar. */
.add-activity-row {
  display: flex;
  justify-content: center;
  margin-top: 10px;
}

.btn-add-activity {
  width: 46px;
  height: 46px;
  border: none;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent-dark, var(--accent)) 0%, var(--accent) 55%, var(--pop, var(--accent)) 130%);
  color: #fff;
  font-size: 26px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  display: grid;
  place-items: center;
  box-shadow: 0 6px 16px rgba(124, 58, 237, 0.35);
  transition: transform var(--duration-quick) var(--ease-warm),
              box-shadow var(--duration-quick) var(--ease-warm);
}

.btn-add-activity:hover {
  transform: scale(1.12) rotate(90deg);
  box-shadow: 0 8px 22px rgba(236, 72, 153, 0.4);
}

.btn-add-activity:active {
  transform: scale(0.95);
}

/* The add/edit form wears the brand gradient as its border -- a small
   celebratory frame around "you're adding something to your trip". */
.activity-form {
  margin-top: 8px;
  padding: 14px;
  border: 2px solid transparent;
  border-radius: 16px;
  background:
    linear-gradient(var(--bg), var(--bg)) padding-box,
    linear-gradient(120deg, var(--accent-dark, var(--accent)) 0%, var(--accent) 55%, var(--pop, var(--accent)) 100%) border-box;
  box-shadow: 0 10px 30px rgba(124, 58, 237, 0.18);
  display: flex;
  flex-direction: column;
  gap: 10px;
  animation: fade-rise-in var(--duration-entrance) var(--ease-warm) both;
  /* Positioned so it paints above the absolutely-positioned timeline
     spine when a form replaces a row inside .activity-list. */
  position: relative;
  z-index: 1;
}

.activity-form-row {
  display: flex;
  gap: 8px;
}

.activity-form-row select,
.activity-form-title,
.activity-form-location,
.activity-form-desc {
  border: 1.5px solid var(--border);
  border-radius: 10px;
  padding: 9px 11px;
  font-size: 13px;
  font-family: var(--font-ui);
  background: var(--bg-soft);
  color: var(--ink);
  width: 100%;
  transition: border-color var(--duration-quick) var(--ease-warm),
              background var(--duration-quick) var(--ease-warm),
              box-shadow var(--duration-quick) var(--ease-warm);
}

.activity-form-row select:focus,
.activity-form-title:focus,
.activity-form-location:focus,
.activity-form-desc:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--bg);
  box-shadow: 0 0 0 3px var(--accent-bg-soft);
}

.activity-form-desc {
  resize: vertical;
  min-height: 44px;
}

.activity-form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.btn-form-cancel,
.btn-form-save {
  padding: 7px 14px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  border: none;
}

.btn-form-cancel {
  background: none;
  color: var(--muted);
}

.btn-form-cancel:hover {
  color: var(--ink);
}

.btn-form-save {
  background: linear-gradient(120deg, var(--accent-dark, var(--accent)) 0%, var(--accent) 55%, var(--pop, var(--accent)) 130%);
  color: #fff;
  box-shadow: 0 4px 12px rgba(124, 58, 237, 0.3);
  transition: transform var(--duration-quick) var(--ease-warm),
              box-shadow var(--duration-quick) var(--ease-warm);
}

.btn-form-save:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(236, 72, 153, 0.35);
}

.itinerary-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  margin-bottom: 14px;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: 10px;
}

.itinerary-save-indicator {
  font-size: 12px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 6px;
}

.itinerary-save-indicator.idle {
  color: var(--success, #1a7f4b);
}

.itinerary-save-indicator.offline {
  color: #FBBF24;
}

.itinerary-save-indicator.error {
  color: var(--danger, #c0392b);
}

.itinerary-save-indicator.saving {
  color: var(--muted);
}

.btn-itinerary-toggle {
  flex-shrink: 0;
  padding: 6px 14px;
  border-radius: 100px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--ink);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

.btn-itinerary-toggle:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.activity-title {
  font-weight: 600;
  font-size: 14px;
  color: var(--ink);
}

.activity-desc {
  font-size: 13px;
  color: var(--muted);
  margin-top: 2px;
}

/* Sticker-style category pill -- bolder, rounder, and it wiggles a
   little when you hover its row. */
.activity-category {
  display: inline-block;
  font-size: 10px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  background: var(--bg-soft);
  border-radius: 100px;
  padding: 3px 10px;
  margin-top: 6px;
  transition: transform var(--duration-quick) var(--ease-warm);
}

.activity-row:hover .activity-category {
  transform: rotate(-2deg) scale(1.06);
}

.kids-form {
  max-width: 340px;
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 16px;
  background: var(--bg);
  box-shadow: 0 8px 28px rgba(124, 58, 237, 0.1);
}

.kids-form-header {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 15px;
  color: var(--ink);
  margin-bottom: 10px;
}

.kids-count-row {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 16px;
}

.kids-count-btn {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--ink);
  font-size: 16px;
  cursor: pointer;
}

.kids-count-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.kids-count-value {
  font-size: 18px;
  font-weight: 700;
  color: var(--ink);
  min-width: 16px;
  text-align: center;
}

.kids-form-subheader {
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  margin-bottom: 8px;
}

.kids-ages-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 16px;
}

.kids-age-input {
  width: 62px;
  padding: 9px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 14px;
  text-align: center;
  font-family: var(--font-ui);
}

.kids-age-input:focus {
  outline: none;
  border-color: var(--accent);
}

.kids-form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.date-picker {
  max-width: 340px;
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  background: var(--bg);
  box-shadow: 0 8px 28px rgba(124, 58, 237, 0.14);
  animation: date-picker-in 0.2s ease;
}

@keyframes date-picker-in {
  from { opacity: 0; transform: scale(0.97) translateY(4px); }
  to { opacity: 1; transform: scale(1) translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .date-picker { animation: none; }
}

.date-picker-header {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 14px 14px 12px;
  background: linear-gradient(120deg, var(--accent-dark, var(--accent)) 0%, var(--accent) 100%);
  color: #fff;
}

.date-picker-month {
  flex: 1;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 15px;
}

.date-picker-nav,
.date-picker-close {
  width: 26px;
  height: 26px;
  border-radius: 8px;
  border: none;
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
  cursor: pointer;
  font-size: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.date-picker-nav:hover:not(:disabled),
.date-picker-close:hover {
  background: rgba(255, 255, 255, 0.3);
}

.date-picker-nav:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}

.date-picker-close {
  font-size: 16px;
  line-height: 1;
}

.date-picker-weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  padding: 10px 10px 0;
  gap: 2px;
}

.date-picker-weekdays span {
  text-align: center;
  font-size: 10px;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
}

.date-picker-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
  padding: 4px 10px 10px;
}

.date-picker-cell {
  aspect-ratio: 1;
  border: none;
  background: none;
  border-radius: 8px;
  font-size: 13px;
  color: var(--ink);
  cursor: pointer;
  transition: background 0.12s, color 0.12s, transform 0.08s;
}

.date-picker-cell:hover:not(:disabled):not(.selected) {
  background: var(--accent-bg-soft);
}

.date-picker-cell.disabled {
  color: var(--border);
  cursor: not-allowed;
}

.date-picker-cell.today {
  font-weight: 700;
  box-shadow: inset 0 0 0 1.5px var(--accent);
}

.date-picker-cell.in-range {
  background: var(--accent-bg-soft);
  border-radius: 0;
}

.date-picker-cell.selected {
  background: var(--accent);
  color: #fff;
  font-weight: 700;
  transform: scale(1.05);
}

.date-picker-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 14px 14px;
  border-top: 1px solid var(--border);
}

.date-picker-range-text {
  font-size: 12px;
  color: var(--muted);
  font-weight: 600;
}

.date-picker-confirm {
  flex-shrink: 0;
}

.date-picker-confirm:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.grounding-note {
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 12px;
}

.quick-replies {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 4px 0 20px 44px; /* aligns under the assistant avatar column */
  animation: quick-replies-in 0.25s ease;
}

@keyframes quick-replies-in {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .quick-replies { animation: none; }
}

.quick-reply-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 16px;
  border-radius: 100px;
  border: 1.5px solid var(--accent-bg-soft);
  background: var(--accent-bg-soft);
  color: var(--accent-ink);
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.15s, transform 0.1s, box-shadow 0.15s;
  /* Staggered per-chip entrance -- the options arrive one after another
     like dealt cards, rather than the whole row popping in at once. */
  animation: fade-rise-in var(--duration-entrance) var(--ease-warm) both;
}

.quick-reply-chip:nth-child(2) { animation-delay: 60ms; }
.quick-reply-chip:nth-child(3) { animation-delay: 120ms; }
.quick-reply-chip:nth-child(4) { animation-delay: 180ms; }
.quick-reply-chip:nth-child(5) { animation-delay: 240ms; }

.quick-reply-chip:hover {
  border-color: var(--accent);
  box-shadow: 0 2px 10px rgba(124, 58, 237, 0.18);
  transform: translateY(-1px);
}

.quick-reply-chip:active {
  transform: translateY(0);
}

.quick-reply-emoji {
  font-size: 15px;
}

/* The "More ideas" reveal chip -- visually an option, but dashed so it
   reads as "there's more here", not as an answer itself. */
.quick-reply-chip.quick-reply-more {
  background: transparent;
  border-style: dashed;
  border-color: var(--accent);
  color: var(--accent);
}

.quick-reply-chip.quick-reply-more:hover {
  background: var(--accent-bg-soft);
}

.food-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
  margin-bottom: 10px;
}

.food-card-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}

.food-name {
  font-weight: 600;
  font-size: 14px;
  color: var(--ink);
}

.food-meta {
  font-size: 12px;
  color: var(--muted);
  margin-top: 3px;
}

.open-badge {
  font-size: 11px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 100px;
  flex-shrink: 0;
}

.open-badge.open {
  background: var(--success-bg);
  color: var(--success);
}

.open-badge.closed {
  background: var(--bg-soft);
  color: var(--muted);
}

.ai-summary {
  font-size: 13px;
  font-style: italic;
  color: var(--ink);
  background: var(--bg-soft);
  border-radius: 8px;
  padding: 10px 14px;
  margin-top: 12px;
}

.info-banner {
  background: var(--bg-soft);
  border: 1px dashed var(--border);
  color: var(--muted);
  border-radius: 8px;
  padding: 10px 14px;
  font-size: 13px;
}

/* --- Live itinerary-generation progress card --- */
.generating-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 16px 18px;
  box-shadow: 0 8px 28px rgba(124, 58, 237, 0.12);
}

.generating-top {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 14px;
}

/* Circular progress ring: a conic-gradient arc, sharp-cut at the current
   percentage, masked into a ring so the center stays open for the live
   number. --progress (0-100) is set on the wrapper from JS on every tick
   and inherits down to .generating-ring-track, whose gradient math
   (percent * 3.6deg, since 100% = 360deg) recomputes on every paint --
   that's what makes the fill visibly sweep as the value climbs. The
   percentage label is a SIBLING of the masked track, not its child --
   a mask clips its element's own rendered content including children,
   which would hide text sitting in the ring's transparent center hole. */
.generating-ring {
  --progress: 0;
  position: relative;
  width: 52px;
  height: 52px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.generating-ring-track {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background:
    conic-gradient(from -90deg,
      #7C3AED 0deg,
      #EC4899 calc(var(--progress) * 3.6deg),
      var(--bg-soft) calc(var(--progress) * 3.6deg),
      var(--bg-soft) 360deg);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 6px), #000 calc(100% - 5px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 6px), #000 calc(100% - 5px));
}

.generating-ring-value {
  position: relative;
  z-index: 1;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.generating-ring-percent {
  font-size: 10px;
  font-weight: 700;
  margin-left: 1px;
  opacity: 0.7;
}

/* The completion payoff: a quick, warm glow the instant the real result
   lands, so reaching 100% reads as an arrival, not just a stop. */
.generating-ring-complete {
  animation: generating-ring-pop 0.42s var(--ease-warm);
}

@keyframes generating-ring-pop {
  0% { transform: scale(1); filter: drop-shadow(0 0 0 rgba(124, 58, 237, 0)); }
  40% { transform: scale(1.12); filter: drop-shadow(0 0 10px rgba(124, 58, 237, 0.45)); }
  100% { transform: scale(1); filter: drop-shadow(0 0 0 rgba(124, 58, 237, 0)); }
}

.generating-text {
  flex: 1;
  min-width: 0;
}

.generating-title {
  margin: 0 0 2px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 16px;
  color: var(--ink);
}

.generating-status {
  margin: 0;
  font-size: 13px;
  color: var(--muted);
}

/* Determinate progress: width tracks the same --progress value driving
   the ring above, so the two indicators tell one consistent story
   instead of a real number next to a decorative, unrelated animation. */
.generating-bar {
  height: 6px;
  border-radius: 100px;
  background: var(--bg-soft);
  overflow: hidden;
  position: relative;
}

.generating-bar-fill {
  height: 100%;
  width: 0%;
  border-radius: 100px;
  background: linear-gradient(90deg, var(--accent) 0%, var(--pop, var(--accent)) 100%);
  transition: width 0.15s linear;
}

.spinner {
  display: inline-block;
  width: 12px;
  height: 12px;
  border: 2px solid var(--border);
  border-top-color: var(--ink);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
  vertical-align: middle;
  margin-right: 6px;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* Placed after the base .chat-pane/.flow-pane rules above on purpose --
   CSS source order decides ties when specificity is equal, and these
   need to win over the base rules on desktop. min-height: 60vh on
   .chat-pane (needed on mobile, where the layout is a single stacked
   column and the whole page scrolling normally is correct) was fighting
   .companion-body's fixed desktop height: a grid item's default
   min-height is "auto" (grow to fit content), and an explicit 60vh
   minimum made that worse, so .chat-pane -- and the whole page with it --
   grew taller than the viewport as a conversation got longer, instead of
   only .messages scrolling internally within a properly constrained
   height. That's what made the trip summary drift out of view. */
@media (min-width: 960px) {
  .chat-pane {
    /* min-height:0 alone wasn't enough -- confirmed by direct
       measurement: getComputedStyle still reported .chat-pane growing
       to its content's height (970px) despite min-height genuinely
       being 0px. A grid item's default stretch-to-row behavior can
       still lose to content-based sizing in practice; an explicit
       height matching the row removes the ambiguity entirely. */
    min-height: 0;
    height: calc(100vh - 57px);
  }
  .flow-pane {
    /* Sticky as a robust safety net on top of the height fix above --
       keeps the trip summary visually anchored even if some future
       change reintroduces a sizing edge case. */
    position: sticky;
    top: 0;
    height: calc(100vh - 57px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .spinner { animation: none; }
}

/* ============================================================
   NEON TICKET WALLET -- the founder-chosen F+E direction: the
   itinerary lives in a dark neon "wallet" container while each stop
   is a bright boarding-pass ticket (kicker, tear line, stub with
   WHERE/TYPE fields, barcode). Scoped under .day-card-group so the
   chat around it keeps the light theme. Poppins carries the rounded
   travel-app voice; sizes are up across the board for readability.
   ============================================================ */
.day-card-group {
  background: #141225;
  border-radius: 26px;
  padding: 18px 18px 20px;
  font-family: "Poppins", var(--font-ui);
  box-shadow: 0 18px 50px rgba(20, 18, 37, 0.35);
}

.day-card-group .itinerary-toolbar {
  background: #1F1C38;
  border-color: #322C58;
}

.day-card-group .itinerary-save-indicator.idle { color: #4ADE80; }
.day-card-group .itinerary-save-indicator.error { color: #F87171; }
.day-card-group .itinerary-save-indicator.saving { color: #B9B3D8; }

.day-card-group .btn-itinerary-toggle {
  background: #1F1C38;
  border-color: #443C77;
  color: #EDEAFB;
}

.day-card-group .btn-itinerary-toggle:hover {
  border-color: #A78BFA;
  color: #fff;
}

.day-card-group .grounding-note { color: #8F87B8; }

.day-card-group .day-nav {
  background: rgba(20, 18, 37, 0.92);
}

.day-card-group .day-nav-pill {
  background: #1F1C38;
  border-color: #322C58;
  color: #B9B3D8;
}

.day-card-group .day-nav-pill:hover { border-color: #A78BFA; color: #fff; }

.day-card-group .day-nav-pill.active {
  border-color: #A78BFA;
  color: #fff;
  box-shadow: 0 0 18px rgba(167, 139, 250, 0.4);
}

.day-card-group .day-nav-num { background: #322C58; color: #C4B5FD; }

.day-card-group .day-nav-pill.active .day-nav-num {
  background: linear-gradient(135deg, var(--accent-dark), var(--accent));
  color: #fff;
}

.day-card-group .day-card {
  background: #1F1C38;
  border: 1px solid #322C58;
  box-shadow: none;
}

.day-card-group .day-num {
  background: linear-gradient(135deg, var(--accent-dark), var(--accent) 60%, var(--pop) 140%);
  color: #fff;
  box-shadow: 0 6px 18px rgba(124, 58, 237, 0.45);
}

.day-card-group .day-label { color: #A78BFA; }
.day-card-group .day-date { color: #fff; font-size: 21px; }

.day-card-group .day-count {
  background: rgba(251, 191, 36, 0.14);
  color: #FBBF24;
}

.day-card-group .activity-list::before {
  opacity: 0.7;
  box-shadow: 0 0 12px rgba(167, 139, 250, 0.5);
}

.day-card-group .activity-time { color: #8F87B8; font-size: 10px; }

.day-card-group .activity-time-emoji {
  background: #141225;
  border-color: #EC4899;
  box-shadow: 0 0 12px rgba(236, 72, 153, 0.6);
}

/* --- The ticket itself: bright card on the dark wallet --- */
.day-card-group .activity-body {
  display: block; /* ticket sections stack; the old flex row is gone */
  background: var(--bg);
  border: none;
  border-radius: 18px;
  padding: 16px 18px 12px;
  box-shadow: 0 10px 26px rgba(10, 8, 24, 0.45);
}

.ticket-main {
  display: flex;
  gap: 14px;
  align-items: flex-start;
}

.ticket-kicker {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #8A82A6;
  margin-bottom: 3px;
}

.day-card-group .activity-title {
  font-family: "Poppins", var(--font-ui);
  font-size: 18.5px;
  font-weight: 700;
  line-height: 1.3;
}

.day-card-group .activity-desc {
  font-size: 15px;
  line-height: 1.62;
  margin-top: 4px;
}

/* Perforated tear line with wallet-colored notches at both ends. */
.ticket-rip {
  border-top: 2px dashed var(--border);
  margin: 13px -18px 0;
  position: relative;
}

.ticket-rip::before,
.ticket-rip::after {
  content: "";
  position: absolute;
  top: -11px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #1F1C38; /* matches the day section behind the ticket */
}

.ticket-rip::before { left: -10px; }
.ticket-rip::after { right: -10px; }

.ticket-stub {
  display: flex;
  align-items: center;
  gap: 18px;
  padding-top: 11px;
  flex-wrap: wrap;
}

.ticket-field {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #8A82A6;
}

.ticket-field b {
  display: block;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
  margin-top: 3px;
}

.ticket-barcode {
  height: 30px;
  width: 84px;
  border-radius: 2px;
  opacity: 0.85;
  background: repeating-linear-gradient(90deg, #14213D 0 2px, transparent 2px 5px, #14213D 5px 6px, transparent 6px 9px);
}

.nearby-btn {
  margin-left: auto;
  border: none;
  border-radius: 100px;
  padding: 8px 16px;
  background: linear-gradient(120deg, #FBBF24, #EC4899);
  color: #fff;
  font-family: "Poppins", var(--font-ui);
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(251, 191, 36, 0.35);
  transition: transform var(--duration-quick) var(--ease-warm),
              box-shadow var(--duration-quick) var(--ease-warm);
}

.nearby-btn:hover {
  transform: translateY(-1px) scale(1.04);
  box-shadow: 0 6px 18px rgba(236, 72, 153, 0.45);
}

/* --- Travel leg between stops: the big distance + time the founder
   asked for, sitting in the rail's whitespace. --- */
.leg-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 4px 0 14px;
  position: relative;
  z-index: 1;
}

.leg-col {
  min-width: 96px;
  text-align: center;
}

.leg-num {
  font-family: "Poppins", var(--font-ui);
  font-size: 26px;
  font-weight: 700;
  line-height: 1.05;
  background: linear-gradient(120deg, #C4B5FD, #EC4899, #FBBF24);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.leg-mode {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: #8F87B8;
  margin-top: 2px;
}

.leg-line {
  flex: 1;
  border-bottom: 2px dashed #443C77;
  margin-right: 6px;
}

/* --- Nearby walkthrough popover: neon-framed, auto-fading --- */
.nearby-pop {
  position: relative;
  z-index: 2;
  margin: 4px 0 14px 58px;
  max-width: 540px;
  border: 2px solid transparent;
  border-radius: 18px;
  background:
    linear-gradient(#1F1C38, #1F1C38) padding-box,
    linear-gradient(120deg, #7C3AED, #EC4899, #FBBF24) border-box;
  padding: 16px 18px 12px;
  color: #EDEAFB;
  box-shadow: 0 14px 40px rgba(124, 58, 237, 0.4);
  animation: fade-rise-in var(--duration-entrance) var(--ease-warm) both;
  transition: opacity 360ms ease, transform 360ms ease;
}

.nearby-pop.closing {
  opacity: 0;
  transform: translateY(6px);
}

.nearby-pop-close {
  position: absolute;
  top: 10px;
  right: 12px;
  width: 26px;
  height: 26px;
  border: none;
  border-radius: 50%;
  background: #322C58;
  color: #C4B5FD;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  display: grid;
  place-items: center;
}

.nearby-pop h4 {
  font-family: "Poppins", var(--font-ui);
  font-size: 16px;
  font-weight: 700;
  color: #FBBF24;
  margin: 0 24px 8px 0;
}

.nearby-step {
  display: flex;
  gap: 12px;
  align-items: baseline;
  padding: 7px 0;
  font-size: 14.5px;
  line-height: 1.5;
}

.nearby-step-num {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 1.5px solid #EC4899;
  color: #EC4899;
  font-size: 12px;
  font-weight: 700;
  display: grid;
  place-items: center;
  align-self: center;
}

.nearby-live-meta {
  margin-left: auto;
  font-size: 12px;
  color: #8F87B8;
  white-space: nowrap;
  padding-left: 10px;
}

.nearby-note {
  font-size: 13.5px;
  color: #B9B3D8;
  margin: 4px 0;
}

.nearby-note a { color: #C4B5FD; }

.nearby-live-btn {
  width: 100%;
  margin-top: 8px;
  border: 1.5px dashed #443C77;
  border-radius: 12px;
  background: none;
  color: #C4B5FD;
  font-family: "Poppins", var(--font-ui);
  font-size: 13px;
  font-weight: 700;
  padding: 9px;
  cursor: pointer;
}

.nearby-live-btn:hover:not(:disabled) { border-color: #A78BFA; color: #fff; }
.nearby-live-btn:disabled { opacity: 0.6; cursor: wait; }

.nearby-fadebar {
  height: 4px;
  border-radius: 10px;
  background: #322C58;
  margin-top: 10px;
  overflow: hidden;
}

.nearby-fadebar i {
  display: block;
  height: 100%;
  border-radius: 10px;
  background: linear-gradient(90deg, #7C3AED, #EC4899, #FBBF24);
  animation: nearby-countdown 10s linear forwards;
}

@keyframes nearby-countdown {
  from { width: 100%; }
  to { width: 0; }
}

/* Dark-wallet tuning for remaining shared pieces. */
.day-card-group .activity-remove-zone {
  border-color: #443C77;
  color: #8F87B8;
}

/* --- Post-review refinements --- */

/* Swipe coaching appears over a card only while THAT card is hovered,
   in a reserved band above it (the band's padding is always there so
   the hint fades in without shifting layout). Scoped to edit mode via
   the hidden handle. The band swaps to the ✕ Remove reveal mid-swipe. */
.activity-row:has(.activity-drag-handle) {
  padding-top: 16px;
}

.activity-row:has(.activity-drag-handle):not(.swiping):not(.removing)::after {
  content: "← swipe left to remove · double-click to change time";
  position: absolute;
  top: 0;
  left: 58px; /* aligned over the card, clear of the timeline column */
  right: 8px;
  text-align: center;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: #B4ABD1;
  opacity: 0;
  transition: opacity 0.18s ease;
  pointer-events: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.activity-row:has(.activity-drag-handle):not(.swiping):not(.removing):hover::after {
  opacity: 1;
}

/* Jumping to a day via the sticky pills used to tuck the day header
   under the pill bar -- scroll-margin keeps it clear. */
.day-card {
  scroll-margin-top: 76px;
}

/* Nearby steps: text flexes, the add action sits at the end. */
.nearby-step-text {
  flex: 1;
  min-width: 0;
}

.nearby-live-meta {
  margin-left: 0;
}

.nearby-add-btn {
  flex-shrink: 0;
  align-self: center;
  border: 1.5px solid #443C77;
  border-radius: 100px;
  background: none;
  color: #C4B5FD;
  font-family: "Poppins", var(--font-ui);
  font-size: 12px;
  font-weight: 700;
  padding: 4px 12px;
  cursor: pointer;
  transition: border-color var(--duration-quick) var(--ease-warm),
              color var(--duration-quick) var(--ease-warm),
              transform var(--duration-quick) var(--ease-warm);
}

.nearby-add-btn:hover:not(:disabled) {
  border-color: #A78BFA;
  color: #fff;
  transform: scale(1.06);
}

.nearby-add-btn:disabled {
  cursor: default;
  color: #4ADE80;
  border-color: rgba(74, 222, 128, 0.35);
  opacity: 0.9;
}

/* --- + add panel (suggest-near-the-last-stop flow) --- */
.nearby-pop.panel {
  margin-left: 0;
  max-width: none;
}

.addpanel-note {
  margin-top: -2px;
}

.addpanel-times {
  display: flex;
  gap: 8px;
  margin: 2px 0 10px;
}

.addpanel-time {
  border: 1.5px solid #443C77;
  border-radius: 100px;
  background: none;
  color: #B9B3D8;
  font-family: "Poppins", var(--font-ui);
  font-size: 13px;
  font-weight: 700;
  padding: 7px 16px;
  cursor: pointer;
  transition: border-color var(--duration-quick) var(--ease-warm),
              color var(--duration-quick) var(--ease-warm),
              background var(--duration-quick) var(--ease-warm);
}

.addpanel-time:hover {
  border-color: #A78BFA;
  color: #fff;
}

.addpanel-time.active {
  background: linear-gradient(120deg, var(--accent-dark), var(--accent));
  border-color: transparent;
  color: #fff;
  box-shadow: 0 4px 14px rgba(124, 58, 237, 0.4);
}

/* --- Discoverability fixes --- */

/* View-only mode announces itself instead of silently hiding tools. */
.itinerary-viewonly-note {
  font-size: 12.5px;
  font-weight: 600;
  color: #B9B3D8;
  margin-right: auto;
}

.day-card-group .btn-itinerary-toggle {
  white-space: nowrap;
}

/* Full day: the + stays, disabled, with the reason next to it. */
.btn-add-activity:disabled {
  opacity: 0.35;
  cursor: not-allowed;
  transform: none !important;
  box-shadow: none;
}

.day-full-note {
  font-size: 12.5px;
  font-weight: 600;
  color: #8F87B8;
  margin-left: 12px;
  align-self: center;
}

/* Freshly inserted stop: amber glow so WHERE it landed is unmissable. */
.activity-row.just-added .activity-body {
  animation: just-added-glow 2.4s var(--ease-warm);
}

@keyframes just-added-glow {
  0%, 55% {
    box-shadow: 0 0 0 3px #FBBF24, 0 12px 32px rgba(251, 191, 36, 0.4);
  }
  100% {
    box-shadow: 0 10px 26px rgba(10, 8, 24, 0.45);
  }
}

/* Touch screens have no hover: the swipe hint would otherwise never
   appear, so it stays visible there while editing is open. */
@media (hover: none) {
  .activity-row:has(.activity-drag-handle):not(.swiping):not(.removing)::after {
    opacity: 1;
  }
}

/* --- Nearby category chips (Food / Activities / Sightseeing) --- */
.nearby-cats {
  display: flex;
  gap: 8px;
  margin: 10px 0 4px;
  flex-wrap: wrap;
}

.nearby-cat-btn {
  border: 1.5px dashed #443C77;
  border-radius: 100px;
  background: none;
  color: #C4B5FD;
  font-family: "Poppins", var(--font-ui);
  font-size: 12.5px;
  font-weight: 700;
  padding: 7px 14px;
  cursor: pointer;
  transition: border-color var(--duration-quick) var(--ease-warm),
              color var(--duration-quick) var(--ease-warm),
              background var(--duration-quick) var(--ease-warm);
}

.nearby-cat-btn:hover {
  border-color: #A78BFA;
  color: #fff;
}

.nearby-cat-btn.active {
  border-style: solid;
  background: linear-gradient(120deg, var(--accent-dark), var(--accent));
  border-color: transparent;
  color: #fff;
  box-shadow: 0 4px 14px rgba(124, 58, 237, 0.4);
}

/* --- Post-generation "save your bookings" offer card --- */
.vault-offer {
  background: linear-gradient(135deg, #1E1936, #16132B);
  color: #EDEAFB;
  border: 1.5px solid #7C3AED;
  border-radius: 16px;
  padding: 18px 20px;
}

.vault-offer h4 {
  margin: 0 0 6px;
  font-family: "Poppins", var(--font-ui, sans-serif);
  font-size: 16px;
}

.vault-offer p {
  margin: 0 0 12px;
  color: #B4ABD1;
  font-size: 13.5px;
  line-height: 1.55;
}

.vault-offer a { color: #A78BFA; font-weight: 700; }

.vault-offer-actions { display: flex; gap: 10px; flex-wrap: wrap; }

.vault-offer-add {
  background: #7C3AED;
  color: #fff;
  border: none;
  border-radius: 100px;
  padding: 10px 18px;
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
}

.vault-offer-later {
  background: transparent;
  color: #A78BFA;
  border: 1.5px dashed #443C77;
  border-radius: 100px;
  padding: 9px 16px;
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
}


/* --- Booking-file attach (+) button & drag-and-drop --- */
.attach-btn {
  width: 42px;
  height: 42px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--bg);
  color: var(--muted);
  display: grid;
  place-items: center;
  flex-shrink: 0;
  cursor: pointer;
  transition: background var(--duration-quick) var(--ease-warm), color var(--duration-quick) var(--ease-warm),
              border-color var(--duration-quick) var(--ease-warm), transform var(--duration-quick) var(--ease-warm);
}
.attach-btn:hover:not(:disabled) { color: var(--accent); border-color: var(--accent); transform: scale(1.05); }
.attach-btn:disabled { opacity: 0.5; cursor: progress; }
.attach-btn.attach-busy svg { animation: attach-spin 0.9s linear infinite; }
@keyframes attach-spin { to { transform: rotate(180deg); } }

.chat-composer.drag-over {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 122, 89, 0.22);
}

.attach-status {
  margin: 6px 16px 10px;
  font-size: 0.82rem;
  color: var(--muted);
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 8px 12px;
}
.attach-status.attach-status-error { color: #b3402a; border-color: rgba(255, 122, 89, 0.5); }

/* --- Chat-pane-wide booking drop zone --- */
.chat-pane { position: relative; }
.booking-drop-overlay {
  position: absolute;
  inset: 0;
  z-index: 40;
  display: grid;
  place-items: center;
  background: linear-gradient(160deg, rgba(220, 252, 231, 0.92), rgba(187, 247, 208, 0.92));
  border: 3px dashed #22c55e;
  border-radius: 16px;
  margin: 8px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 160ms ease;
}
.booking-drag-active .booking-drop-overlay { opacity: 1; }
.booking-drop-overlay-inner {
  text-align: center;
  color: #14532d;
  display: grid;
  justify-items: center;
  gap: 8px;
  padding: 24px;
}
.booking-drop-overlay-inner svg { color: #16a34a; animation: drop-bounce 1.1s ease-in-out infinite; }
.booking-drop-overlay-inner strong { font-size: 1.15rem; }
.booking-drop-overlay-inner span { font-size: 0.83rem; opacity: 0.85; }
@keyframes drop-bounce { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(7px); } }
.booking-drag-active .chat-composer { border-color: #22c55e; box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.28); }
