/* presence.css: the Grade v3 presence-report sections on the on-page result
 * (spec V3-1..V3-7): the factor chip strip, the drawn 3x3 lattice, the profile
 * facts, the field board bars, the directory rows, and the AI panel states.
 * Page-specific styles only; layout, forms, and buttons come from components.css.
 * External file because the site CSP is style-src 'self' (no inline styles):
 * data-driven bar widths use the stepped w0..w20 classes below, set by
 * assets/js/seo-report.2.js with classes, never style attributes. */

/* ---- The factor chip strip (V3-1) ---- */
.presence-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-top: var(--s-4);
}
.pchip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  padding: 4px 12px;
  font-size: 0.8rem;
  background: var(--surface);
}
.pchip-name { font-weight: 700; color: var(--ink); }
.pchip-word { color: var(--muted); }
.pchip--pass { border-color: rgba(31, 122, 82, .4); background: var(--ok-bg); }
.pchip--pass .pchip-word { color: var(--ok); font-weight: 600; }
.pchip--warn { border-color: rgba(176, 125, 18, .4); background: var(--warn-bg); }
.pchip--warn .pchip-word { color: var(--warn); font-weight: 600; }
.pchip--fail { border-color: rgba(180, 69, 47, .4); background: var(--error-bg); }
.pchip--fail .pchip-word { color: var(--error); font-weight: 600; }
.pchip--na { border-style: dashed; }
.pchip--na .pchip-name { color: var(--muted); }
.pchip--na .pchip-word { color: var(--faint); }

/* The permanent /p/ link line in the grade header (shown only when the report
 * row stored; a failed insert renders no link at all rather than a dead one). */
.presence-link { margin: var(--s-3) 0 0; color: var(--muted); font-size: 0.92rem; }
.presence-link a { color: var(--forest-2); font-weight: 600; }

/* ---- Section shells ---- */
.presence-sections { display: grid; gap: var(--s-4); margin-top: var(--s-6); }
.psec {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: clamp(18px, 3vw, 28px);
}
.psec-h { margin: 0 0 var(--s-2); font-size: 1.15rem; }
.psec-lead { margin: 0 0 var(--s-3); color: var(--ink); }
.psec-stat { margin: var(--s-3) 0 0; font-weight: 700; color: var(--ink); }
.psec-note { margin: var(--s-2) 0 0; color: var(--muted); font-size: 0.92rem; }
.psec-missing {
  margin: 0;
  color: var(--muted);
  background: var(--tint);
  border-radius: var(--r);
  padding: var(--s-3) var(--s-4);
}
.psec-tier {
  margin: var(--s-3) 0 0;
  padding-top: var(--s-3);
  border-top: 1px dashed var(--line);
  color: var(--muted);
  font-size: 0.88rem;
}

/* The website heading section is a heading + optional not-measured note only;
 * the check rows themselves stay in the page's existing .check-list. */
.psec-site { border: 0; background: none; padding: 0 0 0; }
.psec-site .psec-h { margin-bottom: var(--s-1); }

/* ---- The drawn 3x3 lattice (V3-2): every dot is one real pinned search.
 * green = in the pack (1-3) · amber = 4-10 · red = 11+ · absent drawn absent ·
 * gray = the call itself failed, labeled not measured. ---- */
/* 2026-08-18: the grid and the street map sit side by side, no toggle, and each
   square names the point it stands for. On a phone they stack. */
.p-mapsplit { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-3); align-items: stretch; margin: var(--s-3) 0; }
@media (max-width: 620px) { .p-mapsplit { grid-template-columns: 1fr; } }
.p-lattice {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  aspect-ratio: 1 / 1;
  margin: 0;
}
.p-cell {
  border-radius: 8px;
  border: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 3px;
  line-height: 1.2;
  overflow: hidden;
}
.p-cz { font-weight: 700; font-size: 0.8rem; }
.p-cb { font-size: 0.68rem; }
.p-cc { font-size: 0.58rem; opacity: 0.75; }
.p-cell.p-g { background: var(--ok); border-color: var(--ok); color: #08130d; }
.p-cell.p-a { background: var(--warn); border-color: var(--warn); color: #171102; }
.p-cell.p-r { background: var(--error); border-color: var(--error); color: #1a0c09; }
.p-cell.p-absent { background: var(--tint); border-color: var(--line-2); color: var(--muted); }
.p-cell.p-gray {
  background:
    repeating-linear-gradient(45deg, var(--line), var(--line) 3px, transparent 3px, transparent 6px);
  border-style: dashed;
  border-color: var(--faint);
  color: var(--muted);
}
/* The street map half. Leaflet is self-hosted; the basemap is the one external host
   the page's policy opens for. Either failing leaves the note and the grid alone. */
.p-mappane { position: relative; border-radius: 8px; overflow: hidden; border: 1px solid var(--line); background: var(--tint); aspect-ratio: 1 / 1; min-height: 200px; }
.p-map { position: absolute; inset: 0; }
.p-mapnote { position: absolute; left: 0; right: 0; bottom: 0; margin: 0; padding: 8px 10px; font-size: 0.8rem; color: var(--muted); background: color-mix(in srgb, var(--surface) 88%, transparent); }
/* The map host div carries BOTH classes (Leaflet adds leaflet-container to the element
   you hand it), so a descendant selector never matches it. */
.p-map.leaflet-container { background: var(--tint); }
.p-map .leaflet-control-attribution,
.p-map.leaflet-container .leaflet-control-attribution { font-size: 9px; }

/* ---- The profile facts (V3-5): measurement statements only ---- */
.p-facts { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-2); }
.p-fact {
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-3);
  font-size: 0.95rem;
}
.p-fact--gap { border-color: rgba(180, 69, 47, .35); background: var(--error-bg); }

/* ---- The field board (V3-6): rating and review-count bars, the customer's
 * own row marked. Bar widths ride the stepped classes (CSP: no inline styles). */
.p-board { display: grid; gap: var(--s-2); margin-top: var(--s-2); }
.p-frow {
  display: grid;
  grid-template-columns: minmax(120px, 1fr) 2fr auto;
  gap: var(--s-3);
  align-items: center;
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-3);
}
.p-frow.is-you { border-color: var(--forest-2); background: var(--tint); }
.p-fname { font-weight: 600; font-size: 0.92rem; color: var(--ink); overflow-wrap: anywhere; }
.p-frow.is-you .p-fname { color: var(--forest); }
.p-fbar-wrap {
  display: block;
  height: 10px;
  border-radius: var(--r-pill);
  background: var(--paper);
  border: 1px solid var(--line);
  overflow: hidden;
}
.p-fbar { display: block; height: 100%; background: var(--forest-2); border-radius: var(--r-pill); }
.p-frow.is-you .p-fbar { background: var(--gold); }
.p-fmeta { color: var(--muted); font-size: 0.85rem; white-space: nowrap; }
/* Stepped bar widths: 5% steps, class set from data by the renderer. */
.p-fbar.w0 { width: 0; }
.p-fbar.w1 { width: 5%; }
.p-fbar.w2 { width: 10%; }
.p-fbar.w3 { width: 15%; }
.p-fbar.w4 { width: 20%; }
.p-fbar.w5 { width: 25%; }
.p-fbar.w6 { width: 30%; }
.p-fbar.w7 { width: 35%; }
.p-fbar.w8 { width: 40%; }
.p-fbar.w9 { width: 45%; }
.p-fbar.w10 { width: 50%; }
.p-fbar.w11 { width: 55%; }
.p-fbar.w12 { width: 60%; }
.p-fbar.w13 { width: 65%; }
.p-fbar.w14 { width: 70%; }
.p-fbar.w15 { width: 75%; }
.p-fbar.w16 { width: 80%; }
.p-fbar.w17 { width: 85%; }
.p-fbar.w18 { width: 90%; }
.p-fbar.w19 { width: 95%; }
.p-fbar.w20 { width: 100%; }

/* ---- The directory rows (V3-7) ---- */
.p-lrows { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--s-2); margin-top: var(--s-2); }
.p-lrow {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-3);
  font-size: 0.92rem;
}
.p-lname { font-weight: 600; }
/* A found directory row links to the listing; the underline appears on hover so the
   board still reads as a row of measurements rather than a list of links. */
.p-llink { color: var(--forest-2); text-decoration: none; }
.p-llink:hover, .p-llink:focus-visible { text-decoration: underline; }
.p-lstate { font-size: 0.82rem; font-weight: 700; }
.p-lrow--found .p-lstate { color: var(--ok); }
.p-lrow--missing .p-lstate { color: var(--error); }
.p-lrow--unknown .p-lstate { color: var(--faint); }

@media (max-width: 560px) {
  .p-frow { grid-template-columns: 1fr; gap: var(--s-1); }
  .p-fmeta { white-space: normal; }
}

/* ---- The AI choice + the progress rail (2026-08-18) ----
 * The visitor decides whether the assistants are asked before anything runs, and then
 * watches the real probe sequence instead of a spinner with a promised duration. */
.ai-choice {
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: var(--s-3) var(--s-4);
  margin: var(--s-4) 0;
  display: grid;
  gap: var(--s-2);
}
.ai-choice legend { font-weight: 700; padding: 0 var(--s-2); color: var(--ink); }
.ai-opt {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 2px var(--s-3);
  align-items: start;
  padding: var(--s-2);
  border-radius: var(--r-sm, 8px);
  cursor: pointer;
}
.ai-opt:hover { background: var(--tint); }
.ai-opt input { grid-row: span 2; margin-top: 4px; }
.ai-opt-t { font-weight: 600; color: var(--ink); }
.ai-opt-d { color: var(--muted); font-size: 0.9rem; }
.ai-opt:has(input:checked) { background: var(--tint); outline: 1px solid var(--line); }

.rail { margin: var(--s-3) 0 0; }
.rail-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.rail-step {
  display: grid;
  grid-template-columns: 14px 1fr auto;
  gap: var(--s-3);
  align-items: center;
  padding: 5px 0;
  font-size: 0.92rem;
  color: var(--muted);
}
.rail-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--line-2); justify-self: center; }
.rail-state { font-size: 0.8rem; letter-spacing: 0.02em; }
.rail-step.is-running { color: var(--ink); }
.rail-step.is-running .rail-dot { background: var(--warn); animation: railPulse 1.1s ease-in-out infinite; }
.rail-step.is-done { color: var(--ink); }
.rail-step.is-done .rail-dot { background: var(--ok); }
.rail-step.is-failed .rail-dot { background: var(--error); }
.rail-step.is-skipped { opacity: 0.6; }
.rail-note { margin: var(--s-2) 0 0; color: var(--muted); font-size: 0.9rem; }
@keyframes railPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) { .rail-step.is-running .rail-dot { animation: none; } }

/* ---- The finish (2026-08-18) ----
 * The report is a document and opens in its own tab. This page stops trying to be the
 * report: one card, the grade, one link. */
.ready { margin: var(--s-4) 0 0; }
.ready-card {
  display: flex;
  gap: var(--s-4);
  align-items: center;
  padding: var(--s-4) var(--s-5, var(--s-4));
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
}
@media (max-width: 560px) { .ready-card { flex-direction: column; text-align: center; } }
.ready-badge {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 66px; height: 66px;
  border-radius: 16px;
  background: var(--forest);
  border: 2px solid var(--gold);
  color: var(--gold);
  font: 700 32px/1 var(--font-display, inherit);
}
.ready-body { flex: 1; min-width: 0; }
.ready-copy { margin: 0 0 var(--s-3); color: var(--muted); }

/* THE "SO FAR" TOOLTIP SPANS THE PARAGRAPH, NOT THE WORD (D-4, the owner, 2026-09-20).
   The tooltip pattern was built for a FORM LABEL, where .tipwrap sits at the start of a
   line and a 340px box anchored to its left edge has the whole field width to open into.
   Here the marker sits mid-sentence inside a modal, and .pmodal-card is `overflow-y: auto`
   (which computes overflow-x to auto as well, so it clips both ways). Measured in the
   browser: the box opened at x=331 in a card ending at 621 and ran 46px past the edge,
   which turned the modal into a sideways scroller. A tooltip you have to scroll to read
   is not a tooltip.
   So inside the ready card the paragraph is the containing block and the box spans it:
   it cannot overflow a card it is measured against, and `top: calc(100% + 8px)` now means
   below the PARAGRAPH rather than below the word, so it never covers the sentence it is
   explaining. */
.ready-card .ready-copy { position: relative; }
.ready-card .tipwrap { position: static; }
.ready-card .tipbox { left: 0; right: 0; width: auto; }
/* THE FINISH BUTTON (owner, 2026-08-19). The one click this whole window exists to
 * produce, so it is treated as a deliberate object rather than a default button.
 *
 * The defect it replaces: this rule used to read `display: inline-block`, which loaded
 * AFTER components.css and therefore overwrote `.btn`'s `display: inline-flex`. That
 * one word cancelled the flex centring, so the label rendered at the top of a 54px box
 * with its own line-height (1) and sat visibly high. Nothing here may set `display`.
 *
 * What it adds beyond the fix: its own height and radius so it is not merely `.btn-lg`,
 * a lit top edge and a gold cast beneath it so it reads as raised on obsidian, a full
 * measure up to a sensible cap so it never floats as a small tab in a wide card, and
 * an arrow that leans on hover to promise the new tab the link actually opens. */
.ready-open {
  width: 100%;
  max-width: 340px;
  min-height: 52px;
  padding: 0 24px;
  gap: 10px;
  border-radius: 12px;
  font-size: 1.02rem;
  letter-spacing: 0.005em;
  background: linear-gradient(180deg, #f2cd80 0%, var(--gold) 55%, #cfa244 100%);
  color: var(--gold-ink);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.42), 0 10px 22px -14px rgba(230, 182, 84, 0.9);
}
.ready-open:hover,
.ready-open:focus-visible {
  background: linear-gradient(180deg, #f7d894 0%, #edc069 55%, #d8ab4a 100%);
  color: var(--gold-ink);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5), 0 14px 26px -14px rgba(230, 182, 84, 1);
}
.ready-open:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
.ready-open-label { min-width: 0; }
.ready-open-arrow { font-size: 1.05em; line-height: 1; transition: transform var(--dur-2) var(--ease); }
.ready-open:hover .ready-open-arrow { transform: translateX(3px); }
@media (prefers-reduced-motion: reduce) {
  .ready-open-arrow, .ready-open:hover .ready-open-arrow { transition: none; transform: none; }
}
.ready-note { margin: var(--s-2) 0 0; color: var(--muted); font-size: 0.85rem; }

/* ---- The progress window (2026-08-18) ----
 * The form hands the work off to a window of its own, so the page that took the
 * details stays exactly where the visitor left it. It cannot be dismissed while the
 * run is in flight: closing it would leave someone staring at a form with no idea
 * anything was happening. */
.modal-open, .modal-open body { overflow: hidden; }
.pmodal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: var(--s-4);
  background: color-mix(in srgb, #0b0e0d 78%, transparent);
  backdrop-filter: blur(3px);
  animation: pmodalIn 0.22s ease both;
}
.pmodal[hidden] { display: none; }
@keyframes pmodalIn { from { opacity: 0; } to { opacity: 1; } }
.pmodal-card {
  width: min(560px, 100%);
  max-height: 90vh;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: clamp(20px, 4vw, 32px);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.45);
  animation: pmodalRise 0.28s cubic-bezier(0.2, 0.9, 0.3, 1) both;
}
@keyframes pmodalRise { from { transform: translateY(14px) scale(0.985); } to { transform: none; } }
/* The window's own controls (owner, 2026-08-18): the finished report announces itself
   HERE, and leaving early is a decision the visitor confirms, never an accident. */
.pmodal-card { position: relative; }
.pmodal-x {
  position: absolute; top: 10px; right: 12px; width: 34px; height: 34px;
  border: 1px solid var(--line); border-radius: 999px; background: transparent;
  color: var(--muted); font-size: 1.05rem; line-height: 1; cursor: pointer;
}
.pmodal-x:hover { color: var(--ink, #eef2ef); border-color: var(--gold); }
.pmodal-foot { margin-top: var(--s-4); display: flex; justify-content: center; }
.pmodal-cancel { font-size: 0.85rem; }
.pmodal-confirm {
  margin-top: var(--s-4); padding: var(--s-4);
  border: 1px solid var(--gold); border-radius: 12px; background: rgba(230, 182, 84, 0.07);
}
.pmodal-confirm-copy { margin: 0 0 var(--s-3); font-size: 0.92rem; }
.pmodal-confirm-row { display: flex; gap: var(--s-3); flex-wrap: wrap; justify-content: center; }
.pmodal[data-mode="done"] .pmodal-foot { display: none; }
.pmodal .ready-card { text-align: left; }
.pmodal-title { margin: 0 0 var(--s-2); font-size: 1.3rem; }
.pmodal-sub { margin: 0 0 var(--s-4); color: var(--muted); font-size: 0.95rem; }

/* The bar itself: a real percentage, with a moving sheen so it reads as alive even
   while a single long step (the assistants) is running. */
.pbar {
  position: relative;
  height: 12px;
  border-radius: var(--r-pill);
  background: var(--tint);
  border: 1px solid var(--line);
  overflow: hidden;
}
.pbar-fill {
  display: block;
  height: 100%;
  width: 0;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--forest-2), var(--ok));
  transition: width 0.5s cubic-bezier(0.3, 0.8, 0.3, 1);
  position: relative;
  overflow: hidden;
}
.pbar-fill::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.35), transparent);
  transform: translateX(-100%);
  animation: pbarSheen 1.6s ease-in-out infinite;
}
@keyframes pbarSheen { to { transform: translateX(100%); } }
/* Stepped widths, same law as the field bars: classes, never style attributes. */
.pbar-fill.w0 { width: 0%; }
.pbar-fill.w1 { width: 5%; }
.pbar-fill.w2 { width: 10%; }
.pbar-fill.w3 { width: 15%; }
.pbar-fill.w4 { width: 20%; }
.pbar-fill.w5 { width: 25%; }
.pbar-fill.w6 { width: 30%; }
.pbar-fill.w7 { width: 35%; }
.pbar-fill.w8 { width: 40%; }
.pbar-fill.w9 { width: 45%; }
.pbar-fill.w10 { width: 50%; }
.pbar-fill.w11 { width: 55%; }
.pbar-fill.w12 { width: 60%; }
.pbar-fill.w13 { width: 65%; }
.pbar-fill.w14 { width: 70%; }
.pbar-fill.w15 { width: 75%; }
.pbar-fill.w16 { width: 80%; }
.pbar-fill.w17 { width: 85%; }
.pbar-fill.w18 { width: 90%; }
.pbar-fill.w19 { width: 95%; }
.pbar-fill.w20 { width: 100%; }
.pbar-now { margin: var(--s-3) 0 2px; font-weight: 700; color: var(--ink); font-size: 1.02rem; }
.pbar-count { margin: 0 0 var(--s-3); color: var(--muted); font-size: 0.85rem; }
@media (prefers-reduced-motion: reduce) {
  .pmodal, .pmodal-card { animation: none; }
  .pbar-fill { transition: none; }
  .pbar-fill::after { animation: none; display: none; }
}

/* ==================== THE INTAKE RIG (owner pick 2026-08-18) ====================
 * Mockup A of the form mockups, made real. The form is an instrument panel in the
 * hero rig's own language: a LIVE head bar, mono labels, dark wells, mint focus.
 * Every control is styled here and DRIVEN BY :has(): the checkbox and radios stay
 * real inputs (focusable, submittable), only their native rendering is replaced,
 * which is what kills the browser-blue radios and the detached checkbox the owner
 * flagged. No style attributes anywhere: style-src 'self' is law. */
.rig-grid { display: grid; grid-template-columns: .9fr 1.1fr; gap: 56px; align-items: start; }
.rig-evid .kicker { display: block; font-family: var(--font-mono); font-size: 0.75rem; letter-spacing: .22em; text-transform: uppercase; color: var(--forest); margin-bottom: 10px; }
.rig-evid-h { font-family: var(--font-display); font-size: clamp(1.7rem, 2.8vw, 2.4rem); line-height: 1.08; margin: 0 0 12px; }
.rig-evid .lead { max-width: 46ch; }
.evrows { display: grid; gap: 18px; margin: 24px 0; }
.evrow { display: flex; gap: 14px; align-items: flex-start; }
.evrow .evn { font-family: var(--font-mono); color: var(--forest); font-size: 0.75rem; margin-top: 3px; }
.evrow p { margin: 0; color: var(--muted); font-size: 0.92rem; }
.evrow strong { color: var(--ink); }
.rig-evid .chips { display: flex; flex-wrap: wrap; gap: 8px; }
.rig-evid .chip { font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: .08em; border: 1px solid var(--line); border-radius: 999px; padding: 4px 11px; color: var(--muted); }

.rigform { background: var(--surface); border: 1px solid var(--line); border-radius: 16px; box-shadow: var(--glow, 0 0 18px rgba(67, 213, 151, .18)); overflow: hidden; }
.rigform-head { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: baseline; padding: 14px 22px; border-bottom: 1px solid var(--line); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: .06em; color: var(--muted); }
.rigform-head h2 { margin: 0; font: inherit; letter-spacing: .1em; text-transform: uppercase; color: var(--ink); }
.rlive { color: var(--forest); }
.rlive::before { content: "\25CF"; margin-right: 5px; animation: rigpulse 2.2s infinite; }
/* The single track is minmax(0, 1fr), never auto: an auto track grows to the widest child, and the
   Turnstile widget is a fixed 300 px box, so on a 375 px phone every field was sized to 300 px and
   clipped at the form's right edge (the money pages' adversarial pass, 2026-09-18). The widget alone
   may overflow its cell; the fields never do. */
.rigform-body { padding: 18px 20px; display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
.rtwo { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.rfield .flabel, .rigai legend.flabel { display: block; font-family: var(--font-mono); font-size: 0.66rem; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); margin-bottom: 5px; padding: 0; }
.rigform .fin { width: 100%; background: var(--surface-3); border: 1px solid var(--line); border-radius: 9px; color: var(--ink); font: inherit; font-size: 0.92rem; padding: 8px 12px; outline: none; transition: border-color .15s, box-shadow .15s; }
.rigform .fin::placeholder { color: var(--placeholder, var(--faint)); }
.rigform .fin:focus { border-color: var(--forest); box-shadow: 0 0 0 3px rgba(67, 213, 151, .12); }
/* 44 px tall on a phone (reviewer B's L3 of 26 Sep: every order form's fields were 42). Under a coarse pointer only: at a
   desk the fields keep their 42, so the $99 page's Order stays inside a 1024 by 768 first screen. */
@media (pointer: coarse) {
  .rigform .fin { min-height: 44px; }
}

/* The no-website switch: a real checkbox wearing a switch, attached to its words.
   Flipping it visibly releases the field; seo-report.2.js still owns the required
   attribute, this is only the truth of it drawn. */
.nositerow { display: flex; align-items: center; gap: 10px; margin-top: 10px; cursor: pointer; user-select: none; }
.nositerow input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.nositerow .sw { position: relative; width: 38px; height: 22px; border-radius: 999px; background: var(--tint); border: 1px solid var(--line-2); transition: background .15s; flex: none; }
.nositerow .sw::after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: var(--muted); transition: left .15s, background .15s; }
.nositerow .nst { font-size: 0.85rem; color: var(--muted); }
.nositerow:has(input:checked) .sw { background: rgba(67, 213, 151, .25); }
.nositerow:has(input:checked) .sw::after { left: 18px; background: var(--forest); }
.nositerow:has(input:checked) .nst { color: var(--ink); }
.nositerow:has(input:focus-visible) .sw { outline: 2px solid var(--gold); outline-offset: 2px; }
.sitewrap:has(.nositerow input:checked) > .fin { opacity: .35; pointer-events: none; }
.sitewrap:has(.nositerow input:checked) > .flabel { opacity: .5; }

/* The AI choice: two selectable cards, the runtime stamped on each in mono, and not
   a native radio in sight (the input stays real underneath). */
.rigai { border: 0; margin: 0; padding: 0; }
.aicards { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.aicard { position: relative; display: block; background: var(--surface-3); border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px 10px 36px; cursor: pointer; transition: border-color .15s, box-shadow .15s; }
.aicard:hover { border-color: var(--line-2); }
.aicard input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.aicard .dot { position: absolute; left: 11px; top: 12px; width: 15px; height: 15px; border-radius: 50%; border: 2px solid var(--faint); }
.aicard:has(input:checked) { border-color: rgba(67, 213, 151, .55); box-shadow: 0 0 16px rgba(67, 213, 151, .08); }
.aicard:has(input:checked) .dot { border-color: var(--forest); }
.aicard:has(input:checked) .dot::after { content: ""; position: absolute; inset: 3px; border-radius: 50%; background: var(--forest); }
.aicard:has(input:focus-visible) { outline: 2px solid var(--gold); outline-offset: 2px; }
.aicard .ai-opt-t { display: block; font-weight: 700; font-size: 0.88rem; color: var(--ink); }
.aicard .ai-opt-d { display: block; color: var(--muted); font-size: 0.76rem; line-height: 1.4; margin-top: 2px; }
/* The AI choice used to carry a runtime on each card. It framed the decision as a cost
 * when the real question is whether the visitor wants the assistants measured at all
 * (owner, 2026-08-19). The rule stays so an older cached page does not break. */
.aicard .eta { display: none; }

/* A label that can explain itself. Hover, focus, or tap the marker. Moving focus away
 * closes it, and seo-report.2.js binds Escape, because on a phone there is no hover to
 * leave, and a tooltip nobody can dismiss fails WCAG 1.4.13. The first version of this
 * comment claimed Escape worked when nothing implemented it (adversarial pass). */
.tipwrap { position: relative; display: inline-flex; align-items: center; gap: 7px; }
.tipbtn {
  /* 24px of target (WCAG 2.2 SC 2.5.8) around a 17px circle: the extra reach comes
     from a transparent border-box so the ring stays small while the tap area does
     not, and so it cannot collide with the label text beside it. */
  flex: none; width: 24px; height: 24px; padding: 3px; box-sizing: border-box;
  background: transparent; border: 0; color: var(--muted);
  font: 600 10.5px/1 var(--font-body); cursor: help;
  display: inline-flex; align-items: center; justify-content: center;
}
.tipbtn::before {
  content: "?"; display: flex; align-items: center; justify-content: center;
  width: 100%; height: 100%; border-radius: 999px;
  /* --line-2 measured 1.89:1 on this surface, under the 3:1 SC 1.4.11 asks of a
     component boundary (adversarial pass, 2026-08-19). */
  border: 1px solid var(--muted);
}
.tipbtn:hover, .tipbtn:focus-visible { color: var(--gold); }
.tipbtn:hover::before, .tipbtn:focus-visible::before { border-color: var(--gold); }
.tipbtn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.tipbox {
  display: none; position: absolute; z-index: 30; top: calc(100% + 8px); left: 0;
  width: min(340px, 78vw); padding: 11px 13px;
  background: var(--surface-3, #121614); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 18px 44px rgba(0, 0, 0, .55);
  font: 400 0.82rem/1.5 var(--font-body); letter-spacing: 0; text-transform: none;
  color: var(--muted);
}
.tipbtn:hover + .tipbox, .tipbtn:focus + .tipbox, .tipbtn:focus-visible + .tipbox { display: block; }

/* The footer row. Two laws learned the hard way: CENTER, never stretch (stretch made
   the button adopt the Turnstile widget's 70px height), and the widget is a
   FIXED-SIZE third-party box, so it gets a fixed-size seat (flex none): squeezing it
   with a flexible basis made it paint outside its box and under the button. */
.rigfoot { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; }
.rigfoot .grader-turnstile { flex: 0 0 auto; display: flex; align-items: center; }
.rigfoot .btn { flex: 1 1 220px; min-height: 46px; max-height: 54px; }
.rigform .form-note { font-size: 0.8rem; color: var(--faint); margin: 0; }
.rigform .form-note a { color: var(--muted); }

@media (max-width: 900px) {
  .rig-grid { grid-template-columns: 1fr; gap: 34px; }
  .rtwo, .aicards { grid-template-columns: 1fr; }
  .rigfoot { flex-direction: column; }
}
/* a 335 px form (a 375 px phone inside the site's 20 px gutter) needs a 305 px content box for the
   300 px Turnstile widget to sit inside it whole */
@media (max-width: 600px) {
  .rigform-body { padding-inline: 14px; }
}
@media (prefers-reduced-motion: reduce) { .rlive::before { animation: none; } }

/* W-10 (the website audit of 2026-09-19): the one field on the free form that makes a
   visitor hesitate, answered where they hesitate. The phone is REQUIRED by the owner's
   ruling of 2026-08-19 and grader.js leans on it for the map match, the website ownership
   test and the identity tie-breaker, so the field is not coming off; what it was missing
   was a reason. Tied to the input with aria-describedby, so a screen reader hears it too. */
.rfield .fhint {
  margin: 5px 0 0;
  font-size: 0.72rem;
  line-height: 1.45;
  color: var(--faint);
}

/* THE OPTIONAL MARKER HAD NO STYLE AT ALL (B-2, plan of record eco
   docs/market-intel-checkout-2026-09-20.html section 5). `.fopt` was written into the
   money pages' labels and never defined in any sheet, so it inherited the label's own
   uppercase mono and read as part of the field's NAME: "BUSINESS NAME OPTIONAL FOR THE
   MARKET REPORT" in one unbroken run, which tells a reader nothing about whether they
   have to fill it in. It is a note about the field, so it is set like one: lower case, no
   tracking, dimmer, behind a middot. Kept INLINE rather than pushed to the end of the
   line, because a label and a marker in a flex row have nowhere to go on a 375px phone
   and the marker is the part that would be cut. */
.rfield .flabel .fopt {
  font-size: 0.68rem;
  letter-spacing: 0;
  text-transform: none;
  font-weight: 400;
  color: var(--faint);
}
.rfield .flabel .fopt::before { content: "\00b7"; margin: 0 5px; color: var(--line-2); }
