/* money-onetime.css: the one-time products' money pages (the launch plan of 2026-09-18, section 4,
 * the middle scope): the free report page and its six ad landers, the $29 page and the $99 page
 * with the $109 pair. Class prefix: mo-. This sheet is the ONLY new stylesheet of that build and it
 * edits nothing shared: tokens.css stays law, instrument.css stays the override, presence.css keeps
 * the rig form, market-intel.css keeps the service-area canvas and pin-picker.css keeps the picker.
 * Where a shared rule had to bend for a phone (the picker's room, the map's width), the override
 * lives here under a mo- ancestor so nothing outside these pages moves.
 *
 * LAWS KEPT: every colour on the warm canvas is a token; raw values appear only inside the drawn
 * product frames (.mo-drawn), which stand in for a capture of the report's light theme until the
 * real capture is taken, and state their token origins beside them. No inline styles (CSP), no em
 * dashes, every animation carries its reduced-motion guard in the same section. */

/* ============================ The compact hero ============================ */
/* The ad's visitor must reach the free form in one screen, so the money pages' hero is the
   home page's rig hero (min-height auto) with the product beside the words. */
.mo-hero { padding-top: clamp(104px, 12vh, 132px); padding-bottom: clamp(28px, 4vw, 48px); }
.mo-hero-grid {
  display: grid; grid-template-columns: minmax(0, 1.02fr) minmax(0, .98fr);
  gap: clamp(28px, 4vw, 56px); align-items: start; width: 100%;
}
.mo-hero h1 { max-width: 18ch; }   /* its size is every hero's (components.css .hero h1) */
.mo-hero .hero-copy { max-width: 56ch; }
.mo-hero .kicker { margin-bottom: 12px; }
.mo-hero .hero-actions { margin-top: var(--s-5); }
/* the one line that carries the price and the promise, in the proof line's mono voice but readable */
/* It flows as text, not as a row of boxes: a flex row made every "·" a box of its own that ended a line or sat alone on
   one (the site plan of 25 Sep, section 10). In text the dot is glued to the words either side (no space around a .sep
   in the markup), so it always sits between them; the line height keeps a wrapped line clear of the big price. */
.mo-priceline {
  margin: var(--s-5) 0 0; line-height: 1.9;
  font-family: var(--font-mono); font-size: 0.8rem; letter-spacing: .03em; color: var(--muted);
}
.mo-priceline b { color: var(--ink); font-weight: 600; }
.mo-priceline .amt { font-family: var(--font-display); font-size: 1.6rem; line-height: 1; color: var(--gold); letter-spacing: 0; margin-right: 4px; }
.mo-priceline .sep { margin: 0 10px; color: var(--line-2); }
/* the free page's hero carries the form itself on the right; on a phone the words come first,
   the form second and the evidence rows third, so the form is never pushed off the first screens */
.mo-hero-evid { margin-top: var(--s-6); }
.mo-hero-evid .evrows { margin: 0 0 var(--s-4); }
@media (max-width: 900px) {
  .mo-hero-grid { grid-template-columns: 1fr; gap: 30px; }
  .mo-hero-grid > .mo-hero-form { order: 2; }
  .mo-hero-grid > .mo-hero-evid { order: 3; margin-top: 0; }
}
/* a phone reads the words tighter so the form begins within the first screens */
@media (max-width: 600px) {
  /* the hero's own gutter comes off so the wrap's is the only one: the free form is then 335 px
     wide on a 375 px phone, the same as the forms in the sections below, and the 300 px Turnstile
     widget sits inside its content box (the adversarial pass, 2026-09-18) */
  .mo-hero { padding-top: 96px; padding-inline: 0; }
  .mo-hero .hero-copy { font-size: 0.98rem; }
  .mo-hero .hero-how { display: none; }
  .mo-hero .hero-actions { margin-top: var(--s-4); }
  /* the free page's hero IS the form, so its two buttons (a scroll to the form 100 px below, and the
     paid reports further down the same page) come off on a phone: with them the first field's bottom
     edge sat at 805 px in an 812 px viewport (the adversarial pass, 2026-09-18) */
  #grade-form.mo-hero .hero-actions { display: none; }
}

/* ============================ The product frames ============================ */
/* A frame is the site's product-shot--light frame with a fixed 16:10 box. The capture drops into the
   capture-slot and fills the box top-aligned, so no layout moves when it lands: the drawn stand-in
   hides itself the moment the slot is shown. The captures were taken on 2026-09-19 at 948 to 1018 px
   from the live polished reports under ?sample=1, each cut to the box's own 16:10 so the cover-fit
   crops nothing. */
.mo-frame { margin: 0; min-width: 0; }
.mo-frame-box {
  position: relative; overflow: hidden; aspect-ratio: 16 / 10;
  border: 1px solid var(--line-2); border-radius: var(--r-lg); box-shadow: var(--sh-3);
  background: #fbfaf6; /* the light theme's paper (tokens.css :root --surface before the override) */
}
/* THE BOX'S GROUND FOLLOWS WHAT IT HOLDS (2026-09-19). The paper above is the light theme's, because
   the drawn stand-in is drawn in the light theme; the report itself is dark, so a frame holding a
   capture would flash a white box while the image decodes, and show a white band for as long as a
   slow line takes. The slot covers the box, so its own ground is enough and no :has() is needed. */
.mo-frame-box > .capture-slot { position: absolute; inset: 0; background: #0b0e0d; }
.mo-frame-box > .capture-slot img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top center; }
.mo-frame-box:has(> .capture-slot:not([hidden])) > .mo-drawn { display: none; }
/* the same rule without :has() (Chrome 105, Safari 15.4, Firefox 121): the slot is always the drawn
   stand-in's previous element sibling, so the adjacent-sibling combinator hides it in every browser */
.mo-frame-box > .capture-slot:not([hidden]) + .mo-drawn { display: none; }
.mo-frame-cap { margin: 10px 2px 0; font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: .04em; color: var(--faint); line-height: 1.5; }
.mo-frame-cap a { color: var(--muted); text-decoration: underline; text-underline-offset: 3px; }
.mo-frame-cap a:hover { color: var(--gold); }
/* THE TAG NEVER SITS ON WORDS (the review of f9da203b, M6, 26 Sep; the coordinator's fix 1 to the home page's frame of the
   same capture). "Open the full example" sat on the bottom 21 to 24 px of the picture at every width, and on the $29 hero
   it covered the picture's "What this means" line. A frame that shows a capture now shows it 16:10 from its top at every
   width, as the home page's frame does, and keeps a 40 px strip of its own under the picture, where the tag sits (at most
   24 px of tag over 14 px of the link's padding), so the tag covers nothing the capture says. The link still covers the
   whole frame, strip and all. report-examples.css is linked after this sheet and gives a filled frame the capture's own
   shape (and its stacked hero a box pinned at 16:10 with the slot laid over it); it is shared at its own tag with pages
   this sheet never reaches, so it stays as it is and these three rules outrank it on specificity, one element name more
   (tests/unit/capture-tag-strip.test.js holds both). */
figure.mo-frame > .mo-frame-box:has(> .capture-slot:not([hidden])) { aspect-ratio: auto; }
figure.mo-frame > .mo-frame-box > .capture-slot:not([hidden]) { position: relative; inset: auto; padding-bottom: 40px; }
figure.mo-frame > .mo-frame-box > .capture-slot:not([hidden]) > img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; object-position: top center; }
/* THE PICTURE ENDS WHERE ITS NEIGHBOUR ENDS (the owner, 26 Sep: the example report on /seo-report "needs to be the same
   length as the 3 cards that are to its right"). Beside the cards, a .mo-frame--match figure takes the row's height with
   the caption under the window; the picture is taken out of the flow (the row is measured from the cards), fills the
   window from its top, keeps the tag's 40 px strip and fades out above it. Its capture is taller than any window it fills
   (979 x 1650, a width to height of at most 0.62), so only its bottom is ever cut, never its sides. Stacked (860 px and
   below) the frame is the one above. Each selector outranks the three rules above and report-examples.css's (one class
   more); tests/unit/capture-tag-strip.test.js holds it. */
@media (min-width: 861px) {
  .mo-frame-row > figure.mo-frame--match { align-self: stretch; display: grid; grid-template-rows: minmax(0, 1fr) auto; }
  .mo-frame-row > figure.mo-frame--match > .mo-frame-box { min-height: 300px; }
  .mo-frame-row > figure.mo-frame--match > .mo-frame-box > .capture-slot:not([hidden]) { position: absolute; inset: 0; }
  .mo-frame-row > figure.mo-frame--match > .mo-frame-box > .capture-slot:not([hidden]) > img {
    position: absolute; top: 0; left: 0; width: 100%; height: calc(100% - 40px); aspect-ratio: auto;
    object-fit: cover; object-position: top center;
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 48px), transparent);
            mask-image: linear-gradient(to bottom, #000 calc(100% - 48px), transparent);
  }
}

/* ---- The drawn stand-ins: the report's light theme, its own words, no figures ----
   Every value is a blank bar. The palette is the light theme's token set restated as literals
   because instrument.css has turned the variables obsidian: paper #fbfaf6 (--surface), ink #14201c
   (--ink), muted #5d6863 (--muted), faint #8a9a90 (--faint), line rgba(20,32,28,.14) (--line),
   mint #1f7a52 (--ok), amber #b07d12 (--warn), red #b4452f (--error), gold #8a6820 (--gold-dark). */
.mo-drawn {
  --dr-paper: #fbfaf6; --dr-ink: #14201c; --dr-muted: #5d6863; --dr-faint: #8a9a90;
  --dr-line: rgba(20, 32, 28, .14); --dr-line-2: rgba(20, 32, 28, .22);
  --dr-mint: #1f7a52; --dr-amber: #b07d12; --dr-red: #b4452f; --dr-gold: #8a6820; --dr-tint: #e8f0e7;
  position: absolute; inset: 0; display: flex; flex-direction: column; gap: 10px;
  padding: clamp(12px, 3.2%, 22px) clamp(14px, 3.6%, 24px);
  color: var(--dr-ink); background: var(--dr-paper); font-family: var(--font-body); font-size: 12px; line-height: 1.35;
  container-type: inline-size;
}
.mo-dr-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; }
.mo-dr-kick { font-family: var(--font-mono); font-size: 10px; letter-spacing: .16em; text-transform: uppercase; color: var(--dr-gold); }
.mo-dr-chip { margin-left: auto; font-family: var(--font-mono); font-size: 10px; letter-spacing: .06em; color: var(--dr-muted); border: 1px solid var(--dr-line-2); border-radius: 999px; padding: 2px 9px; }
.mo-dr-legend { margin: auto 0 0; display: flex; flex-wrap: wrap; gap: 4px 12px; align-items: center; font-size: 10.5px; color: var(--dr-muted); }
.mo-dr-legend i { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 5px; vertical-align: -1px; background: var(--dr-line); }
.mo-dr-legend i.g { background: var(--dr-mint); }
.mo-dr-legend i.a { background: var(--dr-amber); }
.mo-dr-legend i.r { background: var(--dr-red); }
.mo-dr-legend i.x { background: var(--dr-tint); border: 1px solid var(--dr-line-2); }
/* a blank value: the bar where a measured figure will print */
.mo-drawn b.blank { display: inline-block; width: 2.4em; height: .95em; border-radius: 3px; background: var(--dr-line); vertical-align: -1px; }
.mo-drawn i.blank { display: inline-block; width: 4.5em; height: .9em; border-radius: 999px; background: var(--dr-line); vertical-align: -1px; margin-right: 6px; }

/* the visibility ladder: five rungs from the box down */
.mo-dr-rungs { display: grid; gap: 6px; }
.mo-dr-rung { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 6px 10px; border: 1px solid var(--dr-line); border-radius: 7px; background: #fff; font-size: 11.5px; }
.mo-dr-rung--box { border-color: var(--dr-mint); background: rgba(31, 122, 82, .06); font-weight: 600; }
.mo-dr-rung--near { border-color: var(--dr-amber); }
.mo-dr-rung--far { border-color: var(--dr-red); }
.mo-dr-rung--out { color: var(--dr-muted); border-style: dashed; }

@container (max-width: 380px) {
  .mo-dr-legend { display: none; }
}


/* the result section's next-step card (revealed when a free report finishes) */
.mo-next { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin-top: var(--s-4); }
.mo-next a {
  display: flex; flex-direction: column; gap: 4px; padding: 14px 15px; border: 1px solid var(--line);
  border-radius: 12px; background: var(--surface); color: var(--ink); min-width: 0; transition: border-color var(--dur-1) var(--ease);
}
.mo-next a:hover { border-color: var(--forest); color: var(--ink); }
.mo-next .mo-next-price { font-family: var(--font-display); font-size: 1.5rem; line-height: 1; color: var(--gold); }
.mo-next b { font-size: 0.95rem; }
.mo-next span { font-size: 0.82rem; color: var(--muted); }
@media (max-width: 760px) { .mo-next { grid-template-columns: 1fr; } }

/* ============================ The order forms ============================ */
/* THE ROWS OF TWO LINE UP (S1-4, the forms of 25 Sep): a label that wraps (the free form's "Facebook or Instagram page ·
   optional" beside "Business phone") pushed its field below its neighbour's. While the fields sit two by two, each field
   of a row takes three rows of the row's own grid (its label, its field, its note), so labels, fields and notes line up
   across the pair whatever wraps; the spacing stays the labels' and the notes' own. One column below 901 px (presence.css). */
@media (min-width: 901px) {
  @supports (grid-template-rows: subgrid) {
    .rigform .rtwo { grid-template-rows: auto auto auto; row-gap: 0; }
    .rigform .rtwo > .rfield { display: grid; grid-template-rows: subgrid; grid-row: span 3; align-content: start; }
  }
}
/* THE "?" HINTS STAY INSIDE THE FORM (S1-4): the form's card clips what leaves it (presence.css .rigform, overflow hidden,
   the rounded frame), and a hint anchored to its "?" at the right end of a label ran 340 px to the left, past the card's
   edge, in the left column of a row of two (measured at 1440: 48 px cut off). The label row is the hint's box now, as the
   free report's ready card does it: the hint opens under the label, as wide as its field. */
.rigform .flabel-row { position: relative; }
.rigform .flabel-row .tipwrap { position: static; }
.rigform .flabel-row .tipbox { left: 0; right: 0; width: auto; top: calc(100% + 6px); }
/* TAP TARGETS OF 44 PX (the review of f9da203b, L3): the "?" was a 24 px target and the no-website switch row 22 px tall.
   The "?" takes a 44 px hit box around the same 18 px ring (the content box presence.css draws it in), and a negative
   margin keeps its 24 px place in the label row, so nothing drawn moves. The box reaches up into the space between the
   rows rather than down over the field under it, and each label row takes 3 px more above it so the box does not reach
   the field of the row above either (measured at 1440, 1024 and 390: 0 px on any other target); the switch row stands
   44 tall. */
.rigform .tipbtn { width: 44px; height: 44px; padding: 13px; margin: -15px -10px -5px; }
.rigform .flabel-row { padding-top: 3px; }
.rigform .nositerow { min-height: 44px; }

/* ================= THE VISIBILITY REPORT PAGE, LAYOUT A (full-report.html alone; 26 Sep) =================
   The owner's D5 of 26 Sep (inv-29, sections 5 and 7): a short hero on the Market report page's pattern (market-intel.css
   .mr-hero), then ONE horizontal form that sits in the first desktop screen: the six fields three across in two rows
   (two across on a tablet, one per row on a phone), the search grid as one row (pin-picker.css), one pay row (the one
   sentence beside the button), then the explanation after the form as the Market report page's cards (.mr-after).
   Every rule here names a class only this page uses. */
.fr-hero .kicker { display: block; margin-bottom: 10px; }
.fr-hero h1 { max-width: 24ch; }
/* (the sub line runs the Market report hero's full width, 980 px: two lines, not three, so the order fits a short laptop) */
.fr-hero .mo-priceline { margin-top: 14px; }
.mo-order.mr-panel-sec { padding-top: 6px; }
.mo-order .rigform-body { gap: 16px; padding: 20px 22px 18px; }
.fr-fields { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px 16px; }
/* the map, grown to the card's width while the pins are placed by hand, stands 460 px (on a phone, most of the screen);
   the small map in the card keeps pin-picker.css's own size */
.mo-order .pp-block.is-grown .pp-map { height: 460px; }
/* the pay row: the one sentence, then the button beside it (the order line and the button's foot stay adjacent) */
.fr-pay { display: grid; grid-template-columns: minmax(0, 1fr) minmax(240px, 320px); gap: 14px 20px; align-items: center; }
.mo-orderline { margin: 0; font-size: 0.9rem; color: var(--ink); }
.mo-orderline b { color: var(--gold); }
.fr-pay .rigfoot { flex-direction: column; align-items: stretch; }
.fr-pay .rigfoot .btn { width: 100%; flex: 0 0 auto; }
.fr-sample-line { margin: 0; color: var(--muted); font-size: .95rem; line-height: 1.55; max-width: 44ch; }
/* a kept order's line, above the pay button (pin-picker.js, review 29b): a red border and wash, never a stripe; it takes no
   room while empty */
.fr-kept { grid-column: 1 / -1; margin: 0; padding: 10px 12px; border: 1px solid rgba(236, 118, 99, .5); border-radius: 10px; background: rgba(236, 118, 99, .08); color: var(--ink); font-size: .88rem; line-height: 1.45; }
.fr-kept:empty { display: none; }
/* A SHORT LAPTOP SCREEN (review 29b, M3): at 1366x768, 1280x800 and 1024x768 the pay button ended under the first screen.
   A smaller headline and less air in the form bring every field, the grid row and the pay button in; a taller screen keeps
   the page as it is */
/* (to 920 px tall since 27 Sep: the card's bigger map, the owner's, would push pay out of the first screen at 1440x900) */
@media (min-width: 901px) and (max-height: 920px) {
  .fr-hero { padding-top: 88px; }
  .fr-hero h1 { font-size: clamp(2rem, 3.2vw, 2.75rem); }
  .fr-hero .mo-priceline { margin-top: 8px; }
  .mo-order .rigform-head { padding-block: 10px; }
  .mo-order .rigform-body { gap: 12px; padding-top: 14px; padding-bottom: 14px; }
}
/* the line under the City or ZIP field: what the search grid needs from it (pin-picker.js) */
.fr-cityask { margin: 6px 0 0; font-size: .8rem; line-height: 1.4; color: #ec7663; }
/* the checkout's status line takes no room until it has something to say (it stays in the page: a live region) */
.mo-order .form-status { min-height: 0; }
@media (max-width: 900px) {
  .fr-fields { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fr-pay { grid-template-columns: 1fr; }
}
@media (max-width: 760px) {
  .mo-order .pp-block.is-grown .pp-map { height: min(64svh, 460px); min-height: 340px; border-radius: 10px; }
}
@media (max-width: 600px) {
  .fr-fields { grid-template-columns: 1fr; }
  .mo-order .rigform-body { padding: 16px 14px; }
}
/* THE COMPETITOR TO COMPARE WITH (W5, 30 Sep): one optional row under the search grid. On a desktop its label, its box and
   the line that says what we will do with it sit side by side on the fields' three columns, so the order grows by one
   field's height and no more; on a tablet the label goes over the box and the line beside it, on a phone one per row. The
   line's colors are the $99 form's (market-intel.css .mi-rival-say). */
.fr-rival { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px 16px; align-items: center; }
.fr-rival .flabel-row { grid-column: 1; grid-row: 1; margin-bottom: 0; }
.fr-rival .fin { grid-column: 2; grid-row: 1; }
.fr-rival .mi-rival-name { grid-column: 2; grid-row: 2; }
.fr-rival .fr-rival-say { grid-column: 3; grid-row: 1; margin: 0; }
/* the line's room is kept while it is empty, so a message arriving never moves the pay row (the review of W5, item 13): beside
   the box two lines, the box's own height; on a phone, under it, one line */
.fr-rival .fr-rival-say, .fr-rival .fr-rival-say:empty { display: block; min-height: 2.9em; align-self: center; }
@media (max-width: 900px) {
  .fr-rival { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fr-rival .flabel-row { grid-column: 1 / -1; }
  .fr-rival .fin { grid-column: 1; grid-row: 2; }
  .fr-rival .mi-rival-name { grid-column: 1; grid-row: 3; }
  .fr-rival .fr-rival-say { grid-column: 2; grid-row: 2; }
}
@media (max-width: 600px) {
  .fr-rival { grid-template-columns: minmax(0, 1fr); }
  .fr-rival .flabel-row, .fr-rival .fin, .fr-rival .mi-rival-name, .fr-rival .fr-rival-say { grid-column: 1; grid-row: auto; }
  .fr-rival .fr-rival-say, .fr-rival .fr-rival-say:empty { min-height: 1.45em; }
}
/* THE OPTIONAL GROUP (the owner, 2 Oct): the competitor box and the Searches boxes under one head, "Optional", on the form's
   three columns. The Searches row: its label in the first column, the three boxes across the other two, and the line that
   says whose searches they are under them, with "Use the usual searches" beside it when the buyer changed them. On a tablet
   the label goes over the boxes; on a phone the boxes stand one per row. */
.fr-optional { margin: 0; padding: 12px 0 0; border: 0; border-top: 1px solid var(--line); min-width: 0; display: grid; gap: 12px; }
.fr-optional-t { padding: 0; margin: 0 0 2px; font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: .14em; text-transform: uppercase; color: var(--ink); }
.fr-optional-o { margin-left: 10px; font-family: var(--font-body, inherit); font-size: .8rem; letter-spacing: 0; text-transform: none; color: var(--muted); }
.fr-searches { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px 16px; align-items: center; }
.fr-searches .flabel-row { grid-column: 1; grid-row: 1; margin-bottom: 0; }
.fr-search-boxes { grid-column: 2 / span 2; grid-row: 1; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; min-width: 0; }
.fr-search-boxes .fin { min-width: 0; }
.fr-searches-foot { grid-column: 2 / span 2; grid-row: 2; display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 14px; min-width: 0; }
.fr-searches-foot .fr-searches-say { flex: 1 1 18em; margin: 0; }
.fr-searches-reset { flex: none; padding: 0; border: 0; background: none; color: var(--gold); font: inherit; font-size: .8rem; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.fr-searches-reset:hover { color: var(--ink); }
.fr-searches-reset:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; border-radius: 3px; }
@media (max-width: 900px) {
  .fr-searches { grid-template-columns: minmax(0, 1fr); }
  .fr-searches .flabel-row, .fr-search-boxes, .fr-searches-foot { grid-column: 1; grid-row: auto; }
}
@media (max-width: 600px) {
  .fr-search-boxes { grid-template-columns: minmax(0, 1fr); }
  .fr-optional-o { display: block; margin: 4px 0 0; }
}
/* ================= (end of the Visibility report page's block) ================= */

/* ============================ The landers ============================ */
.mo-mini { display: grid; gap: 10px; margin-top: var(--s-4); }
.mo-mini-card {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 2px 14px; align-items: start;
  padding: 13px 15px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); color: var(--ink);
  transition: border-color var(--dur-1) var(--ease);
}
.mo-mini-card:hover { border-color: var(--forest); color: var(--ink); }
.mo-mini-price { grid-row: 1 / span 2; font-family: var(--font-display); font-size: 1.6rem; line-height: 1; color: var(--gold); min-width: 3.2em; }
.mo-mini-card b { font-size: 0.98rem; }
.mo-mini-card span:not(.mo-mini-price) { font-size: 0.84rem; color: var(--muted); line-height: 1.45; }
.mo-mini-card--pair { border-style: dashed; }

/* ============================ Shared bits ============================ */
.mo-frame-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-5); margin-top: var(--s-6); align-items: start; }
@media (max-width: 860px) { .mo-frame-row { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) {
  .mo-next a, .mo-mini-card { transition: none; }
}

/* ============================ What fires, drawn (the owner, 26 Sep) ============================ */
/* The free page's "What fires when you press start" list had nothing to its right. This panel draws its four checks,
   each as its real count (nine dots with your city ringed, a star beside review bars with yours lit, five squares and
   twelve ticks, two speech bubbles), numbered 01 to 04 like the list, then the grade's five letters. It is static, so it
   is never caught half drawn, and aria-hidden: the list beside it is the words. Tokens only; colour sits on full borders,
   washes and dots (the grade row's divider is the neutral line). tests/unit/seo-report-fires.test.js holds every drawn
   count to the list's words and to the code that runs the Free report. */
.mo-fires { display: grid; grid-template-rows: minmax(0, 1fr) auto; gap: 10px; padding: 14px; border: 1px solid var(--line-2); border-radius: 16px; background: var(--paper); box-shadow: var(--glow); }
.mo-fires-tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: 1fr; gap: 10px; margin: 0; padding: 0; list-style: none; }
.mo-fires-tile { position: relative; display: grid; align-content: center; gap: 3px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); }
.mo-fires-n { position: absolute; top: 10px; right: 12px; font-family: var(--font-mono); font-size: 0.66rem; letter-spacing: .08em; color: var(--pin); }
.mo-fires-glyph { display: flex; align-items: center; gap: 8px; height: 34px; margin-bottom: 4px; }
.mo-fires-l { font-size: 0.9rem; font-weight: 600; line-height: 1.25; color: var(--ink); }
.mo-fires-l b { margin-right: 2px; font-family: var(--font-display); font-size: 1.1rem; color: var(--pin); }
.mo-fires-s { font-size: 0.78rem; line-height: 1.35; color: var(--muted); }
.mo-fires-dots { display: grid; grid-template-columns: repeat(3, 8px); grid-auto-rows: 8px; gap: 5px; width: max-content; height: auto; }
.mo-fires-dots i { width: 8px; height: 8px; border-radius: 50%; background: var(--pin); }
.mo-fires-dots i.mo-fires-home { box-sizing: border-box; background: transparent; border: 2px solid var(--gold); }
.mo-fires-prof svg { width: 26px; height: 26px; fill: none; stroke: var(--gold); stroke-width: 1.7; stroke-linejoin: round; }
.mo-fires-bars { display: grid; gap: 4px; width: 70px; }
.mo-fires-bars i { display: block; height: 5px; border-radius: 3px; background: var(--line-2); }
.mo-fires-bars i:nth-child(2) { width: 80%; }
.mo-fires-bars i:nth-child(3) { width: 62%; }
.mo-fires-bars i:nth-child(4) { width: 45%; }
.mo-fires-bars i.mo-fires-you { width: 92%; background: var(--pin); }
.mo-fires-dirs { flex-direction: column; align-items: flex-start; justify-content: center; gap: 6px; }
.mo-fires-sq { display: flex; gap: 4px; }
.mo-fires-sq i { box-sizing: border-box; width: 12px; height: 12px; border: 1.5px solid var(--pin); border-radius: 3px; }
.mo-fires-ticks { display: flex; gap: 3px; }
.mo-fires-ticks i { width: 5px; height: 10px; border-radius: 2px; background: var(--pin); opacity: .6; }
.mo-fires-chat { gap: 6px; }
.mo-fires-chat i { box-sizing: border-box; width: 30px; height: 18px; border: 1.5px solid var(--pin); border-radius: 9px 9px 9px 2px; }
.mo-fires-chat i + i { width: 22px; margin-top: 14px; border-color: var(--gold); border-radius: 9px 9px 2px 9px; }
.mo-fires-grade { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding-top: 10px; border-top: 1px solid var(--line); }
.mo-fires-grade-l { font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); }
.mo-fires-letters { display: flex; gap: 6px; }
.mo-fires-letters i { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; border: 1px solid var(--line-2); border-radius: 8px; font-style: normal; font-family: var(--font-display); font-size: 1.05rem; color: var(--gold); }
/* beside the list on a desktop and exactly as tall (the hero grid's second row, right: the grid's fourth child); after the
   form and the list on a tablet (the words carry order 0, so without order 4 it would jump above the form); not on a
   phone, where the list says it all and the form comes first */
@media (min-width: 901px) { .mo-hero-grid > .mo-fires { align-self: stretch; margin-top: var(--s-6); } }
@media (max-width: 900px) { .mo-hero-grid > .mo-fires { order: 4; width: 100%; max-width: 560px; } }
@media (max-width: 600px) { .mo-hero-grid > .mo-fires { display: none; } }
