/* Your Racquet championship theme.
   Deliberately single-theme: lawn green, championship purple, cream, gold.
   Mobile-first; desktop layout enters at 760px. */

:root {
  --court-dark: #0f2b1b;
  --lawn: #1c5b38;
  --purple: #3d2b56;
  --gold: #a8842c;
  --gold-soft: #cbb46a;
  --ball: #cfe23a;

  --page: #f6f2e7;
  --surface: #fffdf7;
  --ink: #1c1b12;
  --ink-2: #56523d;
  --muted: #8a8672;
  --grid: #e7e1cf;
  --baseline: #cfc9b4;
  --border: rgba(28, 27, 18, 0.12);

  /* data colors, validated on --surface (see dataviz validator) */
  --data-1: #1f9d55;
  --data-hot: #d05c3b;
  --data-3: #7a5cc4;
  --data-deep: #14683a;
  --pool: #9a9682;
  --band: rgba(31, 157, 85, 0.09);
  --band-edge: rgba(31, 157, 85, 0.32);
  --halo: #fffdf7;

  --serif: "Playfair Display", Georgia, "Times New Roman", serif;
  --sans: "Libre Franklin", system-ui, -apple-system, "Segoe UI", sans-serif;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--page);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.55;
}

.shell { max-width: 1080px; margin: 0 auto; padding: 0 18px; }

a { color: var(--lawn); text-decoration-color: var(--gold-soft); text-underline-offset: 2px; }
a:hover { color: var(--data-deep); }
:focus-visible { outline: 2px solid var(--purple); outline-offset: 2px; }

/* ---------------------------------------------------------------- masthead */

.masthead {
  background: var(--court-dark);
  color: #f3efdf;
  border-bottom: 3px solid var(--gold);
}
.masthead-inner {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 22px;
  padding-top: 14px; padding-bottom: 10px;
}
.wordmark {
  display: inline-flex; align-items: center; gap: 10px;
  color: #f3efdf; text-decoration: none;
}
.mark { width: 30px; height: 30px; }
.wordmark-text {
  font-family: var(--serif); font-weight: 700; font-size: 21px; letter-spacing: 0.01em;
}
.nav {
  display: flex; gap: 2px; overflow-x: auto; -webkit-overflow-scrolling: touch;
  margin-left: -8px; width: 100%;
}
.nav a {
  color: #cfc9b4; text-decoration: none; font-size: 13.5px; font-weight: 600;
  letter-spacing: 0.04em; text-transform: uppercase;
  padding: 9px 12px 11px; white-space: nowrap; border-bottom: 3px solid transparent;
  margin-bottom: -13px;
}
.nav a:hover { color: #fff; }
.nav a.on { color: #fff; border-bottom-color: var(--ball); }

@media (min-width: 760px) {
  .nav { width: auto; margin-left: auto; }
}

/* -------------------------------------------------------------------- hero */

.hero {
  background:
    radial-gradient(120% 180% at 85% -30%, rgba(61, 43, 86, 0.55) 0%, rgba(61, 43, 86, 0) 55%),
    linear-gradient(170deg, #123722 0%, var(--court-dark) 70%);
  color: #f3efdf;
  padding: 44px 0 46px;
  border-bottom: 3px solid var(--gold);
  position: relative;
  overflow: hidden;
}
.hero::after {   /* court sideline motif */
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(to right, transparent calc(50% - 1px), rgba(243, 239, 223, 0.07) calc(50% - 1px), rgba(243, 239, 223, 0.07) calc(50% + 1px), transparent calc(50% + 1px)),
    linear-gradient(to bottom, transparent calc(100% - 44px), rgba(243, 239, 223, 0.09) calc(100% - 44px), rgba(243, 239, 223, 0.09) calc(100% - 42px), transparent calc(100% - 42px));
  pointer-events: none;
}
.hero-compact { padding: 34px 0 36px; }
.hero-eyebrow {
  margin: 0 0 12px; font-size: 12px; font-weight: 700; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--gold-soft);
}
.hero-title {
  font-family: var(--serif); font-weight: 800;
  font-size: clamp(30px, 6.2vw, 52px); line-height: 1.06; letter-spacing: -0.01em;
  margin: 0 0 16px; text-wrap: balance; max-width: 21ch;
}
.hero-dek { max-width: 62ch; margin: 0; font-size: 16.5px; color: #d8d3bd; }
.hero-dek strong { color: #fff; font-weight: 600; }
.hero-dek a { color: var(--ball); }

/* ---------------------------------------------------------------- sections */

main { padding-bottom: 40px; }
section { margin-top: 56px; }
.eyebrow {
  display: flex; align-items: center; gap: 8px; margin: 0 0 6px;
  font-size: 12px; font-weight: 700; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--purple);
}
.eyebrow::before { content: ""; width: 9px; height: 9px; border-radius: 50%; background: var(--ball); flex: none; }
h2 {
  font-family: var(--serif); font-size: clamp(23px, 3.4vw, 30px); font-weight: 700;
  letter-spacing: -0.005em; line-height: 1.15; margin: 4px 0 8px; text-wrap: balance;
}
.h3 { font-size: 15px; font-weight: 700; margin: 26px 0 8px; }
.h4 { font-size: 12px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; margin: 0 0 6px; }
.h4.good { color: var(--data-deep); }
.h4.bad { color: var(--data-hot); }
.sub { max-width: 66ch; color: var(--ink-2); font-size: 14.5px; margin: 0 0 20px; }
.sub strong { color: var(--ink); }
.mt { margin-top: 40px; }
.note-line { font-size: 13.5px; color: var(--ink-2); max-width: 70ch; margin-top: 16px; }
.prose { max-width: 68ch; font-size: 15px; color: var(--ink-2); }
.prose strong { color: var(--ink); }
.prose li { margin: 7px 0; }
.formula {
  font-family: Georgia, serif; font-style: italic; font-size: 17px; color: var(--ink);
  padding: 10px 16px; background: var(--surface); border-left: 3px solid var(--gold);
  overflow-x: auto;
}

/* ------------------------------------------------------------ verdict cards */

.cards { display: grid; grid-template-columns: 1fr; gap: 14px; }
@media (min-width: 620px) { .cards { grid-template-columns: 1fr 1fr; } }
@media (min-width: 980px) { .cards { grid-template-columns: repeat(4, 1fr); } }

.card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  padding: 18px 18px 14px; border-top: 3px solid var(--baseline);
}
.card.win { border-top-color: var(--gold); box-shadow: 0 6px 22px rgba(28, 27, 18, 0.07); }
.card .rank { font-size: 11px; font-weight: 700; letter-spacing: 0.11em; text-transform: uppercase; color: var(--muted); }
.card.win .rank { color: var(--gold); }
.card .cname { font-family: var(--serif); font-size: 19px; font-weight: 700; margin: 6px 0 2px; line-height: 1.2; }
.card .cscore { font-size: 34px; font-weight: 700; letter-spacing: -0.02em; margin: 4px 0 10px; }
.card .cscore small { font-size: 12.5px; font-weight: 500; color: var(--muted); letter-spacing: 0; }
.card.win .cscore { color: var(--data-deep); }
.specrow { display: flex; justify-content: space-between; gap: 8px; font-size: 13px; padding: 4px 0; border-top: 1px solid var(--grid); }
.specrow span:first-child { color: var(--ink-2); }
.specrow span:last-child { font-variant-numeric: tabular-nums; font-weight: 600; }

/* -------------------------------------------------------------- brand board */

.board { display: grid; grid-template-columns: 1fr; gap: 14px; }
@media (min-width: 620px) { .board { grid-template-columns: 1fr 1fr; } }
@media (min-width: 980px) { .board { grid-template-columns: repeat(3, 1fr); } }

.board-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  padding: 16px 18px 14px; display: flex; flex-direction: column; gap: 2px;
}
.board-head { display: flex; justify-content: space-between; align-items: baseline; }
.board-brand {
  font-size: 12px; font-weight: 700; letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--purple);
}
.board-rank { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.board-model { font-family: var(--serif); font-size: 18.5px; font-weight: 700; line-height: 1.2; margin-top: 4px; }
.board-family { font-size: 12.5px; color: var(--muted); }
.board-score { font-size: 27px; font-weight: 700; margin-top: 6px; color: var(--data-deep); }
.board-score span { font-size: 12px; font-weight: 500; color: var(--muted); }
.specline { font-size: 12.5px; color: var(--ink-2); font-variant-numeric: tabular-nums; margin: 2px 0 10px; }
.board-string {
  border-top: 1px solid var(--grid); padding-top: 10px; margin-top: auto;
  font-size: 13.5px; font-weight: 600;
}
.board-string-label {
  display: block; font-size: 10.5px; font-weight: 700; letter-spacing: 0.11em;
  text-transform: uppercase; color: var(--gold); margin-bottom: 3px;
}
.board-string-why { display: block; font-size: 12px; font-weight: 400; color: var(--muted); margin-top: 2px; }

/* ------------------------------------------------------------------- tables */

.scroll-x { overflow-x: auto; }
.mapping { width: 100%; border-collapse: collapse; font-size: 14px; min-width: 560px; }
.mapping th {
  text-align: left; font-size: 11px; font-weight: 700; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--muted);
  padding: 8px 14px 8px 0; border-bottom: 2px solid var(--baseline);
}
.mapping td { padding: 10px 14px 10px 0; border-bottom: 1px solid var(--grid); vertical-align: top; }
.mapping td:first-child { color: var(--ink-2); max-width: 36ch; }
.mapping.tnum td { font-variant-numeric: tabular-nums; }

.tbl-wrap { overflow-x: auto; background: var(--surface); border: 1px solid var(--border); border-radius: 8px; }
table.data { width: 100%; border-collapse: collapse; font-size: 13.5px; min-width: 780px; }
table.data th {
  background: var(--court-dark); color: #d8d3bd; text-align: right;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  padding: 11px 12px 9px; white-space: nowrap;
}
table.data th:first-child, table.data td:first-child { text-align: left; }
table.data td { padding: 8.5px 12px; border-bottom: 1px solid var(--grid); text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
table.data tr:last-child td { border-bottom: none; }
table.data td:first-child { font-weight: 600; }
table.data tr.hl td { background: var(--band); }
table.data tr.hot-row td:first-child { color: var(--data-hot); }

/* -------------------------------------------------------------------- charts */

.chart-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  padding: 18px 16px 10px; overflow-x: auto;
}
.chart-title { font-size: 14.5px; font-weight: 700; margin: 0 0 2px; }
.chart-sub { font-size: 12.5px; color: var(--muted); margin: 0 0 10px; }
svg text { font-family: var(--sans); }
/* phones scroll wide charts instead of shrinking them illegible */
#scatter-racquets svg, #scatter-strings svg { min-width: 680px; display: block; }
#hists svg { min-width: 360px; display: block; }

.legend { display: flex; flex-wrap: wrap; gap: 14px 18px; align-items: center; font-size: 12.5px; color: var(--ink-2); padding: 10px 2px 4px; }
.legend .key { display: inline-flex; align-items: center; gap: 7px; }

/* An assumption is not a measurement, and it must never be mistaken for one.
   Anything the model assumed about the player, rather than measured in the lab,
   is marked and set apart. */
.legend .key.assumption,
.assumption {
  display: block;
  margin-top: 6px;
  padding-left: 9px;
  border-left: 2px solid var(--gold);
  color: var(--muted);
  font-style: italic;
}
.legend .swatch { width: 11px; height: 11px; border-radius: 50%; flex: none; }
.legend .band-swatch { background: var(--band); border: 1px solid var(--band-edge); border-radius: 2px; }

.hgrid { display: grid; grid-template-columns: 1fr; gap: 14px; }
@media (min-width: 620px) { .hgrid { grid-template-columns: 1fr 1fr; } }
.maps { display: grid; grid-template-columns: 1fr; gap: 14px; }
@media (min-width: 620px) { .maps { grid-template-columns: 1fr 1fr; } }
@media (min-width: 980px) { .maps { grid-template-columns: repeat(4, 1fr); } }

#tip {
  position: fixed; pointer-events: none; z-index: 10; display: none;
  background: var(--court-dark); color: #f3efdf; border-radius: 7px;
  padding: 9px 12px; font-size: 12.5px; line-height: 1.45;
  box-shadow: 0 6px 22px rgba(15, 43, 27, 0.35); max-width: 270px;
}
#tip .t-name { font-weight: 700; margin-bottom: 3px; }
#tip .t-row { display: flex; justify-content: space-between; gap: 14px; color: #cfc9b4; }
#tip .t-row b { color: #fff; font-variant-numeric: tabular-nums; font-weight: 650; }

circle:focus { outline: none; }
circle:focus-visible { stroke: var(--purple); stroke-width: 3px; }
@media (prefers-reduced-motion: no-preference) { circle { transition: r 120ms ease; } }

/* ------------------------------------------------------------------ journal */

.drift {
  display: flex; flex-wrap: wrap; gap: 14px; align-items: stretch; margin-top: 6px;
}
.drift-stat {
  background: var(--court-dark); color: #f3efdf; border-radius: 8px;
  padding: 14px 22px; text-align: center; min-width: 120px;
}
.drift-n { display: block; font-size: 40px; font-weight: 700; line-height: 1.1; }
.drift-label { font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--gold-soft); }
.drift-verdict {
  flex: 1; min-width: 240px; display: flex; align-items: center;
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  padding: 14px 18px; font-size: 15px; font-weight: 600;
}
.drift-verdict.holds { border-left: 4px solid var(--data-1); }
.drift-verdict.changed { border-left: 4px solid var(--data-hot); }
.drift-cols { display: grid; grid-template-columns: 1fr; gap: 8px 28px; }
@media (min-width: 620px) { .drift-cols { grid-template-columns: 1fr 1fr; } }
.ranklist { margin: 4px 0 0; padding-left: 22px; font-size: 14px; }
.ranklist li { margin: 4px 0; }

.entry-form {
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  padding: 18px; margin-top: 6px;
}
.form-grid { display: grid; grid-template-columns: 1fr; gap: 12px 16px; }
@media (min-width: 620px) { .form-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 980px) { .form-grid { grid-template-columns: repeat(4, 1fr); } }
.entry-form label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-2); }
.entry-form label.wide { margin-top: 12px; }

/* Every text control on the site, not just the journal's.
   These rules used to be scoped to `.entry-form`, so the profile quiz, the single most
   important form we have, rendered as raw browser defaults: a monospace textarea, a
   fixed-width box that ignored its column, a system-blue focus ring. The one screen where a
   player decides whether to trust us looked unfinished. Element selectors, so any form we
   add next inherits the design instead of having to remember to ask for it. */
input[type="text"], input[type="number"], input[type="search"], input[type="date"],
input:not([type]), select, textarea {
  width: 100%;
  box-sizing: border-box;
  font: 400 15px/1.5 var(--sans);      /* never the browser's monospace default */
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--baseline);
  border-radius: 6px;
  padding: 10px 12px;
  min-height: 44px;                    /* a real tap target on a phone */
  -webkit-appearance: none;
  appearance: none;
  transition: border-color .12s, box-shadow .12s;
}
textarea { resize: vertical; min-height: 132px; line-height: 1.6; }
input::placeholder, textarea::placeholder { color: var(--muted); opacity: 1; }
input[type="text"]:hover, input:not([type]):hover, textarea:hover, select:hover {
  border-color: var(--muted);
}
input[type="text"]:focus, input[type="number"]:focus, input[type="search"]:focus,
input:not([type]):focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--lawn);
  box-shadow: 0 0 0 3px rgba(28, 91, 56, 0.16);
}
select {
  /* The arrow has to be drawn back in, because appearance:none removes it. */
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-2) 50%),
                    linear-gradient(135deg, var(--ink-2) 50%, transparent 50%);
  background-position: calc(100% - 18px) center, calc(100% - 13px) center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 34px;
}
.btn, a.btn {
  display: inline-block;
  margin-top: 16px; font: 700 14px/1 var(--sans); letter-spacing: 0.06em; text-transform: uppercase;
  color: #fff; background: var(--lawn); border: none; border-radius: 6px;
  padding: 14px 26px; cursor: pointer; min-height: 44px; text-decoration: none;
}
.btn:hover, a.btn:hover { background: var(--data-deep); color: #fff; }
.form-fine { font-size: 12.5px; color: var(--muted); margin: 10px 0 0; }
.form-fine code { background: var(--page); padding: 1px 5px; border-radius: 4px; }

.timeline { display: flex; flex-direction: column; gap: 14px; margin-top: 6px; }
.entry {
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  padding: 16px 18px; border-left: 4px solid var(--lawn);
}
.entry-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.entry-date { font-family: var(--serif); font-weight: 700; font-size: 16.5px; margin-right: 4px; }
.chip {
  font-size: 11px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase;
  background: var(--court-dark); color: #f3efdf; border-radius: 999px; padding: 3px 10px;
}
.chip-soft { background: var(--grid); color: var(--ink-2); }
.chip-score { background: var(--purple); }
.entry-setup { font-size: 13px; color: var(--muted); margin-top: 6px; font-variant-numeric: tabular-nums; }
.entry-cols { display: grid; grid-template-columns: 1fr; gap: 4px 26px; margin-top: 12px; }
@media (min-width: 620px) { .entry-cols { grid-template-columns: 1fr 1fr; } }
.entry-cols ul { margin: 0; padding-left: 20px; font-size: 14px; color: var(--ink-2); }
.entry-cols li { margin: 4px 0; }
.entry-notes { font-size: 13.5px; color: var(--ink-2); border-top: 1px solid var(--grid); padding-top: 10px; margin: 12px 0 0; }

/* ------------------------------------------------------- day-1 UX layer */

html.lab-off .lab-only { display: none !important; }

.lab-toggle {
  display: inline-flex; align-items: center; gap: 7px;
  font: 600 12.5px/1 var(--sans); letter-spacing: 0.06em; text-transform: uppercase;
  color: #cfc9b4; background: rgba(243, 239, 223, 0.08);
  border: 1px solid rgba(243, 239, 223, 0.25); border-radius: 999px;
  padding: 8px 14px; margin-left: 10px; cursor: pointer; white-space: nowrap;
}
.lab-toggle .lab-dot { width: 8px; height: 8px; border-radius: 50%; background: #6b6753; }
.lab-toggle.is-on { color: #fff; border-color: var(--ball); }
.lab-toggle.is-on .lab-dot { background: var(--ball); }

.hero-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 16px; }
.hero-chip {
  font-size: 12px; font-weight: 600; color: #e9e4cf;
  background: rgba(243, 239, 223, 0.10); border: 1px solid rgba(243, 239, 223, 0.22);
  border-radius: 999px; padding: 5px 12px;
}
.btn-ghost {
  display: inline-block; margin-top: 20px; background: transparent;
  border: 1.5px solid var(--gold-soft); color: var(--gold-soft);
  text-decoration: none; text-align: center;
}
.btn-ghost:hover { background: rgba(203, 180, 106, 0.12); color: #fff; }

.picks { display: grid; grid-template-columns: 1fr; gap: 14px; }
@media (min-width: 620px) { .picks { grid-template-columns: 1fr 1fr; } }
@media (min-width: 980px) { .picks { grid-template-columns: repeat(4, 1fr); } }
.pick {
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  padding: 18px 18px 16px; border-top: 3px solid var(--baseline);
  display: flex; flex-direction: column;
}
.pick.win { border-top-color: var(--gold); box-shadow: 0 6px 22px rgba(28, 27, 18, 0.07); }
.pick-string { border-top-color: var(--purple); }
.pick-rank { font-size: 11px; font-weight: 700; letter-spacing: 0.11em; text-transform: uppercase; color: var(--muted); }
.pick.win .pick-rank { color: var(--gold); }
.pick-string .pick-rank { color: var(--purple); }
.pick-name { font-family: var(--serif); font-size: 20px; font-weight: 700; line-height: 1.2; margin: 6px 0 10px; }
.pick-reasons { margin: 0; padding-left: 18px; font-size: 13.5px; color: var(--ink-2); }
.pick-reasons li { margin: 6px 0; }
.pick-specs { border-top: 1px solid var(--grid); margin-top: auto; padding-top: 9px; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }

.glossary { margin-top: 18px; background: var(--surface); border: 1px solid var(--border); border-radius: 8px; }
.glossary summary {
  cursor: pointer; padding: 13px 18px; font-size: 13.5px; font-weight: 700;
  letter-spacing: 0.02em; color: var(--lawn); list-style-position: inside;
}
.glossary summary:hover { color: var(--data-deep); }
.glossary dl { margin: 0; padding: 4px 18px 14px; }
.gl-row { display: grid; grid-template-columns: 1fr; gap: 2px 16px; padding: 8px 0; border-top: 1px solid var(--grid); }
@media (min-width: 620px) { .gl-row { grid-template-columns: 160px 1fr; } }
.gl-row dt { font-weight: 700; font-size: 13.5px; }
.gl-row dd { margin: 0; font-size: 13.5px; color: var(--ink-2); }

.btn-big { font-size: 16px; padding: 18px 34px; }

.quiz { max-width: 720px; }
.q { border: none; margin: 26px 0 0; padding: 0; }
.q legend {
  font-family: var(--serif); font-size: 20px; font-weight: 700; margin-bottom: 12px;
}
.q-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 50%; background: var(--court-dark);
  color: var(--ball); font: 700 13px/1 var(--sans); margin-right: 8px; vertical-align: 2px;
}
.q-hint { font: 400 13px/1 var(--sans); color: var(--muted); margin-left: 6px; }
.q-name {
  font: 500 16px/1.3 var(--sans); color: var(--ink);
  background: var(--surface); border: 1px solid var(--baseline); border-radius: 8px;
  padding: 13px 14px; width: 100%; max-width: 380px;
}
.opts { display: grid; grid-template-columns: 1fr; gap: 10px; }
@media (min-width: 620px) { .opts { grid-template-columns: 1fr 1fr; } }
.opts label { display: block; cursor: pointer; }
.opts input { position: absolute; opacity: 0; }
.opts span {
  display: block; background: var(--surface); border: 1.5px solid var(--baseline);
  border-radius: 8px; padding: 13px 15px; min-height: 100%;
}
.opts strong { display: block; font-size: 15px; }
.opts em { display: block; font-style: normal; font-size: 12.5px; color: var(--muted); margin-top: 2px; }
.opts input:checked + span { border-color: var(--lawn); background: var(--band); box-shadow: 0 0 0 1px var(--lawn); }
.opts input:focus-visible + span { outline: 2px solid var(--purple); outline-offset: 2px; }
.quiz .btn { margin-top: 30px; }

.chipset { margin-top: 18px; }
.chipset-label { display: block; font-size: 12px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; margin-bottom: 8px; }
.good-label { color: var(--data-deep); }
.bad-label { color: var(--data-hot); }
.chip-row { display: flex; flex-wrap: wrap; gap: 8px; }
.pill { cursor: pointer; }
.pill input { position: absolute; opacity: 0; }
.pill span {
  display: inline-block; font-size: 13.5px; font-weight: 600; color: var(--ink-2);
  background: var(--page); border: 1.5px solid var(--baseline); border-radius: 999px;
  padding: 9px 15px;
}
.pill input:checked + span { background: var(--band); border-color: var(--lawn); color: var(--data-deep); }
.pill-bad input:checked + span { background: rgba(208, 92, 59, 0.10); border-color: var(--data-hot); color: var(--data-hot); }
.pill input:focus-visible + span { outline: 2px solid var(--purple); outline-offset: 2px; }

.more-detail { margin-top: 20px; border-top: 1px solid var(--grid); }
.more-detail summary { cursor: pointer; padding: 13px 0; font-size: 13.5px; font-weight: 700; color: var(--lawn); }
.more-detail summary:hover { color: var(--data-deep); }

/* ------------------------------------------------- typeahead & chat input */

.ta { position: relative; display: block; }
.ta input { width: 100%; }
.ta-menu {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 6;
  background: var(--surface); border: 1px solid var(--baseline); border-radius: 8px;
  box-shadow: 0 10px 30px rgba(28, 27, 18, 0.14);
  max-height: 300px; overflow-y: auto; display: none;
  text-transform: none; letter-spacing: normal; font-weight: 400; color: var(--ink);
}
.ta-item { padding: 10px 13px; font-size: 14px; cursor: pointer; border-bottom: 1px solid var(--grid); }
.ta-item:last-of-type { border-bottom: none; }
.ta-item.on, .ta-item:hover { background: var(--band); }
.ta-item mark { background: transparent; color: var(--data-deep); font-weight: 700; }
.ta-more { padding: 8px 13px; font-size: 11.5px; color: var(--muted); background: var(--page); }

.notes-first textarea {
  font-size: 15px; line-height: 1.55; min-height: 120px;
}
.notes-first .hint { font-size: 12.5px; color: var(--muted); margin-top: 6px; }

.chatbar { display: flex; gap: 10px; align-items: stretch; max-width: 780px; }
.chatbar input {
  flex: 1; font: 400 15px/1.4 var(--sans); color: var(--ink);
  background: var(--surface); border: 1.5px solid var(--baseline); border-radius: 999px;
  padding: 13px 20px; min-height: 48px;
}
.chatbar input:focus { outline: 2px solid var(--lawn); border-color: var(--lawn); }
.chatbar button {
  font: 700 14px/1 var(--sans); color: #fff; background: var(--lawn);
  border: none; border-radius: 999px; padding: 0 22px; cursor: pointer; min-height: 48px;
}
.chatbar button:hover { background: var(--data-deep); }
.chat-hint { font-size: 12.5px; color: var(--muted); margin: 8px 0 0 6px; }

.answer {
  background: var(--surface); border: 1px solid var(--border); border-left: 4px solid var(--lawn);
  border-radius: 8px; padding: 18px 20px; max-width: 780px; margin-top: 18px;
}
.answer p { margin: 0 0 12px; font-size: 15px; color: var(--ink-2); }
.answer p:last-child { margin-bottom: 0; }
.answer strong { color: var(--ink); }
.answer .a-label {
  display: block; font-size: 11px; font-weight: 700; letter-spacing: 0.11em;
  text-transform: uppercase; color: var(--lawn); margin-bottom: 8px;
}

/* ------------------------------------------- comparison & simulator */

.q-note { font-size: 13.5px; color: var(--ink-2); margin: 0 0 12px; max-width: 58ch; }
.setup-grid { max-width: 720px; }

.vs { display: flex; flex-direction: column; gap: 10px; align-items: stretch; margin: 8px 0 18px; }
@media (min-width: 620px) { .vs { flex-direction: row; align-items: center; } }
.vs-card {
  flex: 1; background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  padding: 16px 18px; position: relative;
}
.vs-card.vs-top { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold); }
.vs-role { font-size: 11px; font-weight: 700; letter-spacing: 0.11em; text-transform: uppercase; color: var(--muted); }
.vs-top .vs-role { color: var(--gold); }
.vs-name { font-family: var(--serif); font-size: 19px; font-weight: 700; line-height: 1.2; margin: 5px 0 4px; }
.vs-rank { font-size: 26px; font-weight: 700; color: var(--data-deep); font-variant-numeric: tabular-nums; }
.vs-rank span { font-size: 12.5px; font-weight: 500; color: var(--muted); }
.vs-flag {
  position: absolute; top: 14px; right: 14px;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--data-hot); border: 1px solid var(--data-hot); border-radius: 999px; padding: 2px 9px;
}
.vs-note { font-size: 12px; color: var(--muted); margin-top: 6px; }

/* subtle racquet links: inherit ink, dotted underline, green on hover */
a.rlink { color: inherit; text-decoration: none; border-bottom: 1px dotted var(--baseline); }
a.rlink:hover { color: var(--data-deep); border-bottom: 1px solid var(--lawn); }
a.shoplink {
  display: inline-block; margin-top: 9px; font-size: 12px; font-weight: 600;
  color: var(--lawn); text-decoration: none;
}
a.shoplink:hover { color: var(--data-deep); text-decoration: underline; }
.vs-mid {
  font-family: var(--serif); font-style: italic; font-size: 17px; color: var(--muted);
  text-align: center; flex: none; padding: 0 4px;
}

.simnotes { margin: 8px 0 0; padding-left: 20px; font-size: 14.5px; color: var(--ink-2); max-width: 72ch; }
.simnotes li { margin: 7px 0; }

.sim-form { max-width: 780px; }
.sim-grid { grid-template-columns: 1fr; }
@media (min-width: 620px) { .sim-grid { grid-template-columns: 1fr 1fr; } }

.simhero { display: flex; flex-wrap: wrap; gap: 12px; margin: 10px 0 20px; }
.simhero-rank, .simhero-score {
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  padding: 14px 20px; min-width: 130px;
}
.simhero-rank { background: var(--court-dark); border-color: var(--court-dark); }
.simhero-rank .simhero-big { color: var(--ball); }
.simhero-rank .simhero-sub { color: #cfc9b4; }
.simhero-big { display: block; font-size: 32px; font-weight: 700; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; }
.simhero-sub { font-size: 11.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
.simhero-flag {
  align-self: center; font-size: 11px; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--data-hot);
  border: 1px solid var(--data-hot); border-radius: 999px; padding: 5px 12px;
}

.fitbars { display: flex; flex-direction: column; gap: 9px; max-width: 640px; }
.fitbar { display: grid; grid-template-columns: 132px 1fr 52px; gap: 10px; align-items: center; }
.fitbar-label { font-size: 12.5px; font-weight: 600; color: var(--ink-2); }
.fitbar-track { height: 10px; background: var(--grid); border-radius: 5px; overflow: hidden; }
.fitbar-fill { display: block; height: 100%; background: var(--data-1); border-radius: 5px; }
.fitbar-val { font-size: 12.5px; font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------------- pros */

.pro-head { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.pro-majors {
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--gold); border: 1px solid var(--gold-soft); border-radius: 999px; padding: 4px 12px;
}
.pro-timeline { display: flex; flex-direction: column; margin-top: 6px; }
.pro-era {
  display: grid; grid-template-columns: 1fr; gap: 2px 22px;
  padding: 16px 0; border-bottom: 1px solid var(--grid);
}
@media (min-width: 620px) { .pro-era { grid-template-columns: 110px 1fr; } }
.pro-era:last-child { border-bottom: none; }
.pro-years {
  font-variant-numeric: tabular-nums; font-weight: 700; font-size: 14px;
  color: var(--purple); white-space: nowrap;
}
.pro-racquet { font-family: var(--serif); font-size: 18px; font-weight: 700; line-height: 1.25; }
.pro-note { font-size: 13.5px; color: var(--ink-2); margin-top: 3px; max-width: 62ch; }
.pro-strings { font-size: 13px; margin-top: 7px; font-weight: 600; }
.pro-strings-label {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--gold); margin-right: 7px;
}
.pro .specline { margin: 8px 0 0; }

/* ------------------------------------------------------------------- footer */

.footer { margin-top: 64px; background: var(--court-dark); color: #cfc9b4; border-top: 3px solid var(--gold); }
.footer-inner { padding: 26px 18px 30px; display: flex; flex-direction: column; gap: 8px; font-size: 13.5px; }
.footer-mark { font-family: var(--serif); font-weight: 700; color: #f3efdf; }
.footer-fine { font-size: 12px; color: #8f8b76; max-width: 72ch; }
.footer a { color: var(--gold-soft); }

/* ---- Evidence-backed picks, and the audit trail behind them ---------------- */
.pick { border: 1px solid var(--rule); border-radius: 10px; padding: 16px 18px;
  margin: 14px 0; background: var(--card); }
.pick-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.pick-head h3 { margin: 0; flex: 1 1 auto; font-size: 1.15rem; }
.pick-n { display: inline-grid; place-items: center; width: 26px; height: 26px;
  border-radius: 50%; background: var(--court-dark); color: var(--page);
  font-weight: 700; font-size: .8rem; flex: none; }
.pick-price { font-variant-numeric: tabular-nums; color: var(--muted); font-weight: 600; }
.pick-verdict { margin: 8px 0 4px; font-weight: 600; }
.pick-foryou { margin: 4px 0 8px; color: var(--ink); }
.pick-links { margin: 6px 0 0; font-size: .9rem; }

/* The string and tension for one frame. Purple is the string accent throughout,
   carried over from .pick-string in the older layout. */
.setup {
  margin: 14px 0 0; padding: 12px 14px;
  background: var(--page); border: 1px solid var(--rule);
  border-left: 3px solid var(--purple); border-radius: 6px;
}
.setup-h {
  margin: 0 0 4px; font-size: .72rem; font-weight: 700;
  letter-spacing: .11em; text-transform: uppercase; color: var(--purple);
}
.setup-line { margin: 0 0 6px; font-size: 1.02rem; }
.setup-why { margin: 0 0 10px; color: var(--ink-2); font-size: .92rem; }
.setup-alts { margin: 10px 0 0; color: var(--muted); font-size: .88rem; }
.setup-facts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
  gap: 8px; margin: 0; padding: 0; list-style: none;
}
.setup-facts li {
  display: flex; flex-direction: column; gap: 1px;
  padding: 7px 9px; background: var(--card);
  border: 1px solid var(--rule); border-radius: 5px;
}
.setup-facts span {
  font-size: .68rem; letter-spacing: .07em; text-transform: uppercase; color: var(--muted);
}
.setup-facts strong { font-variant-numeric: tabular-nums; font-size: 1rem; }
.setup details.math > summary { color: var(--purple); }

details.math, details.untested { margin-top: 10px; }
details.math > summary, details.untested > summary {
  cursor: pointer; font-weight: 600; font-size: .9rem; color: var(--data-deep);
  padding: 6px 0; list-style: none; }
details.math > summary::before, details.untested > summary::before {
  content: "▸ "; display: inline-block; transition: transform .15s; }
details.math[open] > summary::before, details.untested[open] > summary::before {
  content: "▾ "; }
.math-body { border-top: 1px solid var(--rule); margin-top: 6px; padding-top: 12px; }
.math-body h4 { margin: 14px 0 6px; font-size: .95rem; }
.math-sub { font-weight: 400; color: var(--muted); font-size: .82rem; }
.math-note { color: var(--muted); font-size: .86rem; margin: 6px 0; }
.math-eq { font-variant-numeric: tabular-nums; background: var(--page);
  border-left: 3px solid var(--gold); padding: 8px 12px; margin: 8px 0;
  font-size: .92rem; overflow-x: auto; }
.math-table { width: 100%; font-size: .85rem; }
.math-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.math-table .dim { color: var(--muted); font-size: .8rem; }
.math-table tr.math-total td { border-top: 2px solid var(--rule); font-weight: 700; }
.math-list { margin: 6px 0; padding-left: 18px; }
.math-list li { margin: 5px 0; }
.table-wrap { overflow-x: auto; }

/* The player's own racquet, called out among the heat maps. */
.map-yours {
  display: inline-block; margin-left: 7px; padding: 1px 7px;
  border-radius: 999px; background: var(--court-dark); color: var(--page);
  font-size: .62rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  vertical-align: middle;
}

/* Both sides of the comparison, side by side. A frame that can only lose is not a comparison. */
.vs-gaps { display: grid; grid-template-columns: 1fr; gap: 8px 26px; margin: 14px 0 4px; }
@media (min-width: 700px) { .vs-gaps { grid-template-columns: 1fr 1fr; } }
.vs-gap .simnotes { margin-top: 4px; }

/* ---- why a pick ranked: three marks instead of three sentences -------------
   Recessive track, thin fill, value direct-labelled. The "for you" bar is the
   only one that discriminates between players, so it is the only one in accent. */
.score3 { list-style: none; margin: 10px 0 6px; padding: 0; display: grid; gap: 5px; }
.score3 li { display: grid; grid-template-columns: 62px 1fr 46px; align-items: center; gap: 10px; }
.s3-k { font-size: .68rem; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted); }
.s3-bar { height: 6px; border-radius: 3px; background: var(--grid); overflow: hidden; }
.s3-bar i { display: block; height: 100%; border-radius: 3px; background: var(--pool); }
.s3-you .s3-bar i { background: var(--data-deep); }
.s3-v { font-variant-numeric: tabular-nums; font-weight: 700; font-size: .88rem; text-align: right; }

/* ---- the stringbed gauge ---------------------------------------------------
   Bed stiffness is the quantity that decides how a racquet plays and the one a
   player is never shown. Tension alone cannot be drawn: it means nothing without
   the string it sits on. So the target band is the mark, and the pair is the dot. */
.gauge { margin: 12px 0 10px; }
.gauge figcaption { font-size: .68rem; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 14px; }
.gauge-track { position: relative; height: 8px; border-radius: 4px;
  background: linear-gradient(to right, #f0e4cf, #d8c9a8); }
.gauge-band { position: absolute; top: -3px; bottom: -3px; border-radius: 4px;
  background: var(--band); border: 1px solid var(--band-edge); }
.gauge-mark { position: absolute; top: 50%; width: 12px; height: 12px; margin: -6px 0 0 -6px;
  border-radius: 50%; background: var(--purple); border: 2px solid var(--halo);
  box-shadow: 0 0 0 1px var(--purple); }
.gauge-mark b { position: absolute; left: 50%; transform: translateX(-50%); bottom: 15px;
  font-size: .8rem; font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--purple); }
.gauge-ends { display: flex; justify-content: space-between; margin-top: 7px;
  font-size: .72rem; color: var(--muted); }
.score3-note { margin: 6px 0 8px; font-size: .84rem; color: var(--muted); max-width: 68ch; }
.score3-note strong { color: var(--ink-2); }

/* ============================================================================
   PROVENANCE CHIPS
   Anil's rule is that every number a player sees must be classifiable as
   MEASURED, DERIVED or ASSUMED. That rule used to be honoured in paragraphs of
   hedging, which is the one form nobody reads. It is a property OF the number,
   so it belongs ON the number. Three chips, used everywhere, no exceptions. The
   honesty stops being an apology and becomes the thing the app is for.
   ========================================================================== */
.prov {
  display: inline-block; vertical-align: middle; margin-left: 7px;
  padding: 1px 7px 2px; border-radius: 999px; cursor: help;
  font-size: .6rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  border: 1px solid transparent; white-space: nowrap;
}
.prov.measured { color: var(--data-deep); background: rgba(31, 157, 85, .10); border-color: rgba(31, 157, 85, .30); }
.prov.derived  { color: var(--purple);   background: rgba(61, 43, 86, .09);  border-color: rgba(61, 43, 86, .26); }
.prov.assumed  { color: var(--gold);     background: rgba(168, 132, 44, .10); border-color: rgba(168, 132, 44, .32); }

/* ---- the pick, as two columns: what it IS FOR, and how to string it -------- */
.pick-cols { display: grid; grid-template-columns: 1fr; gap: 16px; margin-top: 12px; }
@media (min-width: 780px) { .pick-cols { grid-template-columns: 1.35fr 1fr; align-items: start; } }
.pick-cols .setup { margin: 0; height: 100%; }

/* ---- THE chart: what testers found a frame is FOR -------------------------
   Two frames our physics rates a point apart can be opposite racquets, and this
   is the only view in the app that can see it. Bars run against the frame's own
   average (the tick), because an absolute score just says "good racquet", which
   is true of nearly everything anyone bothers to test. */
.prof { margin: 0; }
.prof figcaption, .gauge figcaption {
  font-size: .68rem; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 10px;
}
.prof-rows { display: grid; gap: 4px; }
.prof-row { display: grid; grid-template-columns: 96px 1fr 26px; align-items: center; gap: 9px; }
.prof-k { font-size: .78rem; color: var(--ink-2); }
.prof-bar { position: relative; height: 9px; border-radius: 2px; background: var(--grid); }
.prof-bar i { display: block; height: 100%; border-radius: 2px; background: var(--pool); }
.prof-bar u {  /* the frame's own average */
  position: absolute; top: -2px; bottom: -2px; width: 2px; background: var(--ink-2); opacity: .55;
}
.prof-v { font-size: .8rem; font-weight: 700; font-variant-numeric: tabular-nums; text-align: right; }
.prof-row.is-you .prof-k { color: var(--ink); font-weight: 700; }
.prof-row.is-you .prof-bar i { background: var(--data-deep); }
.prof-row.is-you .prof-v { color: var(--data-deep); }
.prof-legend { margin: 9px 0 0; font-size: .78rem; color: var(--muted); }
.prof-legend strong { color: var(--ink-2); }
.prof-tick {
  display: inline-block; width: 2px; height: 10px; background: var(--ink-2);
  opacity: .55; vertical-align: -1px; margin-right: 4px;
}

/* ---- the card footer: why it ranked, and where to go next ----------------- */
.pick-foot { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--rule); }
.pick-foot .score3 li { grid-template-columns: 62px 1fr 34px auto; }
.pick-foot .pick-links { margin-top: 10px; }

/* ---- the verdict banner: the one sentence that changes what you do -------- */
.verdict-banner {
  margin: 16px 0; padding: 12px 16px; max-width: 74ch;
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--gold); border-radius: 6px;
  font-size: .95rem; color: var(--ink-2);
}
.verdict-banner strong { color: var(--ink); }

/* ---- the spec diff --------------------------------------------------------
   Raw specs mean nothing on their own: a 320 swingweight is not "better" than a
   328, it is better FOR THIS PLAYER. So the bars are the desirability the ranking
   actually used, mirrored around the spec name. The picture and the model cannot
   disagree, because they are the same number. */
.diff { margin: 22px 0 0; }
.diff figcaption { font-size: .68rem; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 12px; }
.diff figcaption em { font-style: normal; color: var(--ink-2); }
.diff-head, .diff-row {
  display: grid; grid-template-columns: 42px 1fr 118px 1fr 42px;
  align-items: center; gap: 8px;
}
.diff-head {
  font-size: .7rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--muted); padding-bottom: 8px; border-bottom: 1px solid var(--rule); margin-bottom: 8px;
}
.diff-head span:first-child { grid-column: 1 / 3; }
.diff-head span:last-child { grid-column: 4 / 6; text-align: right; }
.diff-head .diff-mid { text-align: center; }
.diff-row { padding: 3px 0; }
.diff-k { font-size: .76rem; color: var(--ink-2); text-align: center; }
.diff-val { font-size: .8rem; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--muted); }
.diff-row .diff-val:first-child { text-align: right; }
.diff-val.won { color: var(--data-deep); font-weight: 700; }
.diff-bar { height: 9px; border-radius: 2px; background: var(--grid); overflow: hidden; display: flex; }
.diff-bar i { height: 100%; background: var(--pool); border-radius: 2px; }
.diff-bar.l { justify-content: flex-end; }
.diff-bar.l i { background: var(--data-3); }
.diff-bar.r i { background: var(--data-deep); }
.diff-legend { margin: 12px 0 0; font-size: .8rem; color: var(--muted); max-width: 70ch; }

@media (max-width: 560px) {
  .diff-head, .diff-row { grid-template-columns: 34px 1fr 92px 1fr 34px; gap: 5px; }
  .diff-k { font-size: .68rem; }
  .diff-val { font-size: .72rem; }
}

/* ============================================================================
   SIDE BY SIDE: the three picks on one grid
   Three stacked cards cannot be compared. The reader scrolls, fails to hold
   eight numbers per frame in their head, and takes the #1 on faith. That
   quietly undoes the honest position of the app, which is that the model gets
   you to the right neighbourhood and CANNOT tell you which of three similar
   frames you will love. If we mean it, the three must read as a choice.
   Read a row across: which of these is the spin racquet.
   Read a column down: what kind of racquet is this.
   ========================================================================== */
.cmp { margin: 34px 0 0; padding: 20px 0 0; border-top: 2px solid var(--rule); }
.cmp figcaption { margin-bottom: 18px; }
.cmp figcaption h3 {
  font-family: var(--serif); font-size: 1.25rem; font-weight: 700; margin: 0 0 6px;
}
.cmp figcaption p { margin: 0; max-width: 72ch; font-size: .9rem; color: var(--ink-2); }

.cmp-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.cmp-grid {
  display: grid;
  grid-template-columns: 116px repeat(var(--cols), minmax(150px, 1fr));
  gap: 0 12px; min-width: 560px; align-items: center;
}

.cmp-head {
  display: flex; flex-direction: column; gap: 2px;
  padding: 0 0 12px; border-bottom: 2px solid var(--rule); align-self: end;
}
.cmp-name { font-weight: 700; font-size: .92rem; line-height: 1.25; }
.cmp-char {
  font-size: .68rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--purple); margin-top: 3px;
}
.cmp-meta { font-size: .74rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.cmp-string {
  margin-top: 6px; font-size: .74rem; color: var(--ink-2); line-height: 1.3;
  padding-top: 6px; border-top: 1px dashed var(--rule);
}
.cmp-corner { border-bottom: 2px solid var(--rule); }

.cmp-k {
  font-size: .78rem; color: var(--ink-2); padding: 7px 0;
  display: flex; flex-direction: column; gap: 1px;
}
.cmp-k.is-you { color: var(--ink); font-weight: 700; }
.cmp-you {
  font-size: .58rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--data-deep);
}

.cmp-cell { display: grid; grid-template-columns: 1fr 24px; align-items: center; gap: 8px; padding: 7px 0; }
.cmp-cell.is-you { background: rgba(31, 157, 85, .045); }
.cmp-bar { position: relative; height: 9px; border-radius: 2px; background: var(--grid); }
.cmp-bar i { display: block; height: 100%; border-radius: 2px; background: var(--pool); }
.cmp-bar u {  /* that frame's own average */
  position: absolute; top: -2px; bottom: -2px; width: 2px; background: var(--ink-2); opacity: .5;
}
.cmp-cell.is-you .cmp-bar i { background: var(--data-deep); }
.cmp-v {
  font-size: .8rem; font-variant-numeric: tabular-nums; text-align: right; color: var(--ink-2);
}
.cmp-cell.leads .cmp-v { font-weight: 800; color: var(--ink); }
.cmp-cell.leads .cmp-bar i { background: var(--data-deep); }

.cmp-legend { margin: 14px 0 0; font-size: .8rem; color: var(--muted); max-width: 74ch; }
.cmp-weak {
  font-size: .68rem; font-weight: 700; letter-spacing: .04em;
  color: var(--data-hot);
}
.cmp-weak.even { color: var(--muted); font-weight: 600; }

/* Scrolling the grid sideways on a phone must not carry the quality names away with it:
   the numbers are meaningless without the row they belong to. */
.cmp-corner, .cmp-k {
  position: sticky; left: 0; z-index: 2;
  background: var(--page);
  padding-right: 8px;
}
.cmp-k::after {  /* a soft edge so bars scrolling under the labels read as underneath */
  content: ""; position: absolute; top: 0; bottom: 0; right: 0; width: 10px;
  background: linear-gradient(to right, var(--page), rgba(246, 242, 231, 0));
  pointer-events: none;
}

/* The comparison grid now leads, so it needs no top rule of its own; the divider
   belongs between it and the three cards it summarises. */
.cmp { border-top: 0; padding-top: 0; margin-top: 22px; }
.picks-h {
  margin: 40px 0 4px; padding-top: 22px; border-top: 2px solid var(--rule);
  font-family: var(--serif); font-size: 1.25rem; font-weight: 700;
}
/* One "Show the math" per pick, racquet then string. Two buttons made the reader
   choose which maths they wanted before knowing what either one contained. */
.math-rule { border: 0; border-top: 1px dashed var(--rule); margin: 24px 0 14px; }

/* The card's left column now carries a sentence, not a repeat of the grid above it. */
.pick-says { display: flex; flex-direction: column; gap: 10px; }
.pick-says .pick-foryou { margin: 0; }

/* ---- the profile quiz: the one screen that has to earn a player's trust --------------
   Q10 (the free-text write-up) is the highest-signal input in the whole app, and it was
   rendering as a small monospace box the browser drew for us. It gets the room its
   importance deserves. */
.q label.wide { display: block; margin-top: 4px; }
.q label.wide textarea { min-height: 200px; }
.q .hint { display: block; margin-top: 8px; font-size: 13px; color: var(--muted); max-width: 66ch; }

/* The "what's in your bag" row. The labels wrap their own input, so they have to become
   the layout, or the input floats loose beside its own caption. */
.setup-grid { grid-template-columns: 1fr; gap: 14px; }
@media (min-width: 620px) { .setup-grid { grid-template-columns: 2fr 2fr 1fr; } }
.setup-grid label {
  display: flex; flex-direction: column; gap: 6px;
  font-size: 12px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--ink-2);
}
.setup-grid input { font-size: 15px; text-transform: none; letter-spacing: 0; }

/* The typeahead menu must sit over the page, not shove it around. */
.ta-wrap { position: relative; }

/* ---- the quiz as a stepper: one question per screen -----------------------------------
   A review said the form was horizontal and killed the UX. It did: eleven questions stacked
   down a long page, options laid out two and three across, and the player scrolling past
   questions they had not answered yet. The fix is not a narrower form, it is one question at
   a time, and a page that CANNOT scroll: the frame is the viewport, and only the question
   itself scrolls if a question is genuinely tall (the write-up box, the six NTRP tiles).

   Every rule here is behind .quiz-stepped, which quiz.js adds. Without JavaScript the form
   renders exactly as it did before, all questions stacked and submittable. */

body.quiz-stepped {
  height: 100dvh;               /* dvh, not vh: iOS Safari's toolbar eats the difference */
  overflow: hidden;             /* the PAGE never scrolls. the question does. */
  display: flex;
  flex-direction: column;
}
body.quiz-stepped .masthead,
body.quiz-stepped .quiz-hero { flex: 0 0 auto; }
body.quiz-stepped .footer { display: none; }          /* it would eat a third of a phone */
/* The hero is for the no-JS page only. In the stepper it cannot shrink, so on a small phone it
   pushed the Start button off a page that is not allowed to scroll. Everything it said now
   lives inside the first PANEL, which can scroll. */
body.quiz-stepped .quiz-hero { display: none; }
body.quiz-stepped main {
  flex: 1 1 auto; min-height: 0; padding-bottom: 0;
  display: flex; flex-direction: column;
}
body.quiz-stepped .quiz {
  flex: 1 1 auto; min-height: 0; width: 100%; max-width: 640px; margin: 0 auto;
  display: flex; flex-direction: column;
}
body.quiz-stepped .quiz-body {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  padding: 4px 2px 8px;                  /* room for the focus ring, which is outside the box */
  scrollbar-width: thin;
}
body.quiz-stepped #quiz-submit { display: none; }     /* the nav bar owns the submit now */
body.quiz-stepped .q { margin: 0; }
body.quiz-stepped .q-hero .wide textarea { min-height: 34vh; }

/* One column, always. Two-across option tiles are what made it read as a horizontal form,
   and on a phone they were 150px wide with three words wrapped inside. */
body.quiz-stepped .opts,
body.quiz-stepped .setup-grid { grid-template-columns: 1fr; }

/* The progress rail. It answers the only question a stepper raises: how much is left. */
.quiz-rail { flex: 0 0 auto; padding: 14px 0 12px; }
.qp {
  height: 4px; background: var(--baseline); border-radius: 999px; overflow: hidden;
}
.qp-fill {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, var(--lawn), var(--data-deep));
  border-radius: 999px; transition: width .28s ease;
}
.qp-meta {
  display: flex; align-items: baseline; gap: 10px; margin: 8px 0 0;
  font-size: 12px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--muted);
}
.qp-title { font-family: var(--serif); font-size: 14px; font-weight: 700;
  letter-spacing: 0; text-transform: none; color: var(--ink-2); }

/* The nav bar. Fixed to the bottom of the frame, so Back and Next are in the same place on
   every question and never have to be hunted for. */
.quiz-nav {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 14px;
  padding: 14px 0 18px; border-top: 1px solid var(--grid);
  background: var(--page);
}
.quiz-nav .btn { margin-top: 0; }
.quiz-nav #q-next { margin-left: auto; }
.btn-ghost {
  background: transparent; color: var(--ink-2);
  border: 1.5px solid var(--baseline);
}
.btn-ghost:hover:not(:disabled) { border-color: var(--lawn); color: var(--lawn); }
.btn-ghost:disabled { opacity: .35; cursor: default; }
.btn-go { background: var(--court-dark); }
.q-keys { font-size: 12px; color: var(--muted); }
.q-keys kbd {
  font: 600 11px/1 var(--sans); background: var(--surface); color: var(--ink-2);
  border: 1px solid var(--baseline); border-bottom-width: 2px; border-radius: 4px;
  padding: 3px 5px;
}
@media (max-width: 620px) { .q-keys { display: none; } }   /* no keyboard, no hint */

/* Movement, so a step reads as a step and not as the page redrawing under you. */
.slide-in { animation: q-in .26s cubic-bezier(.2, .7, .3, 1) both; }
.slide-in.from-back { animation-name: q-back; }
@keyframes q-in   { from { opacity: 0; transform: translateX(14px); } }
@keyframes q-back { from { opacity: 0; transform: translateX(-14px); } }
@media (prefers-reduced-motion: reduce) {
  .slide-in, .slide-in.from-back { animation: none; }
  .qp-fill { transition: none; }
}

/* Six level tiles is the one question that can outgrow a phone. Tighten them rather than let
   the question scroll: the whole point of the stepper is that a question is a screen. */
body.quiz-stepped .opts-tight { gap: 8px; }
body.quiz-stepped .opts-tight span { padding: 9px 14px; }
body.quiz-stepped .opts-tight em { margin-top: 0; }

/* A question is a screen, so it sits in the middle of it, not pinned to the top with a lake of
   empty page under it. `safe center` because plain centering clips the TOP of a tall question
   out of reach when it does overflow: the write-up box on a small laptop. */
body.quiz-stepped .quiz-body { display: grid; align-content: safe center; }

/* The hint gets its own line. Trailing it after the question made it wrap into the title. */
body.quiz-stepped .q legend .q-hint { display: block; margin: 5px 0 0; }

/* On a small phone the last question (three fields plus the privacy note) is the one thing that
   still outgrows the card, and the submit label wrapped to two lines inside its own button. */
@media (max-width: 620px) {
  .quiz-nav { gap: 10px; }
  .quiz-nav .btn { padding: 13px 16px; font-size: 14.5px; white-space: nowrap; }
  body.quiz-stepped .q-note { font-size: 13px; margin-bottom: 10px; }
  body.quiz-stepped .form-fine { font-size: 12px; }
}
/* When a question does overflow, say so. A hard cut at the card edge reads as a broken layout;
   a fade reads as "there is more", which is what is true. */
body.quiz-stepped .quiz-nav { box-shadow: 0 -14px 16px -12px rgba(15, 43, 27, .16); }

/* The welcome had been apologising for itself ("ten questions, two minutes"), which sells a
   form, not a laboratory. The numbers do the boasting, so they get to be numbers. */
.hero-stats {
  list-style: none; display: flex; flex-wrap: wrap; gap: 10px 34px;
  margin: 18px 0 0; padding: 0;
}
.hero-stats li { display: flex; flex-direction: column; }
.hero-stats strong {
  font-family: var(--serif); font-size: 30px; font-weight: 800; line-height: 1;
  color: var(--ball); font-variant-numeric: tabular-nums;
}
.hero-stats span {
  font-size: 12px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: rgba(243, 239, 223, .72); margin-top: 5px; max-width: 22ch;
}
.hero-dek-2 { margin-top: 18px; }
@media (max-width: 620px) {
  .hero-stats { gap: 12px 22px; }
  .hero-stats strong { font-size: 24px; }
  .hero-stats span { font-size: 11px; }
}

/* ---- the first screen: why this is not a quiz ------------------------------------------
   Every card here is a claim we can point at code or data for. If a claim ever stops being
   true, the card comes out. That is the whole deal with the player. */
.pitch-h {
  font-family: var(--serif); font-size: 24px; margin: 6px 0 16px;
}
.pitch { display: grid; grid-template-columns: 1fr; gap: 12px; }
@media (min-width: 760px) { .pitch { grid-template-columns: 1fr 1fr; } }
.pitch article {
  background: var(--surface); border: 1px solid var(--baseline);
  border-left: 3px solid var(--lawn); border-radius: 8px; padding: 14px 16px;
}
.pitch h3 {
  font-family: var(--serif); font-size: 16.5px; margin: 0 0 6px;
}
.pitch p { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--ink-2); }
.pitch p + p { margin-top: 8px; }
.pitch-n {
  font: 700 11.5px/1.3 var(--sans) !important; letter-spacing: .06em; text-transform: uppercase;
  color: var(--data-deep) !important; font-variant-numeric: tabular-nums;
}
/* The honest card is the one that has to look as considered as the boasts, not like a
   disclaimer someone lawyered in at the end. */
.pitch-honest { border-left-color: var(--gold); }
@media (min-width: 760px) { .pitch-honest { grid-column: 1 / -1; } }
.pitch-honest .pitch-n { color: var(--gold-deep, #8a6a1f) !important; }

.pitch-help { margin-top: 14px; border-top: 1px solid var(--grid); padding-top: 12px; }
.pitch-help summary {
  cursor: pointer; font-weight: 700; font-size: 14px; color: var(--data-deep);
  list-style: none;
}
.pitch-help summary::-webkit-details-marker { display: none; }
.pitch-help summary::before { content: "+ "; font-weight: 800; }
.pitch-help[open] summary::before { content: "− "; }
.pitch-help-body { padding: 10px 0 2px; font-size: 13.5px; color: var(--ink-2); }
.pitch-help-body ul { margin: 8px 0; padding-left: 18px; display: grid; gap: 6px; }
.pitch-help-body strong { color: var(--ink); }

/* The counts, on the light ground of the first panel. */
.pitch-stats {
  /* A grid, not a wrapping flex row: four counts in a 640px column left one number stranded
     on a line of its own, which reads as a layout accident rather than a fact. */
  list-style: none; display: grid; grid-template-columns: 1fr 1fr; gap: 12px 20px;
  margin: 0 0 16px; padding: 0 0 14px; border-bottom: 1px solid var(--grid);
}
@media (min-width: 760px) { .pitch-stats { grid-template-columns: repeat(4, 1fr); } }
.pitch-stats li { display: flex; flex-direction: column; }
.pitch-stats strong {
  font-family: var(--serif); font-size: 26px; font-weight: 800; line-height: 1;
  color: var(--court-dark); font-variant-numeric: tabular-nums;
}
.pitch-stats span {
  font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); margin-top: 4px;
}
@media (max-width: 620px) {
  .pitch-stats { gap: 10px 20px; }
  .pitch-stats strong { font-size: 21px; }
  .pitch-h { font-size: 20px; margin-bottom: 12px; }
}

/* The pitch is the one screen with more to say than a question, so it gets a wider column.
   The card that admits what we cannot do must be ABOVE the fold, not scrolled past. */
body.quiz-stepped.quiz-intro .quiz { max-width: 900px; }

/* ---- the wait after submit -------------------------------------------------------------
   Anil: "there is no loading concept it just waits im like is it stuck". The work is real
   (Claude reads the notes, 285 frames are scored, the tension is solved per frame), so the
   screen says what is actually happening and shows the shape of what is coming. A skeleton,
   not a spinner: a spinner says "something", a skeleton says "your report". */
.load {
  position: fixed; inset: 0; z-index: 60; background: var(--page);
  overflow-y: auto; padding: 28px 18px 40px;
}
body.is-loading { overflow: hidden; }
.load-inner { max-width: 720px; margin: 0 auto; }
.load-eyebrow {
  font: 700 12px/1 var(--sans); letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); margin: 0 0 14px;
}
.load-steps { list-style: none; margin: 0 0 24px; padding: 0; display: grid; gap: 10px; }
.load-steps li {
  display: flex; align-items: center; gap: 10px;
  font-size: 14.5px; color: var(--muted); opacity: .45; transition: opacity .3s, color .3s;
}
.load-steps li.on { opacity: 1; color: var(--ink); font-weight: 600; }
.load-steps li.done { opacity: .8; color: var(--ink-2); font-weight: 400; }
.load-dot {
  width: 9px; height: 9px; border-radius: 50%; background: var(--baseline); flex: 0 0 auto;
}
.load-steps li.on .load-dot { background: var(--lawn); animation: pulse 1.1s ease-in-out infinite; }
.load-steps li.done .load-dot { background: var(--data-deep); animation: none; }
@keyframes pulse { 50% { transform: scale(1.5); opacity: .55; } }

.sk {
  background: linear-gradient(90deg, var(--grid) 25%, #efe9d7 37%, var(--grid) 63%);
  background-size: 400% 100%; border-radius: 8px;
  animation: shimmer 1.4s ease-in-out infinite;
}
@keyframes shimmer { from { background-position: 100% 0; } to { background-position: 0 0; } }
.sk-hero { height: 92px; margin-bottom: 14px; }
.sk-row { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; margin-bottom: 16px; }
.sk-card { height: 190px; }
.sk-line { height: 14px; margin-bottom: 8px; }
.sk-line.short { width: 62%; }
@media (prefers-reduced-motion: reduce) {
  .sk, .load-steps li.on .load-dot { animation: none; }
}

/* ---- the verdict, at the top of the report ---------------------------------------------- */
.hero-do {
  margin: 16px 0 0; font-size: 15.5px; color: #f3efdf;
  border-left: 3px solid var(--ball); padding-left: 12px;
}
.hero-do-k {
  display: block; font: 700 11px/1 var(--sans); letter-spacing: .1em; text-transform: uppercase;
  color: var(--ball); margin-bottom: 5px;
}

/* Rank and ownership, said out loud. Without these the reader cannot tell OUR pick from
   THEIR OWN racquet, which is exactly the confusion Anil hit. */
.cmp-rank {
  display: block; font: 700 10.5px/1.3 var(--sans); letter-spacing: .08em;
  text-transform: uppercase; color: var(--data-deep); margin-bottom: 5px;
}
.cmp-mine {
  display: block; color: var(--gold); font-weight: 800; letter-spacing: .06em; margin-top: 3px;
}
.cmp-head.is-mine { background: rgba(168, 132, 44, .08); border-radius: 8px 8px 0 0; }
.cmp-string b {
  display: block; font: 700 10px/1.3 var(--sans); letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 2px;
}
.cmp-same { border-left: 3px solid var(--lawn); padding-left: 12px; margin-top: 10px; }
.pick-scored { font-size: 13px; color: var(--muted); margin: 8px 0 0; }
.pick-scored b { color: var(--ink-2); font-variant-numeric: tabular-nums; }

/* ---- feedback floater ------------------------------------------------------------------
   A tab peeking from the right edge, on every page. Opens a panel in the site's own design.
   The endpoint behind it is the strictest route on the site; this is just the way in. */
.fb-tab {
  position: fixed; right: 0; top: 50%; z-index: 70;
  transform: translateY(-50%) rotate(180deg); writing-mode: vertical-rl;
  background: var(--court-dark); color: var(--ball);
  border: none; border-radius: 8px 0 0 8px; cursor: pointer;
  font: 700 12.5px/1 var(--sans); letter-spacing: .12em; text-transform: uppercase;
  padding: 16px 9px; box-shadow: -2px 2px 10px rgba(15, 43, 27, .22);
  transition: padding-right .16s ease, background .16s ease;
}
.fb-tab:hover { padding-right: 13px; background: var(--lawn); }
.fb-tab:focus-visible { outline: 2px solid var(--ball); outline-offset: 2px; }

.fb-panel {
  position: fixed; right: 16px; bottom: 16px; z-index: 71; width: min(370px, calc(100vw - 32px));
  background: var(--surface); border: 1px solid var(--baseline);
  border-top: 3px solid var(--gold); border-radius: 12px;
  box-shadow: 0 16px 44px rgba(15, 43, 27, .26); padding: 18px 18px 16px;
  animation: fb-in .2s ease both;
}
@keyframes fb-in { from { opacity: 0; transform: translateY(12px); } }
@media (prefers-reduced-motion: reduce) { .fb-panel { animation: none; } }

.fb-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.fb-head h2 { font-family: var(--serif); font-size: 19px; margin: 0 0 4px; }
.fb-x {
  background: none; border: none; font-size: 26px; line-height: 1; color: var(--muted);
  cursor: pointer; padding: 0 4px; margin: -4px -4px 0 0;
}
.fb-x:hover { color: var(--ink); }

.fb-form { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; }
.fb-l {
  font: 700 11px/1 var(--sans); letter-spacing: .07em; text-transform: uppercase;
  color: var(--ink-2); margin-top: 10px; margin-bottom: 5px;
}
.fb-select, .fb-textarea {
  width: 100%; font: 400 15px/1.4 var(--sans); color: var(--ink);
  background: var(--page); border: 1px solid var(--baseline); border-radius: 8px;
  padding: 11px 12px; min-height: 44px;
}
.fb-textarea { resize: vertical; }
.fb-select:focus, .fb-textarea:focus { outline: 2px solid var(--purple); outline-offset: 1px; }

/* The honeypot. Kept in the DOM for bots, kept off the screen and out of the tab order and the
   accessibility tree for humans. display:none can be detected and skipped by smarter bots, so
   it is moved off-canvas instead. */
.fb-hp {
  position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden;
}
.fb-submit { margin-top: 14px; width: 100%; }
.fb-note { font-size: 13px; margin: 10px 0 0; min-height: 1.1em; }
.fb-note.is-ok { color: var(--data-deep); font-weight: 600; }
.fb-note.is-err { color: var(--data-hot); font-weight: 600; }
.fb-fine { font-size: 11.5px; color: var(--muted); margin: 8px 0 0; }

@media (max-width: 620px) {
  .fb-tab { padding: 13px 8px; font-size: 11.5px; }
  .fb-panel { right: 8px; left: 8px; bottom: 8px; width: auto; }
}
