/* Generator layout on Concept 3 tokens (R5).
 *
 * Loaded after concept3-brand.css on planning and day trip ONLY, so nothing
 * here can reach the rest of the site. Every selector is namespaced gen-,
 * pablo- or sticker-choice, which keeps it clear of the 24 class names
 * tests/design-brand-bridge.spec.js pins, and a test enforces that prefix.
 *
 * R5 ships the state layer, the trip card and Pablo while the existing
 * two-step wizard still drives the form, so this file styles the new pieces
 * and does not lay out the questions yet. The skins (R6, R7) bring that.
 */

/* The trip card: what you have asked for so far, taking shape as you answer. */
.gen-trip-card {
  border: 3px solid var(--dark-green, #1A3009);
  border-radius: 18px;
  background: var(--white, #fff);
  box-shadow: 6px 6px 0 var(--dark-green, #1A3009);
  overflow: hidden;
}

.gen-card-media {
  position: relative;
  aspect-ratio: 16 / 9;
  background: linear-gradient(135deg, var(--pineapple-yellow, #F4D35E), var(--leaf-green, #2D5016));
}

.gen-card-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* 22 of the 183 safety countries have no curated photograph at all, and no
   amount of hosting fixes that: it needs pictures that do not exist yet. So
   they get a DESIGNED card rather than an absence. Founder direction
   2026-09-12 was that the image must work every time and must never degrade to
   a bare gradient; a flag and a country name on the brand's own treatment is a
   finished state that happens not to be a photograph, and it renders from a
   string and an emoji, so it cannot fail. */
.gen-card-brandmark {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  text-align: center;
  padding: 12px;
}

.gen-card-flag {
  font-size: 38px;
  line-height: 1;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.25));
}

.gen-card-brandmark-name {
  font-family: var(--ff-display, "Poppins", sans-serif);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.02em;
  color: var(--white, #fff);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
}

/* Attribution sits on the photo it belongs to. 150 of the 162 curated images
   are CC licensed and require credit wherever they appear, so this is a
   licence obligation rather than a styling choice and must stay legible. */
.gen-card-credit {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  margin: 0;
  padding: 4px 8px;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: 10px;
  line-height: 1.35;
}

.gen-card-credit a { color: #fff; text-decoration: underline; }

.gen-card-body { padding: 14px 16px 16px; }

.gen-card-kicker {
  display: block;
  font-family: var(--ff-display, "Poppins", sans-serif);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--coral-text, #A8461A);
}

.gen-card-dest {
  margin: 2px 0 10px;
  font-family: var(--ff-display, "Poppins", sans-serif);
  font-size: 1.25rem;
  font-weight: 800;
  line-height: 1.2;
  color: var(--dark-green, #1A3009);
}

/* A description list, so the pairs are related in the accessibility tree
   rather than being two visually adjacent spans. */
.gen-card-facts {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px 12px;
  margin: 0 0 12px;
  font-size: 12.5px;
}

.gen-card-facts dt {
  font-weight: 700;
  color: var(--black-coral, #5D6676);
}

.gen-card-facts dd {
  margin: 0;
  color: var(--charcoal, #2D2D2D);
}

.gen-card-meter { display: flex; align-items: center; gap: 8px; }

/* A real <progress>: announced by screen readers and meaningful with CSS off,
   which a div with a width is not. */
.gen-card-progress {
  flex: 1 1 auto;
  height: 8px;
  border: 2px solid var(--dark-green, #1A3009);
  border-radius: 999px;
  background: var(--light-yellow, #FFF1BF);
  overflow: hidden;
  appearance: none;
  -webkit-appearance: none;
}

.gen-card-progress::-webkit-progress-bar { background: var(--light-yellow, #FFF1BF); }
.gen-card-progress::-webkit-progress-value { background: var(--leaf-green, #2D5016); }
.gen-card-progress::-moz-progress-bar { background: var(--leaf-green, #2D5016); }

.gen-card-meter-text {
  flex: 0 0 auto;
  font-size: 11px;
  font-weight: 600;
  color: var(--black-coral, #5D6676);
}

/* Pablo. The mood is a CSS variant on one image rather than six files: the
   same face, tilted, which cannot 404 and costs nothing extra to load. */
.gen-pablo { display: flex; align-items: flex-start; gap: 10px; }

.gen-pablo .pablo-face {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border: 2px solid var(--dark-green, #1A3009);
  border-radius: 50%;
  object-fit: cover;
  transition: transform 0.2s ease;
}

.gen-pablo[data-mood="happy"] .pablo-face { transform: rotate(-6deg); }
.gen-pablo[data-mood="thinking"] .pablo-face { transform: rotate(4deg) scale(0.97); }
.gen-pablo[data-mood="cheer"] .pablo-face { transform: rotate(-10deg) scale(1.04); }
.gen-pablo[data-mood="oops"] .pablo-face { transform: rotate(8deg); filter: saturate(0.7); }

/* Motion is opt-in, per the site's reduced-motion stance. */
@media (prefers-reduced-motion: reduce) {
  .gen-pablo .pablo-face { transition: none; }
}

.gen-pablo .pablo-bubble {
  margin: 0;
  padding: 8px 12px;
  border: 2px solid var(--dark-green, #1A3009);
  border-radius: 14px;
  background: var(--light-yellow, #FFF1BF);
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--charcoal, #2D2D2D);
}

.gen-pablo .pablo-bubble:empty { display: none; }

/* Nothing to say yet means nothing on screen. Hiding only the empty bubble left
   the face behind, orphaned under the trip card. See the note in
   generator-pablo.js's say(). */
.gen-pablo:not([data-spoken]) { display: none; }

/* At phone width the card goes full bleed above the form rather than beside
   it. The sticky column and the bottom sheet arrive with the skins in R6/R7,
   which is what actually needs them. */
@media (max-width: 860px) {
  .gen-trip-card { box-shadow: 4px 4px 0 var(--dark-green, #1A3009); }
  .gen-card-dest { font-size: 1.1rem; }
}

/* ---------------------------------------------------------------------------
 * R6: the guided skin. One question per screen.
 *
 * WHY THIS BLOCK IS LONG. The first cut of R6 shipped the behaviour (step
 * order, validation, the shim) and no layout, on the assumption that the
 * questions would inherit something reasonable. They inherited the opposite.
 * Each step is a <section>, and legacy style.css carries a bare
 * `section { padding: 80px 0 }` rule, so every question rendered with 80px of
 * dead space above and below it and ZERO padding at the sides: the input ran
 * edge to edge, the heading had no margin, and the questions that used to sit
 * inside .form-section (padding: 30px 35px) lost the only horizontal padding
 * they ever had. On top of that .generator-form still wore the pre-Concept-3
 * treatment, a white fill with `box-shadow: 0 10px 40px rgba(0,0,0,.08)` and a
 * 15px radius, which is the soft blurred look the sticker system replaced.
 * Read together on a real screen it looked like an unstyled form floating on
 * the page. Founder review 2026-09-13 called it compressed and hard to look at,
 * which is what it was.
 *
 * So the guided skin styles its own frame rather than inheriting one: the form
 * becomes the sticker card, the step resets the inherited section padding, and
 * the native controls inside the stage get the 3px border treatment the rest
 * of the site already uses. Everything is scoped under #generator-stage, so
 * nothing here can reach a page that does not host the generator.
 * ------------------------------------------------------------------------ */

#generator-stage {
  --g-pad: 30px;
  --g-hairline: rgba(26, 48, 9, 0.22);
}

/* THE CARD. The question flow lives inside the existing <form>, so the form is
   the sticker rather than a wrapper added around it: one less box, and the
   card cannot drift out of sync with what is actually being submitted.
   `overflow: visible` is a deliberate override of the legacy `hidden`, which
   clipped both the hard shadow and any focus ring on an edge control. */
#generator-stage .generator-form {
  padding: var(--g-pad);
  background: var(--cream, #FFFDF5);
  border: 3px solid var(--dark-green, #1A3009);
  border-radius: 22px;
  box-shadow: 6px 6px 0 var(--dark-green, #1A3009);
  overflow: visible;
}

/* Reset the inherited `section { padding: 80px 0 }`. This single line is the
   difference between a question and a question lost in a field of whitespace. */
#generator-stage .g-step {
  padding: 0;
  margin: 0;
}

/* Steps have wildly different heights (a date field against the interests
   grid). Without a floor the card snaps shorter and taller on every Next,
   which reads as the page breaking rather than as progress. The floor is set
   just above the tallest SHORT question rather than at the tallest question
   overall: high enough to stop the jitter, low enough that a one-field screen
   does not read as a mostly empty card. */
.g-host {
  min-height: 240px;
}

/* THE PROGRESS RAIL. Above the question, inside the card, full width. */
.g-rail {
  display: flex;
  gap: 5px;
  list-style: none;
  margin: 0 0 22px;
  padding: 0;
}

.g-rail-dot {
  flex: 1 1 auto;
  height: 8px;
  border-radius: 999px;
  background: var(--white, #fff);
  border: 2px solid var(--dark-green, #1A3009);
  transition: background 0.2s ease;
}

.g-rail-dot.done { background: var(--leaf-green, #2D5016); }
.g-rail-dot.current { background: var(--pineapple-yellow, #F4D35E); }

@media (prefers-reduced-motion: reduce) {
  .g-rail-dot { transition: none; }
}

/* "Load My Preferences" lives in the chrome, under the rail, so a returning
   traveler is offered their saved profile before they start answering rather
   than after. Right-aligned and quiet: it is an accelerator, not the next
   thing to do. */
.g-prefs {
  display: flex;
  justify-content: flex-end;
  margin: 0 0 14px;
}

/* The button is `position: absolute; right: 0` in style.css, which was right
   when it sat in a relatively positioned section heading and wrong the moment
   it moved: it rendered nowhere, leaving a bar-shaped hole. The heading it
   travels inside comes along too, so both are put back in normal flow. */
.g-prefs .form-section-title,
.g-prefs .load-preferences-btn {
  position: static;
  margin: 0;
  /* Not padding-left:0. This control is a filled pill, and zeroing the left
     padding put the icon 1px from its own border. Flush-left alignment with
     the section heading is not worth a button that looks broken. */
}

/* "Question 3 of 14". A one-question-per-screen flow hides how much is left,
   which is the standard complaint about this pattern; the rail shows shape and
   this shows the number. */
.g-step-count {
  display: block;
  font-family: var(--ff-display, "Poppins", sans-serif);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--coral-text, #A8461A);
  margin: 0 0 6px;
}

.g-step-title {
  font-family: var(--ff-display, "Poppins", sans-serif);
  /* Scales with the viewport so the heading is not the same 21px on a phone
     and a 27in display. */
  font-size: clamp(1.4rem, 1.15rem + 1vw, 2rem);
  font-weight: 800;
  line-height: 1.2;
  color: var(--dark-green, #1A3009);
  margin: 0 0 8px;
}

/* NO RING ON THE HEADING, and this is an accessibility decision rather than a
   concession against one.
 *
 * Focus still moves here on every step change: a screen reader has to hear the
 * question before the traveler is dropped into the answer, and that is the only
 * reason the heading is focusable at all. What is removed is the VISIBLE ring.
 *
 * WCAG 2.4.7 Focus Visible is about keyboard-operable controls. This heading is
 * tabindex="-1": it is not in the tab order, it does nothing when activated,
 * and the next Tab goes past it to the input. Drawing a 3px box around it told
 * a sighted traveler that something was selected, or wrong, when neither was
 * true. Founder review 2026-09-13 read the boxes as exactly that. The
 * convention for a programmatic focus target (a skip-link landing, a route
 * change) is to move focus without painting it, which is what this now does.
 *
 * Every control a traveler can actually reach keeps its ring: the inputs, the
 * selects, the textareas, the choice tiles and the nav buttons all define
 * :focus-visible above and below this rule, and those are the ones a keyboard
 * user navigates by. */
.g-step-title:focus {
  outline: none;
}

/* The first-timer line. PinyaGenState already carries a `why` per question and
   nothing rendered it; CLAUDE.md's utility-copy rule is that a form should say
   why a question matters rather than assume the reader knows, and on a
   one-question screen there is finally room to. */
.g-step-why {
  margin: 0 0 20px;
  max-width: 54ch;
  font-size: 15px;
  line-height: 1.5;
  color: var(--black-coral, #5D6676);
}

.g-error {
  margin: 0 0 14px;
  padding: 10px 14px;
  border: 2px solid var(--coral, #E8734A);
  border-left-width: 6px;
  border-radius: 10px;
  background: #FFF4EF;
  color: var(--coral-text, #A8461A);
  font-size: 14px;
  line-height: 1.45;
}

/* NATIVE CONTROLS. The stage inherits inputs with a 2px #E0E0E0 border and an
   8px radius, which is the one piece of the old form that still looked like a
   different website. 16px type is not a style choice: below 16px iOS Safari
   zooms the page on focus and the traveler lands on a form they have to pinch
   back out of. */
#generator-stage input[type="text"],
#generator-stage input[type="number"],
#generator-stage input[type="date"],
#generator-stage input[type="time"],
#generator-stage input[type="search"],
#generator-stage select,
#generator-stage textarea {
  width: 100%;
  padding: 13px 15px;
  border: 3px solid var(--dark-green, #1A3009);
  border-radius: 12px;
  background: var(--white, #fff);
  font-family: inherit;
  font-size: 16px;
  color: var(--charcoal, #2D2D2D);
}

#generator-stage input:focus-visible,
#generator-stage select:focus-visible,
#generator-stage textarea:focus-visible {
  outline: 3px solid var(--leaf-green, #2D5016);
  outline-offset: 2px;
}

#generator-stage textarea { min-height: 96px; resize: vertical; }

/* The destination and must-visit fields are not native inputs: they are chip
   containers (.dest-chip-container and the .chip-input that shares its recipe)
   with a borderless input inside, so the rule above styles a box nobody sees
   and the 1px gainsboro container is what actually renders. Both get the same
   treatment as a plain field, so the form does not have two kinds of input
   that look unrelated. */
#generator-stage .dest-chip-container,
#generator-stage .chip-input {
  padding: 9px 12px;
  min-height: 52px;
  border: 3px solid var(--dark-green, #1A3009);
  border-radius: 12px;
  background: var(--white, #fff);
}

#generator-stage .dest-chip-container:focus-within,
#generator-stage .chip-input:focus-within {
  border-color: var(--leaf-green, #2D5016);
  box-shadow: 0 0 0 3px rgba(45, 80, 22, 0.18);
}

/* A BOX INSIDE A BOX, and it was this file's doing.
 *
 * The chip containers are the control, and the input inside one is just where
 * the cursor goes: style.css correctly gives .chip-typing `border: none`. But
 * the native-control rule above is `#generator-stage input[type="text"]`, an id
 * plus an attribute, which outranks `.form-group .chip-input .chip-typing` and
 * put a second 3px border and a second 12px radius back on the inner input. So
 * Must-Visit Places rendered as a bordered box drawn inside a bordered box, on
 * both generators, and the destination field only escaped because its own
 * borderless rule happens to outrank mine.
 *
 * Restated here rather than by weakening the rule above, because "the field is
 * a sticker" is right and "the caret well inside it is also a sticker" is the
 * only part that was wrong. */
#generator-stage .chip-input .chip-typing,
#generator-stage .dest-chip-container .dest-typing-input {
  border: none;
  border-radius: 0;
  background: transparent;
  padding: 4px;
  /* Not width:100%: these sit in a wrapping flex row beside the chips
     themselves, and a full-width input pushes every chip onto its own line. */
  width: auto;
  flex: 1 1 120px;
  min-width: 80px;
}

#generator-stage .chip-input .chip-typing:focus-visible,
#generator-stage .dest-chip-container .dest-typing-input:focus-visible {
  /* The container already shows focus via :focus-within, so a ring on the
     inner input would draw a second box for the same focus. */
  outline: none;
}

#generator-stage .dest-typing-input { font-size: 16px; }

/* CHOICE TILES. Interests, pace, trip stage and specificity all render as a
   grid of tappable tiles, and all three recipes in style.css predate Concept 3:
   a 2px #E0E0E0 border on an off-white fill, which on a cream card reads as a
   disabled control rather than as something to pick. They get the sticker
   treatment instead, with the selected state carrying real weight, because on
   a one-question screen the grid IS the question and a barely-tinted background
   is not enough of an answer.

   Both class names are listed rather than one generalised selector: they are
   generated by different code paths (itinerary-utils.js writes .interest-label,
   itinerary-generator.js writes .quiz-option-btn) and keeping them explicit
   means adding a third tile type fails visibly instead of half-inheriting. */
#generator-stage .interest-label,
#generator-stage .quiz-option-btn {
  min-height: 56px;
  padding: 12px 10px;
  border: 2px solid var(--dark-green, #1A3009);
  border-radius: 12px;
  background: var(--white, #fff);
  font-size: 14px;
  font-weight: 600;
  color: var(--charcoal, #2D2D2D);
  box-shadow: 3px 3px 0 rgba(26, 48, 9, 0.18);
  transition: transform 0.12s ease, box-shadow 0.12s ease, background 0.12s ease;
}

/* The lift is the site's established hover feel. Guarded on hover:hover so a
   touch device does not leave a tile stuck in the lifted state after a tap. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  #generator-stage .interest-label:hover,
  #generator-stage .quiz-option-btn:hover {
    transform: translate(-1px, -1px);
    box-shadow: 4px 4px 0 rgba(26, 48, 9, 0.28);
  }
}

/* Selected has to be obvious at a glance across a grid of ten, so it changes
   fill AND shadow weight rather than nudging a border colour. */
#generator-stage .interest-checkbox input:checked + .interest-label,
#generator-stage .quiz-option-btn.selected {
  background: var(--pineapple-yellow, #F4D35E);
  border-color: var(--dark-green, #1A3009);
  color: var(--dark-green, #1A3009);
  box-shadow: 3px 3px 0 var(--dark-green, #1A3009);
}

#generator-stage .interest-checkbox input:focus-visible + .interest-label,
#generator-stage .quiz-option-btn:focus-visible {
  outline: 3px solid var(--leaf-green, #2D5016);
  outline-offset: 3px;
}

/* 130px-minimum tracks put "Culture & History" on two lines inside a tile only
   150px wide. A slightly wider floor fixes that without changing the column
   count at any width that matters.
 *
 * THIS WAS BACKED OUT ONCE AND THE REASON GIVEN WAS WRONG. In September it
 * appeared to break day trip: a real pointer click on an interest tile toggled
 * nothing while an in-page .click() on a freshly queried node worked, and
 * removing this rule fixed it. The note left here blamed the grid re-rendering
 * after first paint and a click landing on a stale node. That was a guess, and
 * instrumenting it later disproved it: the grid renders exactly once, and the
 * label stays attached for the life of the page.
 *
 * What actually changed in between is R8. Day trip tagged data-q on the grid
 * itself, so the grid moved into a screen while the label that names it stayed
 * behind; the tagging now covers the whole question. With that fixed the rule
 * is clean, verified by clicking an interest sixteen times across both
 * generators at both widths. tests/generator-day-mode.spec.js and
 * tests/generator-guided.spec.js each hold a guard so a silent regression here
 * fails instead of being backed out again on another guess. */
#generator-stage .interests-grid {
  grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
  gap: 12px;
}

/* The required marker was three inline spans carrying `color:#ef4444`, a red
   that appears nowhere else in the palette, plus a `display:inline` that looked
   redundant. It was not. style.css opens with a reset that includes
   `a, img, span, input, label, button, ion-icon { display: block }`, so EVERY
   span on this site is a block unless something says otherwise: dropping the
   inline style put the asterisk on its own line under the label. The rule is
   restated here rather than left inline so the next span added to the
   generator has a precedent to copy. Coral is the brand's own attention
   colour, and the asterisk is aria-hidden because the control is already
   marked required to assistive tech. */
.gen-req-mark {
  display: inline;
  color: var(--coral-text, #A8461A);
}

#generator-stage .form-group { margin-bottom: 18px; }
#generator-stage .form-group:last-child { margin-bottom: 0; }

#generator-stage .form-group > label {
  display: block;
  margin-bottom: 7px;
  font-family: var(--ff-display, "Poppins", sans-serif);
  font-size: 14px;
  font-weight: 700;
  color: var(--dark-green, #1A3009);
}

#generator-stage .form-hint {
  margin-top: 7px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--black-coral, #5D6676);
}

/* Two fields that belong together (duration and travelers) stay on one row on
   a desktop and stack on a phone rather than shrinking to unusable widths. */
#generator-stage .form-row {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}

#generator-stage .form-row > .form-group { flex: 1 1 220px; }

/* The old wizard's section chrome, swept into the fine-tune step: a centered
   title with a numbered circle and a 1px gainsboro rule under every block.
   Numbered sections make no sense in a flow whose numbering is now the rail,
   and the hairline rules were the stray horizontal lines visible in the
   founder's screenshots. */
#generator-stage .form-section {
  padding: 0;
  border-bottom: none;
}

#generator-stage .form-section-title {
  justify-content: flex-start;
  padding-left: 0;
  margin-bottom: 14px;
  text-align: left;
}

#generator-stage .form-section-title .step-number { display: none; }

/* THE NAV. Separated from the question so Back and Next read as chrome rather
   than as two more answers. */
.g-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  margin-top: 24px;
  padding-top: 20px;
  border-top: 2px solid var(--g-hairline);
}

.g-nav .g-next,
.g-nav #generate-btn { margin-left: auto; }

@media (max-width: 860px) {
  #generator-stage {
    --g-pad: 20px;
  }

  #generator-stage .generator-form {
    border-radius: 18px;
    box-shadow: 4px 4px 0 var(--dark-green, #1A3009);
  }

  .g-host { min-height: 260px; }

  /* Stacking these put Back underneath Next, which reads as a list of two
     equal choices rather than as one action and one escape hatch. They stay on
     one row: Back takes only the width of its label, Next takes the rest, so
     the primary action is still the big thumb target. */
  .g-nav { flex-wrap: nowrap; }
  .g-nav .g-back { flex: 0 0 auto; }
  .g-nav .g-next,
  .g-nav #generate-btn { flex: 1 1 auto; justify-content: center; margin-left: 0; }
}

/* The [hidden] attribute is a UA rule (display: none) and ANY author display
   rule beats it. .btn sets display: inline-flex, so backBtn.hidden = true set
   the property and changed nothing: the Back button stayed on screen on the
   first question. Found by looking at a screenshot; the test asserting
   `.hidden === true` passed the whole time, because the property was true.
   Scoped to the generator rather than global so it cannot surprise another
   page. */
#generator-stage [hidden] {
  display: none !important;
}

/* ---------------------------------------------------------------------------
 * R7: the builder skin. Everything on one screen, the trip beside it.
 *
 * Two columns at 861px and up, one below. 861 is not arbitrary: it is where
 * PinyaGenState.activeSkin() switches skins, and where the trip card already
 * changed from full bleed to a column, so the layout and the skin change at the
 * same width instead of one pixel apart.
 * ------------------------------------------------------------------------ */

.b-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
}

@media (min-width: 861px) {
  .b-grid {
    /* The aside is a fixed, readable width; the questions take the rest. A
       fraction for both would let the summary grow wider than it has content
       for on a very large screen. */
    grid-template-columns: minmax(0, 1fr) 300px;
    gap: 32px;
    align-items: start;
  }
}

/* SECTIONS. Numbered, but not steps: the number is a landmark on a page you can
   see all of, which is the whole difference from the guided skin. */
.b-section {
  padding: 0 0 26px;
  margin: 0 0 26px;
  border-bottom: 2px solid var(--g-hairline);
}

.b-section:last-of-type {
  border-bottom: none;
  margin-bottom: 0;
  padding-bottom: 0;
}

.b-kick {
  display: block;
  font-family: var(--ff-display, "Poppins", sans-serif);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--coral-text, #A8461A);
  margin: 0 0 4px;
}

.b-title {
  font-family: var(--ff-display, "Poppins", sans-serif);
  font-size: 1.25rem;
  font-weight: 800;
  line-height: 1.2;
  color: var(--dark-green, #1A3009);
  margin: 0 0 16px;
}

/* THE ASIDE. Sticky so the trip stays in view while the form scrolls past it,
   which is the reason this skin is worth having on a desktop at all. The offset
   clears the site header; max-height plus its own scroll keeps a long card from
   running off the bottom on a short window. */
@media (min-width: 861px) {
  .b-aside {
    position: sticky;
    top: 96px;
    max-height: calc(100vh - 120px);
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 14px;
  }
}

@media (max-width: 860px) {
  .b-aside {
    display: flex;
    flex-direction: column;
    gap: 14px;
    /* Above the questions on a phone: the card is the reason to keep going, so
       it should not be something you only meet after scrolling past everything.
       (The builder is not what phones get today; this is for a forced skin and
       for a narrow desktop window.) */
    order: -1;
  }
}

/* "Using your saved preferences for budget, pace and interests." Sits at the
   top of the form, above the first question, because a traveler should meet it
   before answering rather than discover after the fact that their trip was
   shaped by something they set months ago on another page. Informational, so
   it takes the light-yellow treatment rather than the coral error one: nothing
   has gone wrong. */
.gen-prefs-applied {
  margin: 0 0 20px;
  padding: 12px 16px;
  border: 2px solid var(--pineapple-gold, #E0B83A);
  border-radius: 12px;
  background: var(--light-yellow, #FFF1BF);
  color: var(--dark-green, #1A3009);
  font-size: 14px;
  line-height: 1.5;
}

.gen-prefs-applied a {
  color: var(--dark-green, #1A3009);
  font-weight: 700;
  text-decoration: underline;
}

.b-prefs { margin-bottom: 20px; }

/* THE ACTIONS BLOCK. The missing-answers note sits ABOVE the button rather than
   below it, so it is read before the click rather than as a reaction to one. */
.b-actions {
  margin-top: 26px;
  padding-top: 20px;
  border-top: 2px solid var(--g-hairline);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 14px;
}

/* THE CHECKLIST. Founder decision 2026-09-14, picked from four rendered
   treatments. No box and no colour wash: nothing has gone wrong, the traveler
   simply has not finished, and a bordered yellow panel for "you are partway
   through a form" is the kind of thing that makes a first-timer think they
   broke something. The list carries the meaning on its own. */
.b-missing {
  margin: 0;
  padding: 0;
  border: none;
  background: none;
}

.b-missing-kick {
  display: block;
  font-family: var(--ff-display, "Poppins", sans-serif);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--coral-text, #A8461A);
  margin: 0 0 9px;
}

.b-missing-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.b-need {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0 0 6px;
  font-size: 14px;
  line-height: 1.4;
  color: var(--charcoal, #2D2D2D);
}

.b-need:last-child { margin-bottom: 0; }

/* The bubble. Empty ring while outstanding, filled once answered. */
.b-bubble {
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  border: 2px solid var(--dark-green, #1A3009);
  border-radius: 50%;
  background: transparent;
  transition: background 0.15s ease;
}

@media (prefers-reduced-motion: reduce) {
  .b-bubble { transition: none; }
}

.b-need[data-done="true"] .b-bubble {
  background: var(--leaf-green, #2D5016);
  border-color: var(--leaf-green, #2D5016);
}

/* Struck through AND muted, with a screen-reader-only "Answered:" alongside,
   because neither the line nor the colour is available to everyone. */
.b-need[data-done="true"] .b-need-text {
  color: var(--black-coral, #5D6676);
}

.b-actions #generate-btn { align-self: flex-start; }

@media (max-width: 860px) {
  .b-actions { align-items: stretch; }
  .b-actions #generate-btn { width: 100%; justify-content: center; }
}
