/* Generate Ideas — feature-flagged UI (see js/features/idea-pool/, issue #174) */

/* Unlike css/features/itinerary-agent.css's `.feature-itinerary-agent`
   convention, there's no single hidden-by-default class here: every element
   this feature touches is rebuilt fresh on each renderIdeasSidebar() call
   (js/itinerary.js), so a class-based reveal wouldn't survive the next
   render — the JS itself gates on window.__FEATURES__?.ideaPool before ever
   emitting this markup. This file is purely the strip's visual styling. */

/* The Ideas header's one accent, and the panel's only AI action. It carried
   `background: rgba(255,255,255,0.22); color: #fff` from the era when this
   header was a solid amber bar — after #447 turned the header neutral that
   is a white pill with a white glyph on a near-white surface, i.e. no
   affordance at all. A Trail Green Mist fill with a Trail Green glyph reads
   as a button on the neutral header and inverts to solid on hover. */
.ideas-sidebar-generate-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  padding: 0;
  border: none;
  border-radius: var(--radius-pill);
  background: var(--vn-teal-light);
  color: var(--vn-teal);
  font-size: var(--fs-md);
  line-height: 1;
  cursor: pointer;
  position: relative;
  transition: background var(--dur-feedback) var(--ease-out),
              color var(--dur-feedback) var(--ease-out);
}
.ideas-sidebar-generate-btn:hover {
  background: var(--vn-teal);
  color: var(--surface-2);
}
.ideas-sidebar-generate-btn:disabled {
  cursor: default;
  opacity: 0.7;
}
/* Issue #784 — a slow ambient "still working" signal on the header glyph
   itself, cheaper and calmer than layering anything onto the skeleton card
   below it. Answered in the prefers-reduced-motion block at the end of
   style.css (resolves to the glyph's normal, finished scale/opacity, never
   a hidden one). */
@keyframes idea-sparkle-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.55; transform: scale(1.15); }
}
.ideas-sidebar-generate-btn.loading .ti-sparkles {
  animation: idea-sparkle-pulse 1.4s var(--ease-out) infinite;
}
/* Reaches --tap-min without growing the visible chip past the header's own
   height — same convention as .stop-menu-btn (css/style.css). */
.ideas-sidebar-generate-btn::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: max(var(--tap-min), 100%);
  height: max(var(--tap-min), 100%);
  transform: translate(-50%, -50%);
}

#idea-suggestions-strip:empty { display: none; }

/* "Suggested for you" and "Your saved ideas" are the panel's two section
   headings and now share one treatment (see .ideas-saved-label) — they were
   a 12px bold sentence-case row and an 11px uppercase muted row sitting six
   pixels apart, which read as two unrelated kinds of thing rather than two
   sections of one list. */
.idea-suggestions-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  padding: var(--space-lg) var(--space-lg) var(--space-2xs);
  font-family: var(--df-mono);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--df-ink-soft);
}

.idea-suggestions-shuffle-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  flex-shrink: 0;
  border: 2px solid var(--df-ink);
  background: var(--df-panel);
  color: var(--vn-teal);
  border-radius: var(--radius-pill);
  padding: var(--space-xs) var(--space-lg);
  font-size: var(--fs-xs);
  font-family: inherit;
  cursor: pointer;
  position: relative;
  transition: background var(--dur-feedback) var(--ease-out),
              transform var(--dur-feedback) var(--ease-out);
}
.idea-suggestions-shuffle-btn:hover { background: var(--vn-teal-light); }
.idea-suggestions-shuffle-btn:active { transform: translateY(1px); }
/* 22px tall by design — it must not out-weigh the section label it sits on —
   so the hit area is expanded rather than the chip. */
.idea-suggestions-shuffle-btn::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: max(var(--tap-min), 100%);
  height: max(var(--tap-min), 100%);
  transform: translate(-50%, -50%);
}

.idea-suggestions-cards {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  padding: var(--space-md) var(--space-lg);
}

/* Issue #734 Part A — a one-line explainer under the "Suggestions" heading so
   it is unambiguous that these are not the user's own parked ideas. */
.idea-suggestions-subhead {
  padding: 0 var(--space-lg) var(--space-xs);
  font-size: var(--fs-xs);
  color: var(--df-ink-soft);
  line-height: 1.4;
}

/* Issue #734 Part A — a dashed border (vs the solid border on the user's own
   .idea-card stops) marks a suggestion as "not yours yet / a copy". The
   distinction has to survive into the Part F picker, where both appear side by
   side. */
.idea-suggestion-card {
  display: flex;
  gap: var(--space-md);
  border: 2px dashed var(--df-ink);
  border-radius: var(--df-radius-card);
  background: var(--df-panel);
  box-shadow: var(--df-press);
  overflow: hidden;
}

/* A real <img>, not a background-image div: it gets lazy loading, and
   `onerror="this.remove()"` (the convention renderStopCard()'s thumbnails
   already use) so a dead photo URL collapses the column instead of leaving a
   permanent 56px grey bar. The old inline `url('...')` also interpolated a
   URL that escHtml() does not escape apostrophes in. */
.idea-suggestion-photo {
  flex-shrink: 0;
  width: 56px;
  align-self: stretch;
  object-fit: cover;
  background: var(--df-panel);
}

.idea-suggestion-body {
  flex: 1;
  min-width: 0;
  padding: var(--space-md) var(--space-lg) var(--space-md) 0;
}
.idea-suggestion-photo + .idea-suggestion-body { padding-left: 0; }
.idea-suggestion-card:not(:has(.idea-suggestion-photo)) .idea-suggestion-body { padding-left: var(--space-lg); }

/* Badge + text column, the same shape a saved idea card uses one row below
   (.itin-stop-card.idea-card .stop-summary-row) — so the name and its city
   line share a left edge instead of the city starting back under the icon. */
.idea-suggestion-head {
  display: flex;
  align-items: center;
  gap: var(--space-lg);
}

/* Matches the 30px circular category badge every saved idea card in this same
   panel already uses (.itin-stop-card.idea-card .cat-pill, css/style.css) —
   the suggestion card used to show a bare monochrome ti-* glyph instead, so
   the Category Compass hue was missing on exactly the card that introduces a
   place, then appeared on the card it turned into once kept. */
.idea-suggestion-head .cat-pill {
  width: 30px;
  height: 30px;
  padding: 0;
  justify-content: center;
  border-radius: 50%;
  font-size: 15px;
  flex-shrink: 0;
}

/* Issue #734 Part A — .idea-type-badge base lives in css/style.css (shared
   with the Quick Idea side, which uses --vn-teal). Deliberately NOT another
   --vn-* brand hue here — every one of those is already the Category
   Compass's own color for a specific PLACE_TYPES category (coral=shopping,
   amber=food, etc.), and poaching one for an unrelated axis is exactly the
   leak #447 already fixed once on this same card's Keep/Dismiss buttons. A
   plain neutral (matching .cat-other's own "no category color" treatment)
   reads as "not a category signal" instead of accidentally implying one. */
.idea-type-badge-suggestion {
  background: var(--df-hair);
  color: var(--df-ink-soft);
}

.idea-suggestion-headtext {
  min-width: 0;
}

.idea-suggestion-name {
  display: block;
  font-size: var(--fs-md);
  font-weight: 600;
  line-height: 1.3;
}

.idea-suggestion-city {
  display: block;
  font-size: var(--fs-xs);
  color: var(--df-ink-soft);
  margin-top: 1px;
}

.idea-suggestion-blurb {
  font-size: var(--fs-sm);
  color: var(--df-ink-soft);
  margin-top: var(--space-xs);
  line-height: 1.35;
}

.idea-suggestion-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-size: var(--fs-xs);
  color: var(--vn-teal);
  margin-top: var(--space-xs);
}

.idea-suggestion-actions {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  margin-top: var(--space-lg);
}

/* Keep is the one action this whole feature exists to produce, so it says so
   and carries the solid fill; Dismiss is a quiet neutral icon beside it.
   They used to be two equally-heavy 28px squares — a green tick and a
   terracotta cross — which read as a symmetric accept/reject pair, and which
   also spent the *shopping* category hue (--vn-coral) on a piece of chrome,
   the same Category Compass leak #447 fixed on the header above. */
.idea-suggestion-keep {
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
  flex-shrink: 0;
  min-height: 32px;
  padding: 0 var(--space-xl);
  border: none;
  border-radius: var(--radius-pill);
  background: var(--vn-teal);
  color: var(--surface-2);
  font-family: inherit;
  font-size: var(--fs-sm);
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  position: relative;
  transition: background var(--dur-feedback) var(--ease-out),
              transform var(--dur-feedback) var(--ease-out);
}
.idea-suggestion-keep:hover { background: var(--vn-teal-mid); }
/* The system's press, at dense scale: the control nudges into the page on tap.
   Answered in this file's prefers-reduced-motion block. */
.idea-suggestion-keep:active { transform: translateY(1px); }

.idea-suggestion-dismiss {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 2px solid var(--df-ink);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--df-ink-soft);
  font-size: var(--fs-md);
  line-height: 1;
  cursor: pointer;
  position: relative;
  transition: background var(--dur-feedback) var(--ease-out),
              color var(--dur-feedback) var(--ease-out),
              transform var(--dur-feedback) var(--ease-out);
}
.idea-suggestion-dismiss:hover {
  background: var(--df-hair);
  color: var(--df-ink);
}
.idea-suggestion-dismiss:active { transform: translateY(1px); }

/* Expand the tappable area to --tap-min without growing the visible chip —
   same convention as .stop-menu-btn (css/style.css). */
.idea-suggestion-keep::before,
.idea-suggestion-dismiss::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: max(var(--tap-min), 100%);
  height: max(var(--tap-min), 100%);
  transform: translate(-50%, -50%);
}

/* Built from js/skeleton.js's shared shapes now (skeletonSuggestionCard())
   rather than a hand-rolled background-position shimmer that
   painted a flat 64px bar, animated a paint property instead of a transform,
   and — being its own @keyframes — was never answered in style.css's
   prefers-reduced-motion block. css/skeleton.css already covers all three. */
.idea-suggestion-skeleton {
  display: block;
  padding: var(--space-md) var(--space-lg);
}
.idea-suggestion-skeleton .skeleton-row { align-items: flex-start; }

/* Issue #784 — staged copy for a cold (AI-generation) draw, revealed after
   ~1.2s inside the same role="status"/aria-busy region as the skeleton
   above, so it's announced rather than a separate live region. */
.idea-suggestions-stage-copy {
  padding: 0 var(--space-lg) var(--space-md);
  font-size: var(--fs-xs);
  color: var(--df-ink-soft);
  text-align: center;
}

.idea-suggestions-empty {
  padding: var(--space-xl) var(--space-2xl);
  font-size: var(--fs-sm);
  color: var(--df-ink-soft);
  text-align: center;
}
/* The recovery action inside an empty/error state sits on its own line — it
   was inline after the sentence, where it read as part of the prose. */
.idea-suggestions-empty .btn-small {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  margin-top: var(--space-lg);
}

/* The reference treatment for both of the panel's section headings — see
   .idea-suggestions-header, which now matches it. The hairline is what
   separates the served suggestion from the list it will join once kept;
   without it the two sections ran together as one stack of cards. */
.ideas-saved-label {
  padding: var(--space-lg) var(--space-lg) var(--space-2xs);
  border-top: 2px solid var(--df-hair);
  font-family: var(--df-mono);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--df-ink-soft);
  text-transform: uppercase;
}

/* ── Motion ────────────────────────────────────────────────────────────────
   The suggestion strip's job: a place is struck onto the board, then filed
   into "Your ideas" or flicked away. The strike is the one authored beat here
   — everything else in the panel stays quiet state feedback. The `anim-in`
   class is emitted by renderIdeaSuggestionsStrip() (js/features/idea-pool/)
   only on a real draw or a real resolve, never a routine re-render, so a stop
   edit elsewhere on the tab can't replay it.

   Own reduced-motion block below: css/style.css loads BEFORE this file, so an
   `animation: none` for these same-specificity selectors there would lose the
   cascade to the rules above. (Same reason css/skeleton.css / css/landing.css
   each keep their own.) */

/* Focal moment — the struck suggestion. The card lands from just above with a
   faint overshoot, and its hard offset shadow snaps in from nothing as it
   seats: Departure Fever's press mechanic run backwards. No `both` fill — if
   the animation never runs the card is simply visible in its resting state. */
@keyframes idea-suggestion-strike {
  0%   { opacity: 0; transform: translateY(-10px) scale(0.965); box-shadow: 0 0 0 var(--df-ink); }
  68%  { opacity: 1; transform: translateY(0) scale(1.014); }
  100% { transform: translateY(0) scale(1); box-shadow: var(--df-press); }
}
.idea-suggestions-cards.anim-in .idea-suggestion-card {
  animation: idea-suggestion-strike 360ms var(--ease-out);
}

/* The empty / error / "saved" line rises in when the last suggestion clears,
   rather than snapping into place under the header. */
@keyframes idea-empty-rise {
  from { opacity: 0; transform: translateY(6px); }
}
.idea-suggestions-empty.anim-in {
  animation: idea-empty-rise var(--dur-state) var(--ease-out);
}

/* The staged "still writing…" copy on a cold draw fades up when it arrives
   (~1.2s in) and again on each check-in, so a new line reads as new. */
@keyframes idea-stage-copy-in {
  from { opacity: 0; transform: translateY(4px); }
}
.idea-suggestions-stage-copy {
  animation: idea-stage-copy-in var(--dur-state) var(--ease-out);
}

@media (prefers-reduced-motion: reduce) {
  /* Every entrance resolves to its finished, visible state — the cards and
     copy above are already rendered in their resting position, so dropping
     the animation loses only the travel. */
  .idea-suggestions-cards.anim-in .idea-suggestion-card,
  .idea-suggestions-empty.anim-in,
  .idea-suggestions-stage-copy {
    animation: none;
  }
  .idea-suggestion-keep:active,
  .idea-suggestion-dismiss:active,
  .idea-suggestions-shuffle-btn:active {
    transform: none;
  }
}
