/* ══════════════════════════════════════════════════════════════════════════
   Layout, colour and spacing below. Type sizes as noted above.

   Its own file rather than more of marketing/pages/onboarding.css, which is
   already 3,500 lines shared with the buyer and broker steppers. Loaded per
   screen via `content_for :marketing_page_asset, "seller_setup"`.

   Type is the design's own px and weights, NOT the shared --type-* ramp. The
   design uses 32/750 on every headline, 34/700 on the collections input and
   weights of 750 and 800, none of which have a rung, and snapping them cost
   roughly ten visible deviations per screen. This file is therefore excluded from
   rake typography:check in one documented place (see lib/tasks/typography.rake),
   the way themes/broker-v2.css already is, rather than carrying 41 inline opt-outs.
   The class names are the roles; each size lives once, on its role.

   Values are measured off claude-design/seller-onboarding-v3/Seller Onboarding
   v3.dc.html. The prototype's palette is declared once here rather than reaching
   for the marketing tokens, because the design ships an explicit ramp and the
   near-matches would drift under it.
   ══════════════════════════════════════════════════════════════════════════ */

.onb-s {
  --g: #0ea184;
  --gh: #0b8770;
  --gd: #0a6e5c;
  --g50: #e7f7f1;
  --ink: #222222;
  --tx: #484848;
  --tx2: #5e5e5e;
  --tx3: #767676;
  --tx4: #a0a0a0;
  --n50: #f7f7f7;
  --n100: #ebebeb;
  --n200: #dddddd;

  /* The nav this shell sits under is 64px (.onboarding-nav in
     marketing/pages/onboarding.css), NOT the prototype's 76px. Subtracting the
     prototype's number left the footer floating 12px above the bottom of the
     viewport on every screen, with the page background showing under it. */
  --onb-nav-h: 64px;

  display: flex;
  flex-direction: column;
  /* 🚨 A fixed height with the SCROLL INSIDE, not min-height.
     The design pins its footer and scrolls the question area within it. With
     min-height the whole page grows instead, so on any screen taller than the
     viewport (payer mix, size, review, type) the act bar and the forward CTA slide
     below the fold and the seller sees no way onward. */
  height: calc(100dvh - var(--onb-nav-h));
  overflow: hidden;
  font-size: 15px;
  color: var(--tx);
  line-height: 1.55;
}

/* The native app drops the web nav entirely (see layouts/onboarding.html.erb), so
   there is nothing to subtract. Mirrors what .buyer-setup already does. */
.onboarding-body.is-native .onb-s { --onb-nav-h: 0px; }

.onb-s__scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  justify-content: center;
  padding: 8px 40px 40px;
}

.onb-s__col {
  width: 100%;
  max-width: var(--onb-s-w, 720px);
  margin: auto 0;
  padding: 24px 0;
  /* The design gives every screen the same entrance. In the prototype it plays on
     a state change; here it plays on load, which is the same moment for a seller.
     Without it the act bar slides and the content it belongs to snaps. */
  animation: onb-s-in 0.26s ease;
}

/* The two screens that arrive rather than advance: a reveal and a conclusion. The
   design swaps the rise for a settle on both. */
.onb-s--valuation .onb-s__col,
.onb-s--handoff .onb-s__col {
  animation: onb-s-pop 0.3s ease;
}

@keyframes onb-s-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

@keyframes onb-s-pop {
  from { opacity: 0; transform: scale(0.98); }
  to { opacity: 1; transform: none; }
}

/* ── Type ────────────────────────────────────────────────────────────────── */

.onb-s__title {
  margin: 0;
  font-family: var(--font-display, "Figtree", Inter, sans-serif);
  font-size: 32px;
  font-weight: 750;
  letter-spacing: -0.026em;
  /* 1.55 to match the prototype's COMPUTED result, not its source. It declares no
     line-height on the h1, so the value comes from its body. Simply omitting it
     here does not reproduce that: the marketing bundle's own h1 rule wins and
     lands on 1.25, which made every headline 10px short and pulled all twelve
     screens' content up. Match what renders, not what is authored. */
  line-height: 1.55;
  color: var(--ink);
  text-wrap: balance;
}

.onb-s__sub {
  margin: 10px 0 0;
  font-size: 16px;
  color: var(--tx2);
  text-wrap: pretty;
}

.onb-s__eyebrow {
  margin: 0;
  font-family: var(--font-display, "Figtree", Inter, sans-serif);
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
}

.onb-s__grouplabel {
  font-family: var(--font-display, "Figtree", Inter, sans-serif);
  font-size: 17px;
  font-weight: 700;
  color: var(--ink);
}

.onb-s__note {
  margin: 24px 0 0;
  font-size: 14.5px;
  color: var(--tx3);
}

.onb-s__body {
  margin-top: 28px;
}

.onb-s__group {
  margin-top: 34px;
}

.onb-s__group .onb-s__opts {
  margin-top: 14px;
}

.onb-s__error {
  margin-top: 18px;
  padding: 12px 14px;
  border-radius: 10px;
  background: #fdecea;
  color: #8a1c14;
  font-size: 14.5px;
}

.onb-s__field-error {
  margin-top: 10px;
  font-size: 14px;
  color: #b42318;
}

/* ── Option cards ────────────────────────────────────────────────────────── */

.onb-s__opts {
  display: grid;
  gap: 12px;
}

.onb-s__opts.is-cols-1 { grid-template-columns: minmax(0, 1fr); }
.onb-s__opts.is-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.onb-s__opts.is-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.onb-s__opt {
  display: flex;
  align-items: flex-start;
  gap: 13px;
  padding: 20px;
  border: 1.5px solid var(--n200);
  border-radius: 12px;
  background: #fff;
  text-align: left;
  font: inherit;
  cursor: pointer;
  /* Only the border and background move on selection. Animating the border WIDTH
     would shift every neighbour in the grid by half a pixel. */
  transition: background-color 0.16s ease, border-color 0.16s ease;
}

.onb-s__opt:hover { border-color: #c8c8c8; }

/* The selected card thickens its border. The 0.5px inset keeps the box the same
   size as its unselected neighbours so the grid does not twitch. */
.onb-s__opt.is-on,
.onb-s__opt:has(.onb-s__opt-input:checked) {
  border-color: var(--ink);
  border-width: 2px;
  padding: 19.5px;
  background: var(--n50);
}

.onb-s__opt:has(.onb-s__opt-input:focus-visible) {
  outline: 2px solid var(--g);
  outline-offset: 2px;
}

/* The design draws four card shapes and they differ in TYPE as well as spacing,
   so the base card is only ever a starting point. Keyed off the variant rather
   than the column count: padding is a property of the shape, and timing being
   the only single-column screen was a coincidence, not a rule.
   See _setup_options.html.erb for what each variant is. */

.onb-s__opts.is-preset .onb-s__opt { padding: 18px; align-items: flex-start; }
.onb-s__opts.is-preset .onb-s__opt.is-on { padding: 17.5px; }

/* The compact row card: icon beside the label rather than above it. Used by
   specialty, position and market setting. */
.onb-s__opts.is-row .onb-s__opt {
  align-items: center;
  gap: 12px;
  padding: 16px 18px;
}

.onb-s__opts.is-row .onb-s__opt.is-on,
.onb-s__opts.is-row .onb-s__opt:has(.onb-s__opt-input:checked) {
  padding: 15.5px 17.5px;
}

/* Position, the one row group the design pads evenly. Scoped to the group
   wrapper because type.html.erb is its only user. */
.onb-s__group .onb-s__opts.is-row .onb-s__opt { padding: 18px; }

.onb-s__group .onb-s__opts.is-row .onb-s__opt.is-on,
.onb-s__group .onb-s__opts.is-row .onb-s__opt:has(.onb-s__opt-input:checked) { padding: 17.5px; }

/* :stack, the practice-type pair. Icon above the text rather than beside it, so
   two cards can carry the weight the eight-card grid used to. */
.onb-s__opts.is-stack .onb-s__opt {
  flex-direction: column;
  align-items: stretch;
  gap: 24px;
  padding: 18px;
}

.onb-s__opts.is-stack .onb-s__opt.is-on,
.onb-s__opts.is-stack .onb-s__opt:has(.onb-s__opt-input:checked) { padding: 17.5px; }

/* The compact row: the same card as .is-row at the smaller scale the design uses
   for a group revealed inside another answer. */
.onb-s__opts.is-row.is-compact .onb-s__opt { gap: 11px; padding: 14px 16px; }

.onb-s__opts.is-row.is-compact .onb-s__opt.is-on,
.onb-s__opts.is-row.is-compact .onb-s__opt:has(.onb-s__opt-input:checked) { padding: 13.5px 15.5px; }

.onb-s__opts.is-row.is-compact .onb-s__opt-label { font-size: 14.5px; }

/* ── The specialty disclosure ───────────────────────────────────────────────
   Closed by default. Opened by the controller, or forced open by the noscript
   rule in type.html.erb so the seven specialties are never unreachable.
   ────────────────────────────────────────────────────────────────────────── */

.onb-s__spec-stage { display: none; }
.onb-s__spec-stage.is-open { display: block; }

.onb-s__spec-stage .onb-s__opts { margin-top: 12px; }

.onb-s__spec-hint {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 18px 0 0;
  font-size: 13.5px;
  font-weight: 600;
  /* Green, because it is an instruction the seller has to act on, not a caption.
     Every other hint in the flow is grey and ignorable; this one is not. */
  color: var(--g);
  animation: onb-s-in 0.22s ease;
}

.onb-s__spec-hint[hidden] { display: none; }

/* :tile, priorities. A display-font title over a two-line explainer, so the
   label is 700 whether or not the card is picked. */
.onb-s__opts.is-tile .onb-s__opt { align-items: flex-start; gap: 14px; padding: 20px; }

.onb-s__opts.is-tile .onb-s__opt.is-on,
.onb-s__opts.is-tile .onb-s__opt:has(.onb-s__opt-input:checked) { padding: 19.5px; }

.onb-s__opts.is-tile .onb-s__opt-icon { margin-top: 2px; }

.onb-s__opts.is-tile .onb-s__opt-label {
  font-family: var(--font-display, "Figtree", Inter, sans-serif);
  font-size: 16px;
  font-weight: 700;
}

.onb-s__opts.is-tile .onb-s__opt-desc {
  margin-top: 3px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--tx2);
}

/* :lead, timing. The icon TRAILS the text and the row centres on it. The
   ordering lives in the partial; only the spacing and type are here. */
.onb-s__opts.is-lead .onb-s__opt { align-items: center; gap: 18px; padding: 20px 22px; }

.onb-s__opts.is-lead .onb-s__opt.is-on,
.onb-s__opts.is-lead .onb-s__opt:has(.onb-s__opt-input:checked) { padding: 19.5px 21.5px; }

.onb-s__opts.is-lead .onb-s__opt-label {
  font-family: var(--font-display, "Figtree", Inter, sans-serif);
  font-size: 17px;
  font-weight: 700;
}

.onb-s__opts.is-lead .onb-s__opt-desc {
  margin-top: 3px;
  font-size: 14.5px;
  color: var(--tx2);
}

/* Visually hidden but still focusable and still the source of :checked. */
.onb-s__opt-input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.onb-s__opt-icon {
  flex: none;
  display: flex;
  color: var(--ink);
}

.onb-s__opt-text {
  flex: 1;
  min-width: 0;
  display: block;
}

.onb-s__opt-label {
  display: block;
  font-size: 15px;
  font-weight: 500;
  color: var(--ink);
}

.onb-s__opt.is-on .onb-s__opt-label,
.onb-s__opt:has(.onb-s__opt-input:checked) .onb-s__opt-label {
  font-weight: 700;
}

.onb-s__opt-desc {
  display: block;
  margin-top: 2px;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--tx3);
}

/* ── Counters (Size) ─────────────────────────────────────────────────────── */

.onb-s__rows { margin-top: 2px; }

.onb-s__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 22px 0;
  border-top: 1px solid var(--n100);
}

.onb-s__row-label {
  font-size: 16.5px;
  font-weight: 600;
  color: var(--ink);
}

.onb-s__row-hint {
  margin-top: 1px;
  font-size: 14px;
  color: var(--tx3);
}

.onb-s__counter {
  flex: none;
  display: flex;
  align-items: center;
  border: 1.5px solid var(--n200);
  border-radius: 12px;
  overflow: hidden;
}

.onb-s__counter-btn {
  width: 52px;
  height: 52px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: #fff;
  color: var(--ink);
  cursor: pointer;
  transition: background-color 0.15s ease;
}

.onb-s__counter-btn:hover { background: var(--n50); }
.onb-s__counter-btn:active { background: var(--n100); }

.onb-s__counter-input {
  width: 64px;
  height: 52px;
  border: 0;
  border-left: 1px solid var(--n100);
  border-right: 1px solid var(--n100);
  text-align: center;
  font-family: var(--font-display, "Figtree", Inter, sans-serif);
  font-size: 19px;
  font-weight: 700;
  color: var(--ink);
  background: #fff;
  /* The spinners duplicate the buttons either side of this field. */
  appearance: textfield;
  -moz-appearance: textfield;
}

.onb-s__counter-input::-webkit-inner-spin-button,
.onb-s__counter-input::-webkit-outer-spin-button {
  appearance: none;
  margin: 0;
}

/* ── Collections ─────────────────────────────────────────────────────────── */

.onb-s__money { margin-top: 8px; }

.onb-s__money-label {
  display: block;
  margin-bottom: 12px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--tx4);
}

.onb-s__money-field {
  position: relative;
  max-width: 420px;
}

.onb-s__money-prefix {
  position: absolute;
  left: 22px;
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--font-display, "Figtree", Inter, sans-serif);
  font-size: 34px;
  font-weight: 700;
  color: var(--tx3);
  pointer-events: none;
}

.onb-s__money-input {
  width: 100%;
  height: 88px;
  padding: 0 22px 0 56px;
  border: 1.5px solid var(--n200);
  border-radius: 14px;
  background: #fff;
  font-family: var(--font-display, "Figtree", Inter, sans-serif);
  font-size: 34px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
  outline: none;
}

/* The focus rule for this input lives with the search field's, above. The
   prototype declares a green ring here, but the two text inputs in the flow have
   to agree and the location field is the one the design actually renders. */

.onb-s__money-hint {
  margin-top: 12px;
  font-size: 14px;
  color: var(--tx3);
}

.onb-s__notes {
  display: grid;
  gap: 12px;
  max-width: 62ch;
  margin-top: 40px;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--tx2);
}

.onb-s__notes strong {
  color: var(--ink);
  font-weight: 600;
}

/* ── Location ────────────────────────────────────────────────────────────── */

.onb-s__search {
  position: relative;
  margin-top: 2px;
}

.onb-s__search-icon {
  position: absolute;
  left: 18px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  color: var(--tx3);
  pointer-events: none;
}

.onb-s__search-input {
  width: 100%;
  height: 60px;
  padding: 0 18px 0 48px;
  border: 1.5px solid var(--n200);
  border-radius: 12px;
  font: inherit;
  font-size: 16px;
  color: var(--ink);
  background: #fff;
  outline: none;
}

/* No focus styling, deliberately. The design's search field keeps its resting
   border when focused: the caret is the affordance, and a green ring on a field
   that is about to sprout an autocomplete list below it competes with the list.
   Applies to the collections input too, so the two text fields behave alike.

   ⚠️ This also opts BOTH text inputs out of the app-wide keyboard focus ring
   (`input:focus-visible { outline: 2px solid var(--base-border-focus) }` in
   marketing/site.css). A text input always matches :focus-visible when focused,
   even from a mouse click, so there is no way to keep the ring for keyboard users
   only. The caret is the remaining focus indicator. Deliberate, and narrow: it is
   these two fields and nothing else. Every non-text control in the flow keeps its
   ring, including the option cards. */
.onb-s__search-input:focus,
.onb-s__search-input:focus-visible,
.onb-s__money-input:focus,
.onb-s__money-input:focus-visible {
  outline: none;
  border-color: var(--n200);
  box-shadow: none;
}

/* 🚨 The app-wide focus ring in marketing/site.css is
   `a, button, input, select, textarea :focus-visible { outline: 2px …;
   border-radius: 4px }`. That last declaration is the problem: it rewrites the
   SHAPE of whatever takes keyboard focus, so every rounded control in this flow
   squares off the moment it is focused. Seven of them do it: both text inputs,
   the forward CTA, the ghost button, and both halves of the counter.

   Each control's own radius is restored below. The ring itself is left alone
   everywhere it is wanted. `.onb-s__back` is deliberately absent: it is an
   underlined text link with no border or background, so only its outline's
   corners round, which is what the app's convention wants anyway. */
.onb-s__search-input:focus-visible { border-radius: 12px; }
.onb-s__money-input:focus-visible { border-radius: 14px; }
.onb-s__next:focus-visible { border-radius: 12px; }
.onb-s__ghost:focus-visible { border-radius: 10px; }

/* Square, and it has to stay square: this sits inside a rounded, overflow-hidden
   group, so rounding one corner notches the dividers between them. */
.onb-s__counter-btn:focus-visible { border-radius: 0; }

/* The counter VALUE takes no focus ring at all — the design shows a stepper looking
   identical focused and unfocused, and the only interactive feedback on it is the
   button hover above. The app-wide ring squared the field off and boxed the number
   inside its own group, reading as two nested controls.
   Kept on the buttons deliberately: they have no caret, so a keyboard user needs to
   see which half is focused. The input has one, which is its focus indicator. */
.onb-s__counter-input:focus,
.onb-s__counter-input:focus-visible {
  outline: none;
  box-shadow: none;
  /* border-radius stays 0 for the same reason as the buttons above: the app-wide rule
     sets 4px, and this field's left/right divider edges sit flush inside the group, so
     rounding them notches the seams. Suppressing the outline does not suppress that. */
  border-radius: 0;
}

.onb-s__market { margin-top: 30px; }

/* The setting trio is the one grid the design tightens to 10px, and its glyphs
   are 19px rather than the 21px the specialty cards carry. */
.onb-s__market .onb-s__opts { gap: 10px; }

.onb-s__market-lede {
  margin-bottom: 12px;
  font-size: 15px;
  color: var(--tx2);
}

.onb-s__market-lede strong {
  color: var(--ink);
  font-weight: 600;
}

/* Two ledes, one shown at a time. The guess is the design's sentence; the ask
   replaces it when the place gave us nothing to infer from, because "This looks
   like a suburban market" has to be something we actually worked out. */
.onb-s__market-ask { display: none; }
.onb-s__market.is-unknown .onb-s__market-guess { display: none; }
.onb-s__market.is-unknown .onb-s__market-ask { display: inline; }

.onb-s__trust {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 24px;
  font-size: 13.5px;
  color: var(--tx3);
}

/* ── Payer mix ───────────────────────────────────────────────────────────── */

.onb-s__stack {
  display: flex;
  height: 12px;
  margin-top: 34px;
  border-radius: 999px;
  overflow: hidden;
  background: var(--n100);
}

/* An inline box ignores width. Every bar segment in this codebase needs an
   explicit display, and the overview meter learned that the hard way. */
.onb-s__stack-seg {
  display: block;
  height: 100%;
  transition: width 0.2s ease;
}

.onb-s__mixrows { margin-top: 10px; }

.onb-s__mixrow {
  display: grid;
  grid-template-columns: 170px 1fr 52px;
  gap: 20px;
  align-items: center;
  padding: 12px 0;
}

.onb-s__mixrow-label {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  color: var(--ink);
}

.onb-s__swatch {
  display: block;
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 2px;
}

.onb-s__mixrow-pct {
  text-align: right;
  font-size: 15px;
  font-weight: 600;
  color: var(--tx2);
  font-variant-numeric: tabular-nums;
}

/* A real range input, styled, rather than the prototype's transparent input over
   drawn divs: that trick loses the keyboard affordance and the focus ring. */
.onb-s__slider {
  appearance: none;
  width: 100%;
  height: 22px;
  margin: 0;
  background: transparent;
  cursor: pointer;
}

.onb-s__slider::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 999px;
  background: linear-gradient(
    to right,
    var(--track, var(--g)) 0 var(--fill, 0%),
    var(--n100) var(--fill, 0%) 100%
  );
}

.onb-s__slider::-moz-range-track {
  height: 4px;
  border-radius: 999px;
  background: linear-gradient(
    to right,
    var(--track, var(--g)) 0 var(--fill, 0%),
    var(--n100) var(--fill, 0%) 100%
  );
}

.onb-s__slider::-webkit-slider-thumb {
  appearance: none;
  width: 22px;
  height: 22px;
  margin-top: -9px;
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.16);
}

.onb-s__slider::-moz-range-thumb {
  width: 22px;
  height: 22px;
  border: 0;
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.16);
}

.onb-s__slider:focus-visible { outline: none; }

.onb-s__slider:focus-visible::-webkit-slider-thumb {
  outline: 2px solid var(--g);
  outline-offset: 2px;
}

/* ── Review ──────────────────────────────────────────────────────────────── */

.onb-s__review { margin-top: -2px; }

.onb-s__rev-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 19px 0;
  border-top: 1px solid var(--n100);
}

.onb-s__rev-label {
  flex: none;
  width: 190px;
  font-size: 14.5px;
  color: var(--tx3);
}

.onb-s__rev-value {
  flex: 1;
  min-width: 0;
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
}

.onb-s__rev-edit {
  flex: none;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  text-decoration: underline;
}

/* ── Reflection and handoff ──────────────────────────────────────────────── */

/* Both screens sit in a box NARROWER than their column: reflection 640 inside
   720, handoff 660 inside 720. Narrowing the column itself would look the same
   in isolation and be wrong, because the column is centred, so a 640px column
   would start 40px further right than the design's text does. Cap the measure,
   leave the column alone. */
.onb-s--reflection .onb-s__title,
.onb-s--reflection .onb-s__sub,
.onb-s--reflection .onb-s__body { max-width: 640px; }

.onb-s--handoff .onb-s__title,
.onb-s--handoff .onb-s__body { max-width: 660px; }

/* Handoff is a statement, not a question, and the design gives it its own
   headline: bigger, and set tight rather than at the shared 1.55. */
.onb-s--handoff .onb-s__title {
  font-size: 36px;
  line-height: 1.14;
  letter-spacing: -0.028em;
}

.onb-s--handoff .onb-s__note {
  margin-top: 22px;
  line-height: 1.6;
}

/* The one sub the design caps, because it is the longest in the flow. */
.onb-s--priorities .onb-s__sub { max-width: 60ch; }

.onb-s__readback {
  margin: 30px 0 0;
  font-family: var(--font-display, "Figtree", Inter, sans-serif);
  font-size: 24px;
  font-weight: 600;
  line-height: 1.45;
  color: var(--gd);
  text-wrap: pretty;
}

.onb-s__ghost {
  display: inline-block;
  margin-top: 18px;
  padding: 11px 18px;
  border: 1.5px solid var(--n200);
  border-radius: 10px;
  background: #fff;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
  transition: border-color 0.16s ease;
}

.onb-s__ghost:hover { border-color: var(--ink); }

.onb-s__brief {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: 20px 0;
  border-top: 1px solid var(--n100);
}

.onb-s__brief-icon {
  flex: none;
  display: flex;
  margin-top: 3px;
  color: var(--gd);
}

.onb-s__brief-text { flex: 1; min-width: 0; display: block; }

.onb-s__brief-title {
  display: block;
  font-family: var(--font-display, "Figtree", Inter, sans-serif);
  font-size: 17px;
  font-weight: 700;
  color: var(--ink);
}

.onb-s__brief-body {
  display: block;
  margin-top: 3px;
  font-size: 15px;
  line-height: 1.6;
  color: var(--tx2);
}

/* ── Valuation reveal ────────────────────────────────────────────────────────
   The one screen in the flow that is centred. Everything below is the design's
   `valuation` screen; the numbers behind it are the real estimator's.
   ────────────────────────────────────────────────────────────────────────── */

.onb-s__reveal { text-align: center; }

.onb-s__reveal-lede {
  max-width: 52ch;
  margin: 0 auto;
  font-size: 16px;
  line-height: 1.6;
  color: var(--tx2);
  text-wrap: pretty;
}

.onb-s__reveal-range {
  margin: 22px 0 0;
  font-family: var(--font-display, "Figtree", Inter, sans-serif);
  font-size: 62px;
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: -0.038em;
  color: var(--gd);
  /* Held invisible for the first fifth of a second, then faded up. The server
     renders the final figures here and onboarding_reveal counts them up from
     zero, but the controller cannot start until its module has loaded, and until
     then the answer is sitting on screen. This hides that window. It is an
     animation rather than a starting opacity so that with JS off the figures
     still appear: an animation always runs to its end state. */
  animation: onb-s-reveal-in 0.5s ease both;
}

@keyframes onb-s-reveal-in {
  0%, 36% { opacity: 0; }
  100% { opacity: 1; }
}

/* The midpoint supports the range rather than leading it. Not in the design,
   which led with one precise figure. See the partial's header for why. */
.onb-s__reveal-mid {
  margin: 10px 0 0;
  font-size: 15px;
  color: var(--tx3);
}

.onb-s__reveal-mid strong {
  color: var(--ink);
  font-weight: 600;
}

.onb-s__reveal-band {
  max-width: 480px;
  margin: 28px auto 0;
}

.onb-s__reveal-track {
  position: relative;
  height: 10px;
  border-radius: 999px;
  background: var(--n100);
}

/* Inset equally from both ends, so the coloured span is centred on the midpoint
   and its WIDTH is the band's half_pct. A tighter estimate draws a shorter bar. */
.onb-s__reveal-fill {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--inset, 33%);
  right: var(--inset, 33%);
  border-radius: 999px;
  background: linear-gradient(90deg, #5fc7ac, #0b8770);
  transition: left 0.4s ease, right 0.4s ease;
}

.onb-s__reveal-ends {
  display: flex;
  justify-content: space-between;
  margin-top: 9px;
  font-size: 13px;
  color: var(--tx4);
}

.onb-s__reveal-drivers {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin: 26px 0 0;
  padding: 0;
  list-style: none;
}

.onb-s__reveal-driver {
  padding: 8px 14px;
  border: 1px solid var(--n100);
  border-radius: 10px;
  font-size: 13.5px;
  color: var(--tx2);
}

.onb-s__reveal-sharpen {
  max-width: 620px;
  margin: 34px auto 0;
  padding-top: 24px;
  border-top: 1px solid var(--n100);
  text-align: left;
}

.onb-s__reveal-sharpen-title {
  font-family: var(--font-display, "Figtree", Inter, sans-serif);
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
}

.onb-s__reveal-sharpen-list {
  display: grid;
  gap: 12px;
  margin-top: 14px;
}

.onb-s__reveal-sharpener {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  font-size: 15px;
  line-height: 1.6;
  color: var(--tx);
}

.onb-s__reveal-sharpener-icon {
  flex: none;
  display: flex;
  margin-top: 4px;
  color: var(--g);
}

.onb-s__reveal-sharpener strong {
  color: var(--ink);
  font-weight: 600;
}

/* ── Welcome ─────────────────────────────────────────────────────────────── */

.onb-s__welcome {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 64px;
  align-items: center;
}

.onb-s__welcome-copy .onb-s__eyebrow { margin-bottom: 14px; }

/* The welcome headline is its own size, not the shell's question heading: 44px at
   weight 800, wrapping to two lines at this column width. */
.onb-s__welcome-title {
  margin: 0;
  font-family: var(--font-display, "Figtree", Inter, sans-serif);
  font-size: 44px;
  font-weight: 800;
  line-height: 1.08;
  letter-spacing: -0.03em;
  color: var(--ink);
  max-width: 14ch;
}

.onb-s__welcome-lede {
  margin: 20px 0 0;
  font-size: 16.5px;
  line-height: 1.62;
  color: var(--tx2);
  text-wrap: pretty;
}

.onb-s__welcome-lede + .onb-s__welcome-lede { margin-top: 14px; }

/* The gradient is the fallback: if three.js never arrives, or the seller asked
   for reduced motion, this panel still looks deliberate. */
.onb-s__welcome-stage {
  height: 380px;
  border-radius: 20px;
  background: linear-gradient(150deg, #f7fbfa, #edf6f3);
  overflow: hidden;
}

.onb-s__welcome-stage canvas { display: block; }

/* ── Footer ──────────────────────────────────────────────────────────────── */

.onb-s__foot { flex: none; }

.onb-s__acts {
  display: flex;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.onb-s__act {
  flex: 1;
  height: 4px;
  background: var(--n100);
  overflow: hidden;
}

.onb-s__act-fill {
  display: block;
  width: var(--fill, 0%);
  height: 100%;
  background: var(--ink);
  transition: width 0.3s ease;
}

.onb-s__bar {
  height: 88px;
  /* The design's own gutter. Reserving 172px on the right to dodge the Userback
     feedback FAB, as this file used to, pushed the CTA a third of the way across
     the footer on all twelve screens. The FAB is lifted clear instead, above the
     88px footer, by the same rule the buyer stepper already uses (see
     marketing/pages/onboarding.css, the #userback_button_container block). */
  padding: 0 40px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.onb-s__bar-end {
  display: flex;
  align-items: center;
  gap: 22px;
}

.onb-s__back {
  padding: 10px 0;
  border: 0;
  background: transparent;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  text-decoration: underline;
  cursor: pointer;
}

.onb-s__back.is-hidden { visibility: hidden; }

.onb-s__skip {
  border: 0;
  background: transparent;
  font: inherit;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--tx3);
  text-decoration: underline;
  cursor: pointer;
}

.onb-s__next {
  padding: 15px 32px;
  border: 0;
  border-radius: 12px;
  background: var(--g);
  color: #fff;
  font-family: var(--font-display, "Figtree", Inter, sans-serif);
  font-size: 16px;
  font-weight: 650;
  /* Same reason as the title: a button does not inherit the body's line-height
     through the reset, so the design's 24.8px has to be stated. Without it the CTA
     is 6px shorter than the design's. */
  line-height: 1.55;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.18s ease;
}

.onb-s__next:hover { background: var(--gh); }
.onb-s__next:active { background: var(--gd); }

.onb-s__next:disabled,
.onb-s__next[disabled] {
  background: var(--n100);
  color: var(--tx4);
  cursor: not-allowed;
}

/* ── Responsive ──────────────────────────────────────────────────────────────
   Part of Done for seller surfaces, not an afterthought. Two things drive the
   breakpoints: the multi-column card grids, and the payer-mix row whose fixed
   170px label column is what actually overflows first.
   ────────────────────────────────────────────────────────────────────────── */

@media (max-width: 1023px) {
  .onb-s__welcome {
    grid-template-columns: minmax(0, 1fr);
    gap: 32px;
  }

  .onb-s__welcome-stage { height: 280px; }
}

@media (max-width: 767px) {
  .onb-s__scroll { padding: 4px 20px 32px; }
  .onb-s__bar { height: auto; padding: 16px 20px 24px; gap: 12px; }

  .onb-s__title { font-size: 26px; }
  .onb-s__sub { font-size: 15px; }

  /* 62px is a desktop display size. On a phone the range wraps to two lines and
     swamps everything under it, so it comes down with the rest of the headings. */
  .onb-s__reveal-range { font-size: 40px; }
  .onb-s--handoff .onb-s__title { font-size: 28px; }

  /* Three-up specialty cards do not fit a phone; two-up with the compact row
     card still shows the icon and the full label. */
  .onb-s__opts.is-cols-2,
  .onb-s__opts.is-cols-3 { grid-template-columns: minmax(0, 1fr); }

  .onb-s__money-input { height: 72px; font-size: 28px; padding-left: 48px; }
  .onb-s__money-prefix { left: 18px; font-size: 28px; }

  /* The label moves above the slider, so the readout can keep its own column
     rather than being squeezed to nothing. */
  .onb-s__mixrow {
    grid-template-columns: 1fr auto;
    gap: 8px 12px;
  }

  .onb-s__mixrow-label { grid-column: 1; }
  .onb-s__mixrow-pct { grid-column: 2; }
  .onb-s__slider { grid-column: 1 / -1; }

  .onb-s__row {
    align-items: flex-start;
    flex-direction: column;
    gap: 14px;
  }

  /* The review row's fixed 190px label column plus a value plus Edit is more
     than a phone has. Stack the label over the value and keep Edit on the
     baseline. */
  .onb-s__rev-row {
    flex-wrap: wrap;
    gap: 4px 16px;
  }

  .onb-s__rev-label { width: 100%; }
  .onb-s__rev-value { flex: 1 1 auto; }

  .onb-s__readback { font-size: 20px; }
}

@media (prefers-reduced-motion: reduce) {
  .onb-s__act-fill,
  .onb-s__stack-seg,
  .onb-s__opt,
  .onb-s__reveal-fill,
  .onb-s__next { transition: none; }

  /* Screens arrive already in place. setup_shell and onboarding_reveal check the
     same query in JS, so the act bar and the counting figures stop too. */
  .onb-s__col,
  .onb-s--valuation .onb-s__col,
  .onb-s--handoff .onb-s__col { animation: none; }

  /* The count-up is off too (the controller checks the same query), so there is
     no gap left to cover and the figures must not be hidden even briefly. */
  .onb-s__reveal-range { animation: none; }
}


/* ── Icon sizing ─────────────────────────────────────────────────────────────
   IconHelper renders its SVGs at width/height: 1em, so an icon is sized by its
   box. A CSS width/height on the svg beats that attribute and keeps glyph sizing
   out of type entirely. Utility classes are not an option: this surface loads the
   marketing bundle, so w-[21px] does not exist and fails silently.
   ────────────────────────────────────────────────────────────────────────── */

.onb-s__opt-icon svg { width: 21px; height: 21px; }
/* Per card shape, because the design sizes the glyph to the card and not to the
   surface. Higher specificity than the 21px above, so order here does not matter. */
.onb-s__opts.is-tile .onb-s__opt-icon svg { width: 22px; height: 22px; }
.onb-s__opts.is-lead .onb-s__opt-icon svg { width: 24px; height: 24px; }
.onb-s__opts.is-stack .onb-s__opt-icon svg { width: 24px; height: 24px; }
.onb-s__opts.is-row.is-compact .onb-s__opt-icon svg { width: 19px; height: 19px; }
.onb-s__spec-hint svg { width: 15px; height: 15px; flex: none; }
.onb-s__market .onb-s__opt-icon svg { width: 19px; height: 19px; }
.onb-s__search-icon svg { width: 18px; height: 18px; }
.onb-s__counter-btn svg { width: 16px; height: 16px; }
.onb-s__brief-icon svg { width: 22px; height: 22px; }
.onb-s__reveal-sharpener-icon svg { width: 16px; height: 16px; }
.onb-s__trust svg { width: 13px; height: 13px; }

/* ── Stepper nav ─────────────────────────────────────────────────────────────
   The shared onboarding layout puts its exit link in a CENTRE slot. The design
   right-aligns it as a pill. Scoped to the stepper's own body class so the buyer
   and broker onboarding flows that share this layout are untouched.
   ────────────────────────────────────────────────────────────────────────── */

/* 🚨 .onboarding-nav__inner is a GRID: `1fr auto 1fr`, with the exit link in the
   middle column. That is why three flex-based attempts here did nothing at all:
   justify-content and margin-left: auto are meaningless against a grid track.
   Give the logo an auto column, let the middle track take the slack, and
   right-align the link inside it. */
/* The design draws no rule under the top bar. The stepper is one uninterrupted
   white field from the logo down to the act strip, and a hairline here cuts the
   first screen in half. The shared nav keeps its border for every other flow. */
body.onboarding-body:has(.onb-s) .onboarding-nav {
  border-bottom: 0;
}

body.onboarding-body:has(.onb-s) .onboarding-nav__inner {
  grid-template-columns: auto 1fr auto;
}

body.onboarding-body:has(.onb-s) .onboarding-nav__center {
  justify-self: end;
}

.onboarding-body:has(.onb-s) .onboarding-nav__exit {
  padding: 9px 18px;
  border: 1px solid var(--n200, #dddddd);
  border-radius: 999px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink, #222222);
  text-decoration: none;
  transition: background-color 0.16s ease;
}

.onboarding-body:has(.onb-s) .onboarding-nav__exit:hover { background: var(--n50, #f7f7f7); }
