/* ============================================================
   NOVA OS — the front door (os-signup.html)
   ★ EXTENSION LAYER. This file is meaningless on its own. ★

   WHY IT IS SHAPED LIKE THIS
   --------------------------
   Vincent, 2026-08-16, on the old Nova OS onboarding (signup.html, the
   dark statue configurator): "way too complex, way too much... copy the
   exact onboarding we have for Nova Assistant."

   So os-signup.html loads TWO stylesheets, in this order:

     1. assets/css/assistant-signup.css   the whole quiz design system —
        tokens, .nas-* chrome, .nq-* quiz shell, choice cards, goal tiles,
        sticky CTA, progress bar, build-loader checklist, tier cards. 1100
        lines that already exist and are already approved.
     2. this file                          ONLY the components Nova OS needs
        that Nova Assistant never did.

   Nothing here redefines a token, a font, a radius or a color. Every value
   below is a var() off that first file. If a number here is literal, it is a
   layout number (a grid gap, a stroke width) and nothing else.

   WHAT IS GENUINELY NEW HERE, AND WHY
   -----------------------------------
   .nqo-word     the real Nova OS wordmark in the top bar
   .nqo-goal4    the 4-up variant of the Assistant's 2-up goal grid
   .nqo-four     "good news, you get all four" — the ticks that land one by one
   .nqo-skip     the full-width "none of these / I don't have one" row
   .nqo-read     the analyse-your-site readback card
   .nqo-sl       ★ v3 ★ the stepped slider: band control + visible tappable stops
   .nqo-gap      the line a slider screen draws about what was just moved
   .nqo-tools    the tool grid — real product icons, tap to select
   .nqo-total    the running "you pay this much a month" bar over the CTA
   .nqo-slay     ★ v3 ★ the cancel moment: big logo cards, stamped out one at a time
   .nqo-grid     "and you're getting" — all twenty surfaces, dense
   .nqo-callout  ★ v3 ★ the content promise, in their own hours
   .nqo-stack    ★ v3 ★ the value stack: line items, provenance, and a total
   .nqo-price    ★ v3 ★ the price PER DAY
   .nqo-anchor   ★ v3 ★ their own tool total against ours, the honest anchor
   .nqo-feats    ★ v3 ★ the feature stack, icon and line each
   .nqo-proj     the projection card and its curve
   .nqo-hero     one big number, alone
   .nqo-vs       your business without Nova OS / with Nova OS
   .nqo-block    the plan: the stage rail, module cards, the 7-day list
   .nqo-demo     the book-a-demo embed frame

   WHAT WAS REMOVED, AND WHY
   -------------------------
   .nqo-sofar    the "YOUR SETUP" chip rail. Vincent, 2026-08-16: "remove the
                 your setup chip row at the top of question screens. I do not
                 like it." Gone from the markup and gone from here.
   .nqo-eyebrow  the kicker pill above the plan's headline. Vincent, v3:
                 "delete the small kicker headings above the main headings
                 everywhere, that's always not good." The rule is deleted
                 rather than orphaned, so nobody can reach for it again.
   .nqo-kill*    v2's 40px cancel rows, replaced wholesale by .nqo-slay.

   NO PURPLE / VIOLET / INDIGO. Same hard rule as the Assistant page.
   NO z-index LITERALS: the ship gate rejects them, and every layer on this
   page is achievable with DOM order instead.
   ============================================================ */

/* ============================================================
   THE WORDMARK
   ------------------------------------------------------------
   Vincent, 2026-08-16: "the top wordmark must be the Nova OS wordmark, not
   the NOVA | OS lockup." So this is the real asset,
   assets/img/nova-os-word-black.png, with its @2x in a srcset. The width and
   height are set on the <img> itself so the bar cannot reflow as it decodes;
   these rules only cap it so a wide phone does not scale it up.
   ============================================================ */
.nqo-word { display: inline-flex; align-items: center; }
.nqo-word img { height: 18px; width: auto; max-width: 130px; object-fit: contain; display: block; }

/* ============================================================
   SCREEN 1 — FOUR GOALS IN THE ASSISTANT'S TWO-GOAL GRID
   ------------------------------------------------------------
   .nq-goal-grid is already a 1fr 1fr grid, so four cards wrap to 2x2 for
   free. What does NOT come for free is the height: the Assistant's tile is
   sized for two tall cards and four of them would push the second row off a
   390x844 viewport. This trims the padding and the chip so all four are on
   screen at once, which is the whole point of a single-tap first question.
   ============================================================ */
.nqo-goal4 { gap: 10px; margin-top: 10px; }
.nqo-goal4 .nq-goal { padding: 20px 12px 16px; gap: 11px; }
.nqo-goal4 .nq-goal-ico { width: 46px; height: 46px; border-radius: var(--r-14); }
.nqo-goal4 .nq-goal-radio { width: 22px; height: 22px; top: 10px; right: 10px; }
.nqo-goal4 .nq-goal-main strong { font-size: var(--fs-sm); }
.nqo-goal4 .nq-goal-main span { margin-top: 5px; }

/* ============================================================
   SCREEN 2 — "GOOD NEWS. YOU GET ALL FOUR."
   ------------------------------------------------------------
   The payoff for the goal question, and it has to read as a WIN rather than
   as a slide (Vincent's words). So the four rows are not a static list: the
   one they picked is already ticked when the screen lands, and the other
   three tick in on a beat each. The tick is the same gradient circle every
   other pick in this funnel uses, so what the reader watches is four things
   entering their own column.
   ============================================================ */
.nqo-four { list-style: none; margin: 6px 0 0; padding: 0; display: grid; gap: 9px; text-align: left; }
.nqo-fourrow {
  display: flex; align-items: center; gap: 12px; padding: 13px 14px;
  border: 1px solid var(--line); border-radius: var(--r-16);
  background: var(--paper); box-shadow: var(--shadow-card);
  opacity: .38; transform: translateY(5px);
  transition: opacity .38s var(--ease), transform .38s var(--ease),
              border-color .38s var(--ease), background .38s var(--ease);
}
.nqo-four-ico {
  flex: none; width: 36px; height: 36px; border-radius: var(--r-12);
  display: flex; align-items: center; justify-content: center;
  background: var(--tint); color: var(--cy-deep); border: 1px solid var(--cy-pale);
  transition: background .38s var(--ease), color .38s var(--ease);
}
.nqo-four-x { flex: 1; min-width: 0; }
.nqo-four-x b { display: block; font-size: var(--fs-sm); font-weight: 640; color: var(--ink); line-height: 1.3; letter-spacing: -.01em; }
.nqo-four-x i { display: block; margin-top: 3px; font-style: normal; font-size: var(--fs-fine); color: var(--sub); line-height: 1.4; }
.nqo-four-tick {
  flex: none; width: 24px; height: 24px; border-radius: 50%;
  border: 1.5px solid var(--line); background: var(--paper); color: var(--dk);
  display: flex; align-items: center; justify-content: center;
  transition: background .3s var(--ease), border-color .3s var(--ease);
}
.nqo-four-tick svg { opacity: 0; transform: scale(.4); transition: opacity .22s var(--ease), transform .22s var(--ease); }
.nqo-fourrow.is-got { opacity: 1; transform: none; border-color: var(--cy-pale); }
.nqo-fourrow.is-got .nqo-four-tick { background: var(--grad); border-color: transparent; }
.nqo-fourrow.is-got .nqo-four-tick svg { opacity: 1; transform: none; }
/* their own pick reads as theirs, not as one of four identical rows */
.nqo-fourrow.is-mine.is-got { border-color: var(--cy-mid); background: var(--choice-on-bg); }
.nqo-fourrow.is-mine .nqo-four-ico { background: var(--grad); color: var(--dk); border-color: transparent; }

/* ============================================================
   THE SKIP ROW
   ------------------------------------------------------------
   "I do not have a website" and "Nothing organised yet" are real answers, not
   absences, so they get a full-width row under the thing they opt out of
   rather than a greyed link. Dashed border until picked, solid after, which
   is the same on/off language the choice cards speak.
   ============================================================ */
.nqo-skip {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  margin-top: 11px; padding: 14px 15px;
  border: 1px dashed var(--line); border-radius: var(--r-16);
  background: var(--paper); font: inherit; color: inherit; cursor: pointer;
  transition: border-color .18s var(--ease), background .18s var(--ease);
}
.nqo-skip:hover { border-color: var(--cy-mid); }
.nqo-skip.is-on { border-style: solid; border-color: var(--cy-mid); background: var(--choice-on-bg); }
.nqo-skip .nq-cico { width: 34px; height: 34px; flex: none; }
.nqo-skip strong { display: block; font-size: var(--fs-md); font-weight: 640; color: var(--ink); }
.nqo-skip span span { display: block; margin-top: 2px; font-size: var(--fs-note); color: var(--sub); line-height: 1.4; }

/* ============================================================
   ANALYZING YOUR SITE — the readback
   ------------------------------------------------------------
   Vincent: "the website, put that in as the very first thing, and analyze it
   as the very first thing." The steps above this card are .nq-tl, the build
   loader's own component. This is what lands underneath when they finish:
   the domain they typed and the name inside it, plus what happens to that
   site from here. It contains no claim about page content, because this page
   has no cross-origin fetch and will not pretend otherwise.
   ============================================================ */
.nqo-read {
  margin: 20px 0 0; padding: 15px 16px;
  border: 1px solid var(--cy-mid); border-radius: var(--r-18);
  background: var(--choice-on-bg); box-shadow: var(--shadow-card);
}
.nqo-read.is-in { animation: nqo-rise .42s var(--ease) both; }
.nqo-read-l {
  display: inline-flex; align-items: center; gap: 6px; margin-bottom: 7px;
  font-family: var(--disp); font-style: italic; font-weight: 800;
  font-size: var(--fs-label); letter-spacing: .11em; text-transform: uppercase; color: var(--cy-deep);
}
.nqo-read-p { margin: 0; font-size: var(--fs-note); color: var(--mut); line-height: 1.55; }
.nqo-read-p b { color: var(--ink); font-weight: 700; }
@keyframes nqo-rise { from { opacity: 0; transform: translateY(8px); } }

/* ============================================================
   THE TOOL GRID
   ------------------------------------------------------------
   Three columns at 390px. Each tile is the product's REAL icon (the same
   assets/img/replace/* set the /os marketing page ships) on paper, its name
   under it, and its public monthly price under that. Tapping flips the tile
   to the "on the list" state and the price turns cyan.

   The COPY on this screen was rewritten to Vincent's note: the question is
   "Which ones are you using right now?" and nothing else. No "tap everything
   you use", no "I replace all of it", no "this is the bill you stop paying".
   The pitch happens on the next two screens where it belongs.
   ============================================================ */
.nqo-tools {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 9px;
  margin: 4px 0 0;
}
.nqo-tool {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 7px;
  padding: 13px 6px 11px; min-height: 108px;
  border: 1px solid var(--line); border-radius: var(--r-16);
  background: var(--paper); box-shadow: var(--shadow-card);
  font: inherit; color: inherit; text-align: center; cursor: pointer;
  transition: border-color .18s var(--ease), background .18s var(--ease),
              box-shadow .18s var(--ease), transform .18s var(--ease);
}
.nqo-tool:hover { border-color: var(--cy-mid); transform: translateY(-2px); }
.nqo-tool:active { transform: scale(.97); }
.nqo-tool img {
  width: 34px; height: 34px; display: block; object-fit: contain;
  transition: filter .22s var(--ease), opacity .22s var(--ease);
}
.nqo-tool-n {
  display: block; font-size: var(--fs-fine); font-weight: 640; color: var(--ink);
  line-height: 1.25; overflow-wrap: anywhere;
}
.nqo-tool-p {
  display: block; font-size: var(--fs-fine); color: var(--faint);
  font-variant-numeric: tabular-nums; line-height: 1;
  transition: color .18s var(--ease);
}
.nqo-tool.is-on { border-color: var(--cy-mid); background: var(--choice-on-bg); box-shadow: 0 0 0 1px var(--cy-mid), var(--shadow-card); }
.nqo-tool.is-on .nqo-tool-p { color: var(--cy-deep); font-weight: 700; }
/* the little corner tick — .nq-check's recipe, sized for a tile corner, the
   same shape language every other pick in this funnel speaks */
.nqo-tool-tick {
  position: absolute; top: 7px; right: 7px; width: 20px; height: 20px;
  border-radius: 50%; border: 1.5px solid var(--line); background: var(--paper); color: var(--dk);
  display: flex; align-items: center; justify-content: center;
  transition: background .18s var(--ease), border-color .18s var(--ease);
}
.nqo-tool-tick svg { opacity: 0; transform: scale(.4); transition: opacity .16s var(--ease), transform .16s var(--ease); }
.nqo-tool.is-on .nqo-tool-tick { background: var(--grad); border-color: transparent; }
.nqo-tool.is-on .nqo-tool-tick svg { opacity: 1; transform: none; }

/* ---- the running total, docked just above the sticky CTA ----------------
   Lives INSIDE .nq-cta so it rides the same gradient scrim and the same safe
   area inset. It is the scoreboard for the screen: every tap moves it. */
.nqo-total {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin: 0 0 10px; padding: 11px 15px;
  border: 1px solid var(--line); border-radius: var(--r-14);
  background: var(--paper); box-shadow: var(--shadow-card);
}
.nqo-total-l { font-size: var(--fs-note); color: var(--sub); line-height: 1.35; }
.nqo-total-v {
  font-family: var(--disp); font-style: italic; font-weight: 800;
  font-size: var(--fs-stat); color: var(--ink); font-variant-numeric: tabular-nums;
  line-height: 1; white-space: nowrap;
}
.nqo-total-v span { font-family: var(--sans); font-style: normal; font-weight: 500; font-size: var(--fs-fine); color: var(--faint); }
.nqo-total.is-live { border-color: var(--cy-mid); box-shadow: 0 0 0 1px var(--cy-mid), var(--shadow-card); }
.nqo-total.is-live .nqo-total-v { color: var(--cy-deep); }

/* ============================================================
   ★ THE STEPPED SLIDER ★
   ------------------------------------------------------------
   Vincent, 2026-08-16: "it should not be an accurate slider, but like the
   steps." The JS makes that TRUE (min=0, max=lastIndex, step=1, so the thumb
   snaps and cannot land between bands). Everything here exists to make it
   LOOK true before anybody touches it, which is the harder half:

     .nqo-sl-ticks   a dot per band under the track. This is the load-bearing
                     detail on the whole screen. A bare track looks continuous
                     and invites somebody to try to be precise about a number
                     they were told not to be precise about; seven visible
                     stops say "pick a rough one" without a word of copy.
                     They are also TAP TARGETS, 44px tall with a small visible
                     dot, because on a 390px phone tapping the stop you want
                     beats dragging a 26px thumb to it.
     .nqo-sl-val     the readout is a SENTENCE ("About 15 a month"), sized up
                     and in the display face, so the answer is the loudest
                     thing in the panel and the control is secondary.

   Built on .nq-panel / .nq-range / .nq-slide-val from assistant-signup.css,
   which the Assistant funnel's personality screen already ships. Nothing here
   redefines the track, the thumb or the fill; this is the rail and the
   typography only.
   ============================================================ */
.nqo-sl { padding: 15px 16px 11px; }
.nqo-sl-top { display: flex; flex-direction: column; gap: 4px; }
.nqo-sl-q {
  font-size: var(--fs-sm); font-weight: 640; color: var(--ink);
  letter-spacing: -.01em; line-height: 1.35;
}
/* the answer, not the control, is the biggest thing in the panel */
.nqo-sl-val {
  font-size: var(--fs-h3); line-height: 1.15; color: var(--cy-deep);
  letter-spacing: -.01em;
}
.nqo-sl-val.nqo-sl-bump { animation: nqo-sl-bump .26s var(--ease) both; }
@keyframes nqo-sl-bump { 0% { opacity: .35; transform: translateY(-3px); } 100% { opacity: 1; transform: none; } }
.nqo-sl-range { margin: 12px 0 0; }

/* the tick rail — one stop per band, tappable, aligned to the thumb centres.
   The 13px inset on each side is half the 26px thumb, so tick n sits exactly
   under the thumb when the value is n rather than drifting at the ends. */
.nqo-sl-ticks {
  display: flex; justify-content: space-between; align-items: flex-start;
  margin: -4px 13px 0; padding: 0;
}
.nqo-sl-tick {
  flex: 1; min-width: 0; height: 26px; padding: 0; margin: 0;
  border: 0; background: none; cursor: pointer;
  display: flex; align-items: flex-start; justify-content: center;
}
.nqo-sl-tick:first-child { justify-content: flex-start; }
.nqo-sl-tick:last-child { justify-content: flex-end; }
.nqo-sl-tick i {
  display: block; width: 5px; height: 5px; border-radius: 50%;
  background: var(--line); transition: background .18s var(--ease), transform .18s var(--ease);
}
.nqo-sl-tick:hover i { background: var(--cy-mid); transform: scale(1.3); }
.nqo-sl-tick.is-on i { background: var(--cy-deep); transform: scale(1.5); }
.nqo-sl-hint { color: var(--faint); }

/* the line a slider screen draws underneath itself once it can say something
   about what was just moved */
.nqo-gap { margin: 14px 0 0; }
.nqo-gap-p {
  margin: 0; padding: 13px 15px; border-radius: var(--r-16);
  border: 1px solid var(--cy-pale); background: var(--tint);
  font-size: var(--fs-note); color: var(--mut); line-height: 1.5;
}
.nqo-gap-p b { color: var(--cy-deep); font-weight: 700; }

/* ============================================================
   ★ THE CANCEL MOMENT ★
   ------------------------------------------------------------
   Vincent, 2026-08-16: "I like the save the X against the five tools you
   listed, but actually make it VISUAL here and BIG, make a big thing out of
   this. Right now you can cancel X, bam bam bam bam, showcasing the tools and
   you save X amount which is worth X."

   v2 drew this as 40px rows with a 26px logo and an animated strike on the
   name. Correct, and not an event. So:

     * cards, two up, with the product logo at 54px. The visitor recognises
       the thing they pay for by its mark, not by reading its name.
     * each card gets STAMPED: two ink strokes draw across it in a cross
       (.nqo-slay-x i, rotated ±45deg, width 0 -> 100%), the logo drops to
       grayscale and shrinks slightly, the price is replaced by a cyan
       negative. That is the "bam".
     * a shake on impact, 280ms apart, which is the fastest cadence at which
       the eye still registers each one as a separate event.

   THE BUTTON IS NOT ON THIS SCREEN UNTIL THE ANIMATION HAS BEEN SEEN. That
   note survives from v2 unchanged: the .nq-cta block is not rendered at all
   until the last card lands AND the bottom of the tally has been on screen.
   ============================================================ */
.nqo-slay { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 20px 0 0; }
.nqo-slaycard {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 18px 10px 14px; min-height: 132px;
  border: 1px solid var(--line); border-radius: var(--r-18);
  background: var(--paper); box-shadow: var(--shadow-card);
  opacity: .4; transform: translateY(8px) scale(.97);
  transition: opacity .3s var(--ease), transform .3s var(--ease),
              background .3s var(--ease), border-color .3s var(--ease);
}
.nqo-slay-logo {
  width: 54px; height: 54px; display: block; object-fit: contain;
  transition: filter .34s var(--ease), opacity .34s var(--ease), transform .34s var(--ease);
}
.nqo-slay-n {
  font-size: var(--fs-sm); font-weight: 640; color: var(--ink);
  line-height: 1.25; text-align: center; overflow-wrap: anywhere;
  transition: color .34s var(--ease);
}
.nqo-slay-p, .nqo-slay-cut {
  font-family: var(--disp); font-style: italic; font-weight: 800;
  font-size: var(--fs-md); font-variant-numeric: tabular-nums; line-height: 1;
}
.nqo-slay-p { color: var(--faint); transition: opacity .2s var(--ease); }
/* The replacement price is stacked on top of the old one and cross-fades, so
   the card does not change height as it flips.
   text-align is NOT optional here: an absolutely positioned box takes no
   alignment from the flex parent, so without it the "-$97" renders hard
   against the left edge of the card instead of under the logo. */
.nqo-slay-cut {
  position: absolute; left: 0; right: 0; bottom: 14px;
  text-align: center;
  color: var(--cy-deep); opacity: 0; transform: translateY(4px);
  transition: opacity .3s var(--ease) .12s, transform .3s var(--ease) .12s;
}

/* The stamp. Two bars, drawn from the middle out, crossing the whole card.
   No z-index: the stamp and the flipped price are the last two children of
   the card, so paint order already puts them over the logo and the name.
   Reaching for a stacking order the DOM gives you for free is how a page ends
   up with a z-index ladder nobody can reason about. */
.nqo-slay-x { position: absolute; inset: 0; pointer-events: none; }
.nqo-slay-x i {
  position: absolute; top: 50%; left: 50%; height: 3px; width: 0;
  border-radius: var(--r-pill); background: var(--ink); opacity: .78;
  transition: width .3s var(--ease);
}
.nqo-slay-x i:first-child { transform: translate(-50%, -50%) rotate(-32deg); }
.nqo-slay-x i:last-child  { transform: translate(-50%, -50%) rotate(32deg); }

.nqo-slaycard.is-slain {
  opacity: 1; transform: none; background: var(--line-2); border-color: var(--line-2);
  animation: nqo-slay-hit .34s var(--ease) both;
}
.nqo-slaycard.is-slain .nqo-slay-logo { filter: grayscale(1); opacity: .35; transform: scale(.92); }
.nqo-slaycard.is-slain .nqo-slay-n { color: var(--faint); }
.nqo-slaycard.is-slain .nqo-slay-p { opacity: 0; }
.nqo-slaycard.is-slain .nqo-slay-cut { opacity: 1; transform: none; }
.nqo-slaycard.is-slain .nqo-slay-x i { width: 128%; }
/* the impact: a short hard shake, not a bounce */
@keyframes nqo-slay-hit {
  0%   { transform: scale(1.04); }
  35%  { transform: scale(.975) translateX(-3px); }
  65%  { transform: scale(1) translateX(2px); }
  100% { transform: none; }
}

/* the counter takes a hit on every card, so the total is felt climbing */
.nqo-tally-n.is-hit { animation: nqo-tally-hit .24s var(--ease) both; }
@keyframes nqo-tally-hit { 0% { transform: scale(1.09); } 100% { transform: scale(1); } }
.nqo-tally-year {
  margin: 12px 0 0; font-size: var(--fs-note); color: var(--mut); line-height: 1.5;
}
.nqo-tally-year b { color: var(--cy-deep); font-weight: 700; }
.nqo-tally-year.is-in { animation: nqo-rise .42s var(--ease) both; }

/* the counter under the list — the biggest number on the screen */
.nqo-tally {
  margin: 22px 0 0; padding: 20px 18px; text-align: center;
  border: 1px solid var(--cy-mid); border-radius: var(--r-22);
  background: var(--choice-on-bg); box-shadow: var(--shadow-card);
}
.nqo-tally-n {
  display: block; font-family: var(--disp); font-style: italic; font-weight: 800;
  font-size: var(--fs-stat-big); line-height: 1; color: var(--cy-deep);
  letter-spacing: -.02em; font-variant-numeric: tabular-nums;
}
/* the one beat that says "that is the final number" */
.nqo-tally-n.is-landed { animation: nqo-land .5s var(--ease) both; }
@keyframes nqo-land { 0% { transform: scale(1); } 45% { transform: scale(1.07); } 100% { transform: scale(1); } }
.nqo-tally-l { display: block; margin-top: 9px; font-size: var(--fs-sm); color: var(--ink); font-weight: 600; line-height: 1.4; }
.nqo-tally-sub { display: block; margin-top: 5px; font-size: var(--fs-fine); color: var(--sub); line-height: 1.45; }

/* the earned CTA */
.nqo-cta-in { animation: nqo-cta-up .38s var(--ease) both; }
@keyframes nqo-cta-up { from { opacity: 0; transform: translateY(14px); } }

/* the swap line: what they pay now vs what Nova OS costs */
.nqo-swap { display: flex; align-items: stretch; gap: 9px; margin-top: 12px; }
.nqo-swap-c {
  flex: 1; padding: 13px 10px; text-align: center;
  border: 1px solid var(--line); border-radius: var(--r-16); background: var(--paper);
}
.nqo-swap-c i {
  display: block; font-family: var(--disp); font-style: italic; font-weight: 800;
  font-size: var(--fs-label); letter-spacing: .1em; text-transform: uppercase; color: var(--faint);
}
.nqo-swap-c b {
  display: block; margin-top: 6px; font-family: var(--disp); font-style: italic; font-weight: 800;
  font-size: var(--fs-stat); line-height: 1; color: var(--ink); font-variant-numeric: tabular-nums;
}
.nqo-swap-c--old b { color: var(--faint); text-decoration: line-through; text-decoration-thickness: 2px; }
.nqo-swap-c--new { border-color: var(--cy-mid); background: var(--choice-on-bg); }
.nqo-swap-c--new i { color: var(--cy-deep); }
.nqo-swap-c--new b { color: var(--cy-deep); }
.nqo-swap-arrow { display: flex; align-items: center; color: var(--faint); flex: none; }

/* ============================================================
   "AND PLUS, YOU'RE GETTING ALL OF THIS"
   ------------------------------------------------------------
   Vincent asked for the kill to be followed by a "plus you're getting..."
   beat, and for a screen that lays out everything they get. Same screen: all
   twenty surfaces off the /os page, two to a row, each one small enough that
   twenty of them read as ABUNDANCE rather than as a wall of copy. They stagger
   in on --d so the list fills rather than appears.
   ============================================================ */
.nqo-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 6px 0 0; }
.nqo-gcell {
  padding: 11px 11px 12px; border: 1px solid var(--line); border-radius: var(--r-14);
  background: var(--paper); box-shadow: var(--shadow-card);
  animation: nqo-cell-in .4s var(--ease) both; animation-delay: calc(var(--d) * 32ms);
}
.nqo-gico {
  display: flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: var(--r-10);
  background: var(--tint); color: var(--cy-deep); border: 1px solid var(--cy-pale);
}
.nqo-gcell b { display: block; margin-top: 8px; font-size: var(--fs-fine); font-weight: 700; color: var(--ink); line-height: 1.3; }
.nqo-gcell i { display: block; margin-top: 3px; font-style: normal; font-size: var(--fs-label); color: var(--sub); line-height: 1.4; }
@keyframes nqo-cell-in { from { opacity: 0; transform: translateY(7px); } }

/* ============================================================
   THE PROJECTION
   ------------------------------------------------------------
   Vincent, on the v1 of this screen: "the banner that's like 'by November,
   every one of your 35 leads a month gets followed up with'. That's good. I
   love the way that looks." So the headline and the curve keep their exact
   shape, and everything added below them is added underneath rather than in
   place of them.

   What is new: .nqo-proj-goal names the 90-day target they picked (which the
   funnel now asks BEFORE this screen, so it can), and .nqo-hero carries one
   very large number, alone, explained directly under itself. The number is
   (extra leads at their target) x (their revenue / their leads). Both halves
   are their own answers, and the footnote prints the working.
   ============================================================ */
.nqo-proj {
  margin: 20px 0 0; padding: 18px 16px 14px;
  border: 1px solid var(--line); border-radius: var(--r-22);
  background: var(--paper); box-shadow: var(--shadow-lift);
}
.nqo-proj-h { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.nqo-proj-h i, .nqo-proj-h b {
  font-family: var(--disp); font-style: italic; font-weight: 800;
  font-size: var(--fs-label); letter-spacing: .11em; text-transform: uppercase;
}
.nqo-proj-h i { color: var(--faint); }
.nqo-proj-h b { color: var(--cy-deep); }
/* DIRECT CHILD ONLY. This used to be `.nqo-proj svg`, which is fine while the
   card holds nothing but the curve — and the moment the 90-day target line was
   added underneath it, its 14px flag inherited width:100% and rendered as a
   400px flag across half the screen. */
.nqo-proj > svg { display: block; width: 100%; height: auto; }
.nqo-proj-x { display: flex; justify-content: space-between; margin-top: 6px; font-size: var(--fs-fine); color: var(--faint); }

/* the curve draws itself rather than appearing: 1000 is comfortably longer
   than the path, so the dash offset walks it on from the left */
.nqo-curve-line { stroke-dasharray: 1000; stroke-dashoffset: 1000; animation: nqo-draw 1.1s var(--ease) .12s both; }
@keyframes nqo-draw { to { stroke-dashoffset: 0; } }
.nqo-curve-end { animation: nqo-pop .34s var(--ease) 1.05s both; }
.nqo-curve-halo { animation: nqo-halo 2.4s var(--ease) 1.3s infinite; transform-origin: center; transform-box: fill-box; }
@keyframes nqo-pop { from { opacity: 0; transform: scale(.2); transform-origin: center; transform-box: fill-box; } }
@keyframes nqo-halo { 0%, 100% { opacity: .25; } 50% { opacity: .06; } }

.nqo-proj-goal {
  display: flex; align-items: center; gap: 8px; margin: 12px -16px -14px;
  padding: 11px 16px 12px; border-top: 1px solid var(--line);
  background: var(--tint); border-radius: 0 0 var(--r-22) var(--r-22);
  font-size: var(--fs-fine); color: var(--sub); line-height: 1.4;
}
.nqo-proj-goal svg { flex: none; width: 14px; height: 14px; color: var(--cy-deep); }
.nqo-proj-goal b { color: var(--ink); font-weight: 700; }

/* ---- the one big number ---- */
.nqo-hero {
  margin: 16px 0 0; padding: 22px 18px 20px; text-align: center;
  border-radius: var(--r-22); background: var(--dk-card);
  box-shadow: 0 26px 48px -22px rgba(6, 18, 29, .55);
}
.nqo-hero-l {
  display: block; font-family: var(--disp); font-style: italic; font-weight: 800;
  font-size: var(--fs-label); letter-spacing: .12em; text-transform: uppercase; color: var(--cy-lo);
}
/* --fs-hero is the marketing headline size and the largest thing in the token
   set; on a 390px screen it lands at its 2.35rem floor, which is bigger than
   the tally counter and smaller than the h2 above it. That ordering is the
   point: this is the biggest NUMBER on the screen, not the biggest text.
   The gradient is painted through the glyphs, with `color` left as the real
   fallback: -webkit-text-fill-color is what goes transparent, so a browser
   without background-clip:text shows cyan letters rather than nothing. */
.nqo-hero-n {
  display: block; margin-top: 8px; font-family: var(--disp); font-style: italic; font-weight: 800;
  font-size: var(--fs-hero); line-height: 1; letter-spacing: -.03em;
  font-variant-numeric: tabular-nums; color: var(--cy-lo);
  background: var(--grad); -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
.nqo-hero-s { display: block; margin-top: 10px; font-size: var(--fs-note); color: var(--cy-lo); line-height: 1.5; }

.nqo-foot {
  margin: 14px 0 0; font-size: var(--fs-fine); color: var(--faint); line-height: 1.5;
  display: flex; align-items: flex-start; gap: 7px; text-align: left;
}
.nqo-foot svg { flex: none; margin-top: 2px; }

/* ============================================================
   WITHOUT NOVA OS / WITH NOVA OS
   ------------------------------------------------------------
   Vincent asked for this on the paywall. Every left-hand cell is something
   the visitor told us — their lead sources, their subscription total, their
   team size, the sentence they picked for how the week feels — so it is not
   a strawman about "other software", it is their own week on both sides.

   Two columns at 390px is tight, so the row LABEL sits above the pair rather
   than beside it, and only the cells are side by side.
   ============================================================ */
.nqo-vs {
  margin: 26px 0 0; border: 1px solid var(--line); border-radius: var(--r-22);
  background: var(--paper); box-shadow: var(--shadow-card); overflow: hidden;
}
.nqo-vs-head { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--line); }
.nqo-vs-h {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 11px 8px; background: var(--tint);
  font-family: var(--disp); font-style: italic; font-weight: 800;
  font-size: var(--fs-label); letter-spacing: .09em; text-transform: uppercase;
}
.nqo-vs-h svg { flex: none; }
.nqo-vs-h--no { color: var(--faint); }
.nqo-vs-h--yes { color: var(--cy-deep); background: var(--choice-on-bg); }
.nqo-vs-row { padding: 12px 14px 13px; border-top: 1px solid var(--line-2); }
.nqo-vs-row:first-of-type { border-top: 0; }
/* v3: the row label carries the icon of the thing it is about, so the table
   can be skimmed down the left edge as pictures rather than read as eight
   lines of small uppercase type. Vincent asked for this to be more visual. */
.nqo-vs-l {
  display: flex; align-items: center; gap: 6px; margin-bottom: 8px;
  font-family: var(--disp); font-style: italic; font-weight: 800;
  font-size: var(--fs-label); letter-spacing: .1em; text-transform: uppercase; color: var(--faint);
}
.nqo-vs-l svg { flex: none; color: var(--cy-deep); }
.nqo-vs-cells { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; align-items: stretch; }
.nqo-vs-c {
  display: block; padding: 10px 11px; border-radius: var(--r-12);
  font-size: var(--fs-fine); line-height: 1.4;
}
/* the losing side is deliberately flat, greyed and slightly faded; the
   winning side has the paper, the border and the weight. The contrast IS the
   argument, so it is carried by the styling rather than only by the words. */
.nqo-vs-c--no { background: var(--line-2); color: var(--sub); opacity: .82; }
.nqo-vs-c--yes {
  background: var(--choice-on-bg); color: var(--ink); font-weight: 600;
  border: 1px solid var(--cy-mid); box-shadow: var(--shadow-card);
}

/* ---- the content promise, called out where it lands ------------------
   Vincent: content is a first-class part of this, not a feature buried in a
   list of twenty. This is the block on the "you're getting" screen that says
   in plain words what I take over, and it only renders for somebody who told
   me they actually spend hours on it. */
.nqo-callout {
  display: flex; align-items: flex-start; gap: 12px;
  margin: 14px 0 0; padding: 15px 16px;
  border: 1px solid var(--cy-mid); border-radius: var(--r-18);
  background: var(--choice-on-bg); box-shadow: var(--shadow-card);
}
.nqo-callout-ico {
  flex: none; width: 40px; height: 40px; border-radius: var(--r-12);
  display: flex; align-items: center; justify-content: center;
  background: var(--grad); color: var(--dk);
}
.nqo-callout-x { flex: 1; min-width: 0; }
.nqo-callout-x b { display: block; font-size: var(--fs-sm); font-weight: 700; color: var(--ink); line-height: 1.35; }
.nqo-callout-x span { display: block; margin-top: 5px; font-size: var(--fs-fine); color: var(--mut); line-height: 1.5; }

/* ============================================================
   ★ THE VALUE STACK ★
   ------------------------------------------------------------
   Used twice: on the math screen, where it is the argument, and on the
   paywall, where it is the reminder. Same component both times, because they
   are showing the same numbers and two components would eventually disagree.

   The shape is deliberate. Each row is TWO lines: the claim and its money on
   one, and underneath in small grey type the answer that produced it. That
   second line is the entire credibility of this screen. A stack of round
   numbers with no provenance reads as a sales page; the same numbers with
   "6.5h a month back at the $75 an hour you said your time is worth" under
   each one reads as arithmetic, and arithmetic can be checked.

   The total sits INSIDE the same card, on the cyan, so it reads as the sum of
   the rows above rather than as a new claim.
   ============================================================ */
.nqo-stack {
  margin: 18px 0 0; border: 1px solid var(--line); border-radius: var(--r-22);
  background: var(--paper); box-shadow: var(--shadow-lift); overflow: hidden;
}
.nqo-stackrow {
  padding: 14px 15px 13px; border-top: 1px solid var(--line-2);
  animation: nqo-cell-in .42s var(--ease) both; animation-delay: calc(var(--d) * 90ms);
}
.nqo-stackrow:first-child { border-top: 0; }
.nqo-stackrow-h { display: flex; align-items: center; gap: 11px; }
.nqo-stack-ico {
  flex: none; width: 34px; height: 34px; border-radius: var(--r-12);
  display: flex; align-items: center; justify-content: center;
  background: var(--tint); color: var(--cy-deep); border: 1px solid var(--cy-pale);
}
/* the subscriptions row shows the REAL logos of what they ticked, overlapped
   into a stack, because "the 6 subscriptions you cancel" is far more physical
   with six recognisable marks beside it than with a generic icon */
.nqo-stack-logos { flex: none; display: flex; align-items: center; }
.nqo-stack-logos img {
  width: 26px; height: 26px; object-fit: contain; border-radius: var(--r-4);
  background: var(--paper); padding: 2px; border: 1px solid var(--line);
  margin-left: -8px; box-shadow: var(--shadow-card);
}
.nqo-stack-logos img:first-child { margin-left: 0; }
.nqo-stack-l {
  flex: 1; min-width: 0; font-size: var(--fs-sm); font-weight: 640;
  color: var(--ink); line-height: 1.3; letter-spacing: -.01em;
}
.nqo-stack-v {
  flex: none; font-family: var(--disp); font-style: italic; font-weight: 800;
  font-size: var(--fs-stat); color: var(--cy-deep);
  font-variant-numeric: tabular-nums; line-height: 1; white-space: nowrap;
}
/* the provenance line. Indented under the label, never under the icon, so the
   eye reads it as belonging to the claim rather than to the row. */
.nqo-stack-from {
  margin: 6px 0 0 45px; font-size: var(--fs-label); color: var(--faint); line-height: 1.45;
}
.nqo-stacktotal {
  padding: 16px 15px; text-align: center;
  background: var(--choice-on-bg); border-top: 1px solid var(--cy-pale);
}
.nqo-stacktotal-l, .nqo-stacktotal-s {
  display: block; font-size: var(--fs-note); color: var(--sub); line-height: 1.4;
}
.nqo-stacktotal-v {
  display: block; margin: 4px 0 3px;
  font-family: var(--disp); font-style: italic; font-weight: 800;
  font-size: var(--fs-stat-big); line-height: 1; color: var(--cy-deep);
  letter-spacing: -.02em; font-variant-numeric: tabular-nums;
}
.nqo-stack--pay { margin-top: 14px; }

/* ============================================================
   ★ THE PRICE, PER DAY ★
   ------------------------------------------------------------
   Vincent: "show the price per DAY, not per month." So the daily figure is
   the biggest number in the block and the real billed amount sits underneath
   it in plain type, because a page that shows ONLY a daily number is hiding
   the bill and this one does not.
   ============================================================ */
.nqo-price {
  margin: 20px 0 0; padding: 22px 18px 20px; text-align: center;
  border-radius: var(--r-22); background: var(--dk-card);
  box-shadow: 0 26px 48px -22px rgba(6, 18, 29, .55);
}
.nqo-price-l {
  display: block; font-family: var(--disp); font-style: italic; font-weight: 800;
  font-size: var(--fs-label); letter-spacing: .12em; text-transform: uppercase; color: var(--cy-lo);
}
.nqo-price-n {
  display: block; margin-top: 6px;
  font-family: var(--disp); font-style: italic; font-weight: 800;
  font-size: var(--fs-hero); line-height: 1; letter-spacing: -.03em;
  font-variant-numeric: tabular-nums; color: var(--cy-lo);
  background: var(--grad); -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
.nqo-price-u {
  display: block; margin-top: 2px; font-family: var(--disp); font-style: italic;
  font-weight: 800; font-size: var(--fs-h3); color: var(--cy-lo);
}
.nqo-price-s { display: block; margin-top: 10px; font-size: var(--fs-note); color: var(--cy-lo); opacity: .85; line-height: 1.5; }

/* THE HONEST ANCHOR. Not a struck-through price we never charged: their own
   stack total, which they typed in themselves, against what I cost. */
.nqo-anchor {
  margin: 12px 0 0; padding: 13px 15px; border-radius: var(--r-16);
  border: 1px solid var(--cy-pale); background: var(--tint);
  font-size: var(--fs-note); color: var(--mut); line-height: 1.55; text-align: center;
}

/* ---- the feature stack ------------------------------------------------
   Vincent: "a bigger feature section, icon + line each, framed as an
   outrageous steal." Bigger than the twenty-surface checklist under it, so
   it is a proper row with a 40px icon rather than a bullet, and the founder
   call is a step louder again because it is the one with a price on it. */
.nqo-feat-h {
  display: flex; align-items: center; gap: 9px; margin: 18px 0 12px;
  font-family: var(--disp); font-style: italic; font-weight: 800;
  font-size: var(--fs-h3); letter-spacing: -.01em; color: var(--ink);
}
.nqo-feat-h svg { color: var(--cy-deep); flex: none; }
.nqo-feats { list-style: none; margin: 0 0 16px; padding: 0; display: grid; gap: 9px; }
.nqo-feat {
  display: flex; align-items: flex-start; gap: 12px; padding: 13px 14px;
  border: 1px solid var(--line); border-radius: var(--r-16);
  background: var(--paper);
}
.nqo-feat-ico {
  flex: none; width: 40px; height: 40px; border-radius: var(--r-12);
  display: flex; align-items: center; justify-content: center;
  background: var(--tint); color: var(--cy-deep); border: 1px solid var(--cy-pale);
}
.nqo-feat-x { flex: 1; min-width: 0; }
.nqo-feat-x b { display: block; font-size: var(--fs-sm); font-weight: 700; color: var(--ink); line-height: 1.35; letter-spacing: -.01em; }
.nqo-feat-x i { display: block; margin-top: 4px; font-style: normal; font-size: var(--fs-fine); color: var(--sub); line-height: 1.5; }
.nqo-feat-tag {
  flex: none; align-self: center; padding: 4px 10px; border-radius: var(--r-pill);
  background: var(--grad); color: var(--dk);
  font-family: var(--disp); font-style: italic; font-weight: 800; font-size: var(--fs-label);
  letter-spacing: .04em;
}
/* the founder call is the loudest line in the block, because it is the one
   with a real dollar value attached and a month on it */
.nqo-feat.is-big { border-color: var(--cy-mid); background: var(--choice-on-bg); box-shadow: 0 0 0 1px var(--cy-mid), var(--shadow-card); }
.nqo-feat.is-big .nqo-feat-ico { background: var(--grad); color: var(--dk); border-color: transparent; }
.nqo-feat.is-big .nqo-feat-x b { font-size: var(--fs-md); }

/* ---- the full surface list on the tier card ---------------------------
   Vincent: "the benefits list should be much bigger, there's so many more
   benefits, so the list could be really huge." Twenty lines in one column is
   a scroll; in two it is a wall of value you can take in at once. */
.nqo-tier-feats--all { display: grid; grid-template-columns: 1fr 1fr; gap: 7px 10px; }
.nqo-tier-feats--all li { font-size: var(--fs-fine); align-items: flex-start; }
.nqo-tier-feats--all li svg { margin-top: 2px; }

/* the price beat when the billing cycle changes IN PLACE — no re-render, so
   this tick is the only signal that the number moved */
.nqo-flip { animation: nqo-flip .34s var(--ease) both; }
@keyframes nqo-flip { 0% { opacity: .25; transform: translateY(-5px); } 100% { opacity: 1; transform: none; } }

/* ============================================================
   THE OPERATING PLAN (the result screen)
   ------------------------------------------------------------
   Vincent: "'Save your setup' is solid but it doesn't really entice them to
   do anything. Doesn't tell them it's building them a custom plan." So the
   screen opens with an eyebrow that says who it was built for and from what,
   and the headline names their business. He likes "your first 7 days", so
   that block is untouched.
   ============================================================ */
/* .nqo-eyebrow IS DELETED, not merely unused. Vincent, 2026-08-16: "delete
   the small kicker headings above the main headings everywhere, that's always
   not good." It was the "BUILT FOR YOU, FROM YOUR ANSWERS" pill above the
   plan's h2, and the same pattern carried the analyse readback's "HERE IS
   WHAT I HAVE" and the tier card's "EVERYTHING, ONE PRICE" badge. All three
   are gone from the markup, and the rule is removed rather than orphaned so
   the next person cannot reach for it. The harness fails the build if a
   .nqo-eyebrow ever renders again. */
.nqo-block { margin: 26px 0 0; }
.nqo-block-h {
  display: flex; align-items: center; gap: 9px; margin: 0 0 11px;
  font-family: var(--disp); font-style: italic; font-weight: 800;
  font-size: var(--fs-h3); letter-spacing: -.01em; color: var(--ink);
}
.nqo-block-h svg { color: var(--cy-deep); flex: none; }
.nqo-block-sub { margin: -6px 0 12px; font-size: var(--fs-note); color: var(--sub); line-height: 1.5; }

/* the pipeline rail — a vertical spine with a dot per stage, so it reads as
   a pipeline and not a bullet list */
.nqo-stages { list-style: none; margin: 0; padding: 0 0 0 4px; position: relative; }
.nqo-stages::before {
  content: ""; position: absolute; left: 9px; top: 10px; bottom: 10px; width: 2px;
  border-radius: var(--r-pill); background: linear-gradient(180deg, var(--cy-mid), var(--line-2));
}
.nqo-stage { position: relative; padding: 0 0 13px 28px; }
.nqo-stage:last-child { padding-bottom: 0; }
.nqo-stage::before {
  content: ""; position: absolute; left: 4px; top: 5px; width: 12px; height: 12px;
  border-radius: 50%; background: var(--paper); border: 2px solid var(--cy-mid); z-index: 1;
}
.nqo-stage:first-child::before { background: var(--grad); border-color: transparent; box-shadow: var(--glow); }
.nqo-stage b { display: block; font-size: var(--fs-sm); font-weight: 640; color: var(--ink); line-height: 1.35; }
.nqo-stage span { display: block; margin-top: 2px; font-size: var(--fs-fine); color: var(--sub); line-height: 1.4; }

/* module cards — .nq-wyg-row's recipe plus a status chip. There is no
   "after activation" state any more: Vincent killed the pick-three question
   ("it needs to build everything and will"), so every module is built and the
   chip only says which ones go first. */
.nqo-mod { position: relative; }
.nqo-mod .nqo-status {
  display: inline-flex; align-items: center; gap: 5px; margin-top: 7px;
  padding: 3px 9px; border-radius: var(--r-pill);
  font-size: var(--fs-label); font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
}
.nqo-status--ready { background: var(--ok-bg); color: var(--ok); }
.nqo-status--next { background: var(--cy-pale); color: var(--cy-deep); }

/* the 7-day plan */
.nqo-days { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.nqo-day {
  display: flex; align-items: flex-start; gap: 12px; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: var(--r-14);
  background: var(--paper); box-shadow: var(--shadow-card);
}
.nqo-day-n {
  flex: none; width: 34px; height: 34px; border-radius: var(--r-10);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: var(--tint); border: 1px solid var(--cy-pale); color: var(--cy-deep);
  font-family: var(--disp); font-style: italic; font-weight: 800; line-height: 1;
  font-size: var(--fs-sm); font-variant-numeric: tabular-nums;
}
.nqo-day-n i { font-family: var(--sans); font-style: normal; font-weight: 500; font-size: var(--fs-label); letter-spacing: .08em; text-transform: uppercase; color: var(--faint); }
.nqo-day-x { min-width: 0; flex: 1; }
.nqo-day-x b { display: block; font-size: var(--fs-sm); font-weight: 640; color: var(--ink); line-height: 1.35; }
.nqo-day-x span { display: block; margin-top: 3px; font-size: var(--fs-fine); color: var(--sub); line-height: 1.45; }

/* ============================================================
   BOOK A DEMO
   ------------------------------------------------------------
   Nova's own booking page, embedded. Not a third-party scheduler script —
   this host's CSP is script-src 'self', and Nova OS already ships the booking
   surface, so the funnel books through the product it is selling.
   ============================================================ */
.nqo-demo {
  margin: 18px 0 0; border: 1px solid var(--line); border-radius: var(--r-22);
  background: var(--paper); box-shadow: var(--shadow-card); overflow: hidden;
}
.nqo-demo iframe { display: block; width: 100%; height: 620px; border: 0; background: var(--paper); }
.nqo-demo-fall { padding: 20px 18px; text-align: center; }
.nqo-demo-fall p { margin: 0 0 14px; font-size: var(--fs-md); color: var(--sub); }

/* ---- the yearly / monthly saving note under the tier cards ---- */
.nqo-yearline {
  margin: 10px 0 0; padding: 11px 14px; border-radius: var(--r-14);
  border: 1px solid var(--cy-pale); background: var(--tint);
  font-size: var(--fs-note); color: var(--mut); line-height: 1.5;
}
.nqo-yearline b { color: var(--cy-deep); font-weight: 700; }

/* ---- extra bottom clearance -------------------------------------------
   .nq-body reserves 168px for the sticky CTA, which is right for a bare
   button. The paywall's CTA block is a button PLUS a secondary link PLUS a
   fine-print line, so the last thing in the body ended up under it. This is
   the taller reservation for those screens. */
.nqo-body--tallcta { padding-bottom: 232px; }

/* ---- multi-select cap hint ---- */
.nqo-cap { margin: 12px 0 0; font-size: var(--fs-note); color: var(--faint); text-align: center; }
.nqo-cap b { color: var(--cy-deep); font-weight: 700; font-variant-numeric: tabular-nums; }
.nq-choice.is-locked { opacity: .42; pointer-events: none; }

/* ---- small screens ---- */
@media (max-width: 380px) {
  .nqo-tools { gap: 7px; }
  .nqo-tool { min-height: 100px; padding: 11px 4px 9px; }
  .nqo-tool img { width: 30px; height: 30px; }
  .nqo-goal4 .nq-goal { padding: 16px 10px 14px; }
  .nqo-goal4 .nq-goal-ico { width: 40px; height: 40px; }
  .nqo-vs-cells { gap: 7px; }
  .nqo-tier-feats--all { gap: 6px 8px; }
  .nqo-slay { gap: 8px; }
  .nqo-slaycard { min-height: 120px; padding: 15px 8px 12px; }
  .nqo-slay-logo { width: 46px; height: 46px; }
  /* the provenance line loses its indent before it loses its words */
  .nqo-stack-from { margin-left: 0; }
  .nqo-stack-logos img { width: 22px; height: 22px; margin-left: -9px; }
}

/* A nine-band scale (the ticket price and the two revenue scales) puts nine
   dots across ~330px, which is fine, but their tap targets get tight. Widen
   the rail's reach rather than shrinking the dots: the dot is the signal and
   the button around it is the target. */
@media (max-width: 400px) {
  .nqo-sl-ticks { margin-left: 11px; margin-right: 11px; }
}

@media (prefers-reduced-motion: reduce) {
  .nqo-read.is-in, .nqo-gcell, .nqo-cta-in, .nqo-flip,
  .nqo-tally-n.is-landed, .nqo-tally-n.is-hit, .nqo-tally-year.is-in,
  .nqo-stackrow, .nqo-sl-val.nqo-sl-bump { animation: none; }
  .nqo-curve-line { stroke-dashoffset: 0; animation: none; }
  .nqo-curve-end, .nqo-curve-halo { animation: none; }
  .nqo-tool:hover, .nqo-tool:active { transform: none; }
  /* The cancel cards and the four goal rows still RESOLVE one at a time (that
     is the information, not the decoration) — they just snap instead of
     easing, and the stamp appears rather than being drawn. */
  .nqo-slaycard, .nqo-fourrow { transition: none; transform: none; }
  .nqo-slaycard.is-slain { animation: none; transform: none; }
  .nqo-slay-x i, .nqo-slay-logo, .nqo-slay-cut { transition: none; }
  .nqo-sl-tick i { transition: none; }
}
