* {
  box-sizing: border-box;
}

/* Every colour here is chosen against a measured contrast ratio, not by eye.
   The ratios in the comments are WCAG 2.1 relative-luminance figures against
   --bg unless stated otherwise. AA needs 4.5:1 for normal text and 3:1 for
   the boundary of an interactive component (SC 1.4.3, 1.4.11). */
:root {
  --bg: #0b0b0f;
  --card: #16161d;
  --sunk: #0f0f15; /* inset fields, sitting below the card */

  /* Text: three steps, all of which pass AA at the sizes they're used at.
     --ink used to be #f2f2f5 (17.6:1). That passes everything and is still
     too hot: near-white on near-black haloes for readers with astigmatism,
     which is why Material's dark-theme guidance caps emphasis below pure
     white. 14.4:1 is past AAA with the glare taken off. */
  --ink: #dcdce4; /* 14.41:1 */
  --muted: #9a9aa8; /*  7.07:1 -- secondary copy, hints, labels */
  --quiet: #8b8b99; /*  5.85:1 -- footers and legal small print */

  /* Borders. --line is decorative only (card outlines, dividers): it is
     1.39:1 and would fail 1.4.11 if it were carrying meaning. Anything a
     person can type in, tap, or focus gets --edge instead. */
  --line: #2a2a35;
  --edge: #6b6b7b; /* 3.76:1 bg, 3.44:1 card -- passes 1.4.11 */

  /* The two sides. Blue against amber, not blue against red: red/green
     deficiency affects roughly 8% of men, and this pair stays separable
     under all common types because it differs on luminance as well as hue.
     Colour is never the only cue -- each side also carries its own text,
     a position, and an A/B marker. */
  --a: #4f8cff; /* 6.11:1 -- side A, links, accents */
  --b: #f0a742; /* 9.65:1 -- side B */

  /* Side B used to be #ff6b5e, which was also the error colour. Side B was
     literally painted as a mistake. Errors now have their own token. */
  --error: #ff8577; /* 8.30:1 */
  --ok: #5cd39a; /* 10.51:1 */

  /* White on #4f8cff is 3.22:1 -- the primary button on every page failed
     AA for its own label. This fill carries white at 5.07:1 and still holds
     3.88:1 against the page, so the button's edge is visible too. */
  --btn: #356ad2; /* white label 5.07:1 */
  --btn-hover: #2f63c8; /* darker, not lighter: lightening the fill drops the
                           white label back under 4.5:1 */
  --focus: #8ab4ff; /* 9.40:1 against every surface here */
}

html,
body {
  margin: 0;
  min-height: 100%;
  background: var(--bg);
  color: var(--ink);
  font-family:
    -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  font-size: 100%; /* honour the reader's browser setting; never below 16px */
  line-height: 1.6; /* WCAG 1.4.8 asks 1.5+ for blocks of text */
  -webkit-text-size-adjust: 100%;
}

/* One visible focus style for everything, so keyboard users can always see
   where they are. :focus-visible rather than :focus so it doesn't fire on
   mouse clicks. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: 6px;
}

/* Links in prose need to be identifiable without relying on colour. */
.card a:not(.cta):not(.ghost):not(.ghostBtn):not(.shareBtn) {
  color: var(--a);
  text-underline-offset: 2px;
}

.wrap {
  max-width: 560px;
  margin: 0 auto;
  padding: 28px 18px 60px;
}

.head {
  text-align: center;
  margin-bottom: 22px;
}
h1 {
  font-size: 2rem;
  margin: 0 0 6px;
  letter-spacing: -0.02em;
}
.sub {
  color: var(--muted);
  margin: 0;
  font-size: 0.98rem;
}

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 18px;
}

.field {
  display: block;
  position: relative;
  margin-bottom: 14px;
}
.label {
  display: block;
  font-size: 0.82rem;
  color: var(--muted);
  margin-bottom: 6px;
}
input {
  width: 100%;
  min-height: 48px; /* Material's 48dp floor; comfortably past WCAG 2.5.8 */
  padding: 12px 13px;
  font-family: inherit;
  font-size: 1rem; /* 16px or iOS zooms the page on focus */
  color: var(--ink);
  background: var(--sunk);
  /* --line here was 1.39:1: the edge of the field was invisible, which is
     exactly what SC 1.4.11 exists to prevent. */
  border: 1px solid var(--edge);
  border-radius: 10px;
}
input:focus-visible {
  border-color: var(--focus);
}
.count {
  position: absolute;
  right: 4px;
  top: 0;
  font-size: 0.72rem;
  color: var(--muted);
}

.options {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
@media (max-width: 420px) {
  .options {
    grid-template-columns: 1fr;
  }
}

button {
  font-family: inherit;
  cursor: pointer;
}

#submitBtn,
.cta,
#copyBtn {
  width: 100%;
  min-height: 48px;
  padding: 13px;
  font-size: 1rem;
  font-weight: 600;
  color: #ffffff;
  background: var(--btn);
  border: none;
  border-radius: 10px;
  display: block;
  text-align: center;
  text-decoration: none;
  margin-top: 4px;
}
#submitBtn:hover,
.cta:hover,
#copyBtn:hover {
  background: var(--btn-hover);
}
#submitBtn:disabled {
  background: #3a3a46;
  /* The old disabled state was #3a3a46 behind white text: 2.1:1, an
     unreadable label on the one control people are waiting on. */
  color: #b9b9c4;
  cursor: not-allowed;
}
#copyBtn {
  width: auto;
  padding: 12px 16px;
  margin: 0;
}

.status {
  min-height: 1.3em;
  margin: 12px 0 0;
  font-size: 0.9rem;
  color: var(--muted);
  text-align: center;
}
.status.error {
  color: var(--error);
}
.status.ok {
  color: var(--ok);
}

.hidden {
  display: none;
}

.resultLead {
  margin: 0 0 12px;
  font-weight: 600;
}
.linkRow {
  display: flex;
  gap: 8px;
}
.linkRow input {
  font-size: 0.9rem;
}
.hint {
  color: var(--muted);
  font-size: 0.85rem;
  margin: 12px 0;
}
.ghost {
  color: var(--a);
  text-decoration: none;
  font-size: 0.92rem;
}

.duplicateBox {
  margin-top: 12px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--sunk);
  text-align: center;
}
.duplicateBox p {
  margin: 0 0 6px;
  font-size: 0.88rem;
  color: var(--muted);
}
.duplicateBox .ghost {
  display: block;
  margin-bottom: 10px;
}

.editBox {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  text-align: center;
}
.editRow {
  display: flex;
  gap: 8px;
  justify-content: center;
}
.editRow .ghostBtn {
  margin-top: 0;
  flex: 1;
  border: 1px solid var(--edge);
  border-radius: 10px;
  background: none;
}

/* vote page */
.question {
  font-size: 1.5rem;
  text-align: center;
  margin: 10px 0 22px;
  line-height: 1.3;
}
.sides {
  display: grid;
  gap: 12px;
}
.side {
  position: relative;
  overflow: hidden;
  min-height: 92px;
  padding: 20px 18px;
  font-size: 1.12rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--edge);
  border-radius: 14px;
  text-align: left;
  transition: transform 0.12s ease;
}
.side:active {
  transform: scale(0.985);
}
.side .sideText {
  position: relative;
  z-index: 2;
}
.side .pct {
  position: relative;
  z-index: 2;
  float: right;
  font-variant-numeric: tabular-nums;
  opacity: 0;
  transition: opacity 0.25s ease;
}
.side .pct.show {
  opacity: 1;
}
/* The fill bar that reveals the split. 300ms, not 500: long enough to read
   as "this is being counted", short enough that nobody waits on it. */
.side::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--fill, 0%);
  background: var(--tint, #333);
  opacity: 0.28;
  transition: width 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
  z-index: 1;
}
#sideA {
  --tint: var(--a);
}
#sideB {
  --tint: var(--b);
}
.side.picked {
  border-color: var(--ink);
}

.verdict {
  text-align: center;
  font-size: 1.05rem;
  margin: 18px 0 14px;
}

/* The footer was #55555f at 2.67:1, and its Terms and Privacy links had no
   colour rule at all -- so they fell back to the browser's default link
   blue, 2.09:1 unvisited and 1.78:1 once visited. The two links a person is
   most entitled to be able to read were the least readable text on the
   site. Both now pass AA. */
.foot {
  margin-top: 26px;
  text-align: center;
  font-size: 0.8rem;
  color: var(--quiet);
  line-height: 1.6;
}
.foot a {
  color: var(--muted);
  text-decoration: underline;
  text-underline-offset: 2px;
  /* 44px of vertical room around footer links on touch, without visually
     spacing the sentence apart (WCAG 2.5.8). */
  display: inline-block;
  padding: 6px 2px;
}
.foot a:hover {
  color: var(--ink);
}

/* Reporting is a safety control. It was #55555f -- 2.67:1 -- which made the
   one way to flag something harmful the hardest thing on the page to see. */
.reportLink {
  display: block;
  min-height: 44px;
  margin: 10px auto 0;
  padding: 10px 14px;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 0.85rem;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.reportLink:hover {
  color: var(--ink);
}

/* ---- feed ---- */
.feedItem {
  display: block;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 16px;
  margin-bottom: 10px;
  text-decoration: none;
  color: var(--ink);
}
.feedItem.promoted {
  border-color: #3d3d52;
  background: #191922;
}
/* Paid placement has to be obvious, not tasteful-and-invisible: the FTC's
   native-advertising guidance is about whether an ordinary person actually
   notices the label. Bumped from 0.66rem to 0.72rem with a visible edge,
   and the word is now "Paid promotion" rather than "Promoted" (see
   browse.js) because "promoted" doesn't tell anyone money changed hands. */
.promotedTag {
  display: inline-block;
  font-size: 0.72rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #b6b6c8;
  border: 1px solid var(--edge);
  border-radius: 999px;
  padding: 3px 9px;
  margin-bottom: 8px;
}
.feedQ {
  font-size: 1.05rem;
  margin: 0 0 10px;
  line-height: 1.35;
}
.feedSides {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}
.feedSide {
  font-size: 0.88rem;
  background: var(--sunk);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 5px 9px;
}
/* The feed used to print a bare "50/50", which tells you the split but not
   which side is which. The percentage now travels with the side it belongs
   to (see browse.js). */
.feedSide b {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
.feedSide.isA b {
  color: var(--a);
}
.feedSide.isB b {
  color: var(--b);
}
.feedVs {
  font-size: 0.72rem;
  color: var(--muted);
}
.feedMeta {
  margin: 0;
  font-size: 0.78rem;
  color: var(--muted);
}

/* ---- promote ---- */
.promoteBox {
  margin-top: 18px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  text-align: center;
}
.promoteBox p {
  margin: 0 0 10px;
  font-size: 0.88rem;
  color: var(--muted);
}
.navRow {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 4px 16px;
  margin-bottom: 18px;
  font-size: 0.95rem;
}
.navRow a {
  display: inline-block;
  min-height: 44px;
  padding: 10px 6px;
  color: var(--a);
  text-decoration: none;
}
.navRow a:hover {
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* landing: vote first */
.orLine {
  text-align: center;
  color: var(--muted);
  font-size: 0.85rem;
  margin: 16px 0 14px;
}
.ghostBtn {
  display: block;
  width: 100%;
  min-height: 44px;
  text-align: center;
  margin-top: 10px;
  padding: 11px;
  background: none;
  border: none;
  color: var(--a);
  text-decoration: none;
  font-size: 0.95rem;
}
.mineHead {
  margin: 0 0 10px;
  font-size: 0.82rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.mineItem {
  display: block;
  padding: 10px 0;
  border-top: 1px solid var(--line);
  color: var(--ink);
  text-decoration: none;
  font-size: 0.95rem;
}
.mineItem:first-child {
  border-top: none;
}
.mineItem span {
  display: block;
  color: var(--muted);
  font-size: 0.78rem;
  margin-top: 2px;
}

/* browse: tabs + search */
.tabs {
  display: flex;
  gap: 6px;
  margin-bottom: 12px;
  overflow-x: auto;
}
.tab {
  flex: 0 0 auto;
  min-height: 44px; /* was ~33px: under the 44px target-size floor */
  padding: 10px 16px;
  font-size: 0.9rem;
  color: var(--muted);
  background: var(--card);
  border: 1px solid var(--edge);
  border-radius: 999px;
}
/* The selected tab can't be signalled by colour alone (SC 1.4.1), so it also
   gets a heavier weight and a filled edge, and browse.js sets
   aria-selected so it's announced. */
.tab.is-on {
  color: var(--ink);
  font-weight: 600;
  border-color: var(--a);
  background: #1c2440;
}
.searchBox {
  margin-bottom: 14px;
}

/* share row */
.shareRow {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: center;
  margin: 6px 0 14px;
}
.shareBtn {
  display: inline-flex;
  align-items: center;
  min-height: 44px; /* was ~32px */
  padding: 10px 14px;
  font-size: 0.88rem;
  color: var(--ink);
  background: var(--sunk);
  border: 1px solid var(--edge);
  border-radius: 999px;
  text-decoration: none;
  cursor: pointer;
}
.shareBtn:hover {
  border-color: var(--a);
  color: var(--ink);
}

/* ---- ownership: the differentiator, so it gets real estate ---- */
.ownershipNote {
  margin: 10px 0 0;
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--muted);
  text-align: center;
}
.ownershipBox {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  text-align: center;
}
.ownedLead {
  margin: 0 0 6px;
  font-weight: 600;
  font-size: 0.95rem;
}
.ownershipBox .ghost {
  display: block;
  margin: 10px 0;
}
.provenanceLine {
  text-align: center;
  font-size: 0.78rem;
  color: var(--quiet);
  margin: -14px 0 18px;
}

/* ---- dashboard chart ---- */
.chart {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 100px;
  overflow-x: auto;
  padding-top: 6px;
}
.chartBar {
  flex: 0 0 auto;
  width: 10px;
  min-height: 2px;
  background: var(--a);
  border-radius: 3px 3px 0 0;
}
.chartEmpty {
  color: var(--muted);
  font-size: 0.85rem;
}

/* "also built by" — quiet, one item, at a completion moment only */
.alsoBox {
  margin-top: 22px;
  padding: 14px 16px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 12px;
  text-align: left;
}
.alsoHead {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  font-size: 0.75rem;
  /* Uppercase loses ascenders and descenders, so it needs extra tracking to
     stay readable at small sizes. */
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--quiet);
  margin-bottom: 8px;
}
.alsoX {
  flex: 0 0 auto;
  min-width: 44px; /* a dismiss control has to be hittable */
  min-height: 44px;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 1.25rem;
  line-height: 1;
}
.alsoX:hover {
  color: var(--ink);
}
.alsoItem {
  display: block;
  text-decoration: none;
  color: var(--ink);
}
.alsoItem strong {
  display: block;
  font-size: 1rem;
  margin-bottom: 3px;
}
.alsoItem span {
  display: block;
  font-size: 0.84rem;
  color: var(--muted);
  line-height: 1.4;
}
.alsoItem:hover strong {
  color: var(--a);
}
/* Was #44444d text (2.04:1) with #55555f links (2.67:1). Kept visually
   recessive by size rather than by being too faint to read. */
.madeBy {
  margin-top: 10px;
  font-size: 0.78rem;
  color: var(--quiet);
}
.madeBy a {
  color: var(--muted);
}

/* ---------------------------------------------------------------------------
   Shared primitives
   --------------------------------------------------------------------------- */

/* Text for screen readers only. Not display:none, which removes it from the
   accessibility tree as well. */
.srOnly {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Skip link: the first thing a keyboard user hits, hidden until focused. */
.skipLink {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 20;
  padding: 12px 16px;
  background: var(--card);
  border: 1px solid var(--focus);
  border-radius: 0 0 10px 0;
  color: var(--ink);
  text-decoration: none;
}
.skipLink:focus {
  left: 0;
}

/* Honour the reader's motion preference. SC 2.3.3: motion from interaction
   must be suppressible. Transitions become instant rather than being
   removed, so nothing depends on a transitionend that never fires. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .side:active {
    transform: none;
  }
}

/* ---- toggletip: the small "what does this mean?" helper ----
   A button, not a hover tooltip. Hover-only help is unreachable on every
   touch device and by keyboard, and the title attribute is invisible to
   most screen readers. This opens on click, closes on Escape or outside
   click, and stays open while it's read (SC 1.4.13). */
.tipWrap {
  display: inline;
  position: relative;
  white-space: nowrap;
}
.tipBtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  margin-left: 2px;
  padding: 0;
  vertical-align: -4px;
  font-size: 0.78rem;
  font-weight: 700;
  line-height: 1;
  color: var(--muted);
  background: none;
  border: 1px solid var(--edge);
  border-radius: 999px;
}
.tipBtn:hover {
  color: var(--ink);
  border-color: var(--a);
}
/* The 22px circle is the visible mark; this pushes the actual hit area out
   to 44px without pushing the text around it apart. */
.tipBtn::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
}
.tip {
  position: absolute;
  z-index: 10;
  left: 0;
  top: calc(100% + 8px);
  width: min(300px, calc(100vw - 48px));
  padding: 12px 14px;
  font-size: 0.88rem;
  font-weight: 400;
  line-height: 1.55;
  white-space: normal;
  text-align: left;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--edge);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgb(0 0 0 / 55%);
}
.tip[hidden] {
  display: none;
}
.tip p {
  margin: 0 0 8px;
}
.tip p:last-child {
  margin-bottom: 0;
}
.tip a {
  color: var(--a);
}

/* ---- dialog: used by the report flow ----
   window.prompt() was doing this job. Browsers are free to suppress it, it
   cannot be labelled or described, and it can't be styled or translated. */
.sheet {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 18px;
  background: rgb(0 0 0 / 70%);
}
.sheet[hidden] {
  display: none;
}
.sheetCard {
  width: 100%;
  max-width: 420px;
  padding: 20px;
  background: var(--card);
  border: 1px solid var(--edge);
  border-radius: 14px;
}
.sheetCard h2 {
  margin: 0 0 8px;
  font-size: 1.15rem;
}
.sheetCard p {
  margin: 0 0 14px;
  font-size: 0.9rem;
  color: var(--muted);
}
.sheetCard textarea {
  width: 100%;
  min-height: 92px;
  padding: 12px 13px;
  font-family: inherit;
  font-size: 1rem;
  line-height: 1.5;
  color: var(--ink);
  background: var(--sunk);
  border: 1px solid var(--edge);
  border-radius: 10px;
  resize: vertical;
}
.sheetCard textarea:focus-visible {
  border-color: var(--focus);
}
.sheetRow {
  display: flex;
  gap: 8px;
  margin-top: 14px;
}
.sheetRow .cta,
.sheetRow .ghostBtn {
  margin-top: 0;
  flex: 1;
}
.sheetRow .ghostBtn {
  border: 1px solid var(--edge);
  border-radius: 10px;
}

/* ---- long-form pages: help, terms, privacy, guidelines ----
   The 560px column is about 65 characters at 16px, which is inside the
   50-75 range that reads fastest. Keeping it means these pages don't need
   their own measure. */
.prose h2 {
  margin: 26px 0 8px;
  font-size: 1.12rem;
  line-height: 1.35;
}
.prose h2:first-child {
  margin-top: 0;
}
.prose h3 {
  margin: 20px 0 6px;
  font-size: 0.98rem;
  color: var(--ink);
}
.prose p,
.prose li {
  margin: 0 0 12px;
  font-size: 0.98rem;
  line-height: 1.65;
}
.prose ul {
  margin: 0 0 12px;
  padding-left: 22px;
}
.prose li {
  margin-bottom: 8px;
}
.prose strong {
  color: var(--ink);
}
.prose .lead {
  font-size: 1.05rem;
  color: var(--ink);
}
.prose .aside {
  margin: 16px 0;
  padding: 14px 16px;
  background: var(--sunk);
  border: 1px solid var(--line);
  border-left: 3px solid var(--a);
  border-radius: 0 10px 10px 0;
}
.prose .aside p:last-child {
  margin-bottom: 0;
}
.prose dl {
  margin: 0;
}
.prose dt {
  margin-top: 18px;
  font-weight: 600;
}
.prose dd {
  margin: 6px 0 0;
  color: var(--muted);
  font-size: 0.96rem;
  line-height: 1.65;
}
.updated {
  margin: 0 0 18px;
  font-size: 0.85rem;
  color: var(--quiet);
}

/* A plain contents list at the top of long pages. Anchors, not an
   accordion: people need to compare sections in legal text, and accordions
   make that worse (NN/g on accordions and complex content). */
.toc {
  margin: 0 0 22px;
  padding: 14px 16px;
  background: var(--sunk);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.toc p {
  margin: 0 0 8px;
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--quiet);
}
.toc ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
.toc li {
  margin: 0;
}
.toc a {
  display: block;
  padding: 7px 0;
  font-size: 0.94rem;
  color: var(--a);
  text-decoration: none;
}
.toc a:hover {
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Price breakdown shown before any pay button. Total, what you get, what
   happens next -- in that order, and never behind a click. */
.priceCard {
  margin: 0 0 12px;
  padding: 14px 16px;
  text-align: left;
  background: var(--sunk);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.priceRow {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 10px;
}
.priceRow strong {
  font-size: 1.05rem;
}
.priceRow span {
  font-size: 0.82rem;
  color: var(--muted);
}
.priceList {
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 0.9rem;
  color: var(--muted);
}
.priceList li {
  position: relative;
  margin: 0 0 6px;
  padding-left: 20px;
  line-height: 1.5;
}
.priceList li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 0.45em;
  width: 9px;
  height: 5px;
  border-left: 2px solid var(--ok);
  border-bottom: 2px solid var(--ok);
  transform: rotate(-45deg);
}
/* Shown only once an argument has actually travelled -- the moment the
   permanence upsell means something. States the reason, never a deadline:
   the offer does not expire and pretending it does would be a dark pattern. */
.anchorWhy {
  margin: 0 0 12px;
  padding: 12px 14px;
  font-size: 0.9rem;
  line-height: 1.55;
  text-align: left;
  color: var(--ink);
  background: var(--sunk);
  border: 1px solid var(--line);
  border-left: 3px solid var(--b);
  border-radius: 0 10px 10px 0;
}
.anchorWhy.hidden {
  display: none;
}
/* A quieter border while the argument hasn't earned the pitch yet. */
#anchorOffer:not(.earned) .priceCard {
  opacity: 0.92;
}

/* Live slot count. Real inventory, so it gets stated plainly rather than
   dressed up as scarcity -- no red, no countdown, no "hurry". */
.slots {
  margin: 10px 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--line);
  font-size: 0.85rem;
  color: var(--muted);
}
.slots:empty {
  display: none;
}

.priceList li.no::before {
  /* A plain dash, for the "this is what it does NOT do" lines. */
  top: 0.65em;
  width: 9px;
  height: 0;
  border-left: none;
  border-bottom: 2px solid var(--quiet);
  transform: none;
}

/* Consent line, shown next to the action it applies to rather than buried
   in the footer -- a link at the bottom of a page is browsewrap and courts
   have declined to enforce it. */
.consent {
  margin: 12px 0 0;
  font-size: 0.8rem;
  line-height: 1.55;
  color: var(--quiet);
  text-align: center;
}
.consent a {
  color: var(--muted);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ---- receipt page ---- */
.receiptQ {
  margin: 0 0 12px;
  font-size: 1.25rem;
  line-height: 1.35;
}
.receiptFacts {
  margin: 14px 0 0;
}
.receiptFacts dt {
  margin-top: 14px;
  font-size: 0.78rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--quiet);
}
.receiptFacts dd {
  margin: 4px 0 0;
  font-size: 0.95rem;
  color: var(--ink);
}
/* Hashes and key ids are meant to be compared character by character, so
   they get a monospace face and are allowed to wrap anywhere rather than
   overflowing a phone. */
.mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.85rem !important;
  overflow-wrap: anywhere;
  color: var(--muted) !important;
}
.certPreview {
  display: block;
  width: 100%;
  height: auto;
  margin: 4px 0 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fdfbf5;
}

/* Copy-pasteable commands. Horizontally scrollable rather than wrapped:
   a broken line in a shell command is worse than a scrollbar. */
.code {
  margin: 12px 0;
  padding: 14px 16px;
  overflow-x: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--ink);
  background: var(--sunk);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.prose code {
  padding: 2px 5px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.88em;
  background: var(--sunk);
  border: 1px solid var(--line);
  border-radius: 5px;
}

/* ---- skip / save-for-later, and the saved list ---- */

/* Quiet by design. These sit under the two side buttons and must not
   compete with them -- the primary action is still "pick a side". They use
   --muted (7.07:1) rather than --quiet so they stay legible as controls,
   and every one is a full 44px target because they are frequently the last
   thing tapped before someone gives up on a question. */
.altRow {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  justify-content: center;
  margin: 10px 0 4px;
}
.altLead {
  font-size: 0.88rem;
  color: var(--quiet);
}
.altBtn {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 8px 14px;
  font-size: 0.88rem;
  font-family: inherit;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 999px;
  text-decoration: none;
  cursor: pointer;
}
.altBtn:hover {
  color: var(--ink);
  border-color: var(--edge);
}
/* Pressed state is carried by the label text too ("Saved — remove"), not by
   colour alone. */
.altBtn[aria-pressed="true"] {
  color: var(--ink);
  border-color: var(--b);
}

.savedWrap {
  position: relative;
  margin-left: auto;
}
.savedBtn {
  min-height: 44px;
  padding: 6px 12px;
  font-size: 0.92rem;
  font-family: inherit;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
}
.savedBtn:hover,
.savedBtn[aria-expanded="true"] {
  color: var(--ink);
  border-color: var(--edge);
}

/* Anchored to the nav rather than fixed to the viewport edge. A rail down
   the side costs a third of the width on a phone, and most arrivals here
   are a phone following a shared link. */
.savedPanel {
  position: absolute;
  right: 0;
  z-index: 40;
  width: min(320px, calc(100vw - 32px));
  max-height: 60vh;
  margin-top: 8px;
  padding: 12px 14px;
  overflow-y: auto;
  text-align: left;
  background: var(--card);
  border: 1px solid var(--edge);
  border-radius: 12px;
  box-shadow: 0 10px 30px rgb(0 0 0 / 45%);
}
.savedList {
  margin: 0;
  padding: 0;
  list-style: none;
}
.savedList li {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  justify-content: space-between;
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
}
.savedList a {
  flex: 1;
  font-size: 0.92rem;
  line-height: 1.35;
  color: var(--ink);
}
.savedRemove {
  flex: none;
  min-height: 44px;
  padding: 4px 8px;
  font-size: 0.82rem;
  font-family: inherit;
  color: var(--muted);
  background: none;
  border: 0;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.savedRemove:hover {
  color: var(--error);
}
.savedEmpty {
  margin: 6px 0 0;
  font-size: 0.85rem;
  line-height: 1.45;
  color: var(--quiet);
}
.savedFoot {
  margin-top: 10px;
}

/* Server-rendered crawl list. Replaced by the interactive feed the moment
   browse.js runs, so this is what crawlers and no-JS readers see. Styled
   rather than hidden: a no-JS reader should get a usable list, not a
   penalty, and hidden links are exactly what a search engine treats as
   cloaking. */
.crawlList {
  margin: 0;
  padding: 0;
  list-style: none;
}
.crawlList li {
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
}
.crawlList a {
  display: block;
  font-size: 1rem;
  line-height: 1.35;
  color: var(--ink);
}
.crawlList span {
  display: block;
  margin-top: 4px;
  font-size: 0.85rem;
  color: var(--quiet);
}
.crawlMore {
  display: inline-block;
  margin-top: 14px;
  color: var(--a);
}

/* ---- answered / not answered filter ---- */
.answeredTabs {
  margin-top: -6px;
}
.answeredNote {
  margin: -4px 0 14px;
  font-size: 0.85rem;
  color: var(--quiet);
}
/* Answered items stay fully legible -- they are not "done" or lesser, and
   dimming them would fail contrast for the sake of decoration. The marker
   carries the meaning in words instead. */
.answeredTag {
  display: inline-block;
  margin-bottom: 6px;
  padding: 2px 8px;
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--b);
  border: 1px solid var(--b);
  border-radius: 999px;
}
.feedItem.isAnswered {
  border-left: 3px solid var(--b);
}

/* Lines inside a toggletip. These were <p> elements, which are invalid inside
   a <span> and were additionally nested inside <p class="hint"> -- so the
   parser closed both containers on the first one and the tip contents escaped
   onto the page permanently, visible to everyone. That defeated the whole
   purpose of moving jargon into a toggletip. Block-styled spans are legal
   phrasing content and stay where they are put. */
.tipLine {
  display: block;
}
.tipLine + .tipLine {
  margin-top: 8px;
}

/* ---- "Your record": the one-off personal report ---- */
.ephemeral {
  border-left: 3px solid var(--a);
}
.verdictCard {
  text-align: center;
}
.archetype {
  margin: 6px 0 10px;
  font-size: 1.75rem;
  line-height: 1.15;
  color: var(--b);
}
.archetypeWhy {
  margin: 0;
  font-size: 0.98rem;
  line-height: 1.5;
  color: var(--muted);
}

.statGrid {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  margin: 14px 0;
}
.statTile {
  padding: 14px;
  text-align: center;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 12px;
}
.statNum {
  margin: 0;
  font-size: 1.9rem;
  line-height: 1;
  color: var(--ink);
}
.statLabel {
  margin: 6px 0 0;
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}
.statNote {
  margin: 4px 0 0;
  font-size: 0.78rem;
  color: var(--quiet);
}

.repBar {
  margin: 12px 0;
}
.repBarHead {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 6px;
  font-size: 0.9rem;
  color: var(--muted);
}
.repTrack {
  height: 10px;
  background: var(--sunk);
  border: 1px solid var(--line);
  border-radius: 999px;
  overflow: hidden;
}
.repFill {
  height: 100%;
  background: var(--a);
}

.repRow {
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
}
.repRow:last-child {
  border-bottom: 0;
}
.repRow a {
  display: block;
  font-size: 0.95rem;
  line-height: 1.35;
  color: var(--ink);
}
.repMeta {
  display: block;
  margin-top: 4px;
  font-size: 0.82rem;
  color: var(--quiet);
}
.lonelyQ {
  margin: 0 0 8px;
  font-size: 1.15rem;
  line-height: 1.35;
  color: var(--ink);
}

.printOnly {
  display: none;
}

/* Print, which is also how "Save as PDF" works in every browser -- so this
   IS the PDF exporter. No dependency, no server round trip, and the file
   never leaves the machine.
   Inverted to ink on paper: the screen palette would consume a print
   cartridge and read badly on white. */
@media print {
  .noPrint,
  .skipLink {
    display: none !important;
  }
  .printOnly {
    display: block;
  }
  body {
    background: #fff;
    color: #111;
  }
  .wrap {
    max-width: none;
    padding: 0;
  }
  .card,
  .statTile {
    background: #fff;
    border: 1px solid #bbb;
    /* Keeps a card from being split across two pages mid-sentence. */
    break-inside: avoid;
  }
  .archetype {
    color: #7a1f1a;
  }
  .archetypeWhy,
  .statLabel,
  .statNote,
  .repMeta,
  .hint,
  .repBarHead {
    color: #444;
  }
  .statNum,
  .repRow a,
  .lonelyQ,
  h1 {
    color: #111;
  }
  .repTrack {
    background: #eee;
    border-color: #bbb;
  }
  .repFill {
    background: #666;
  }
  /* The URL behind each link, since a printed link is useless otherwise. */
  .repRow a::after {
    content: " (" attr(href) ")";
    font-size: 0.75rem;
    color: #666;
  }
}
.savedRecordLink {
  display: inline-block;
  margin-top: 8px;
  font-size: 0.85rem;
}

/* The shareable card, drawn client-side. Displayed at whatever width is
   available; the canvas itself is always 1200x630 so the saved file is the
   right size for a social preview regardless of the screen it was made on. */
.shareCanvas {
  display: block;
  width: 100%;
  height: auto;
  margin: 10px 0 12px;
  background: var(--sunk);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.consentRow {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  margin: 12px 0;
  font-size: 0.92rem;
  line-height: 1.45;
  color: var(--muted);
  cursor: pointer;
}
.consentRow input {
  flex: none;
  width: 22px;
  height: 22px;
  margin-top: 1px;
  accent-color: var(--a);
}
