/* ==========================================================================
   TrueFans CONNECT™ — Artist Tools Design System
   Built for TrueFans CONNECT / Paul Saunders (New Music Lives)
   ========================================================================== */

:root {
  /* Brand */
  --tfc-purple:      #990FFA;
  --tfc-purple-deep: #6D0BB5;
  --tfc-purple-soft: #A369CD;
  --tfc-purple-wash: #F6EDFF;

  /* Neutrals */
  --ink:      #1d1d1f;
  --ink-2:    #43434a;
  --muted:    #6e6e73;
  --line:     #e8e8ed;
  --line-2:   #d6d6dd;
  --bg:       #ffffff;
  --surface:  #f5f5f7;
  --surface-2:#fafafc;

  /* Semantic */
  --good:     #0a7f4b;
  --good-bg:  #e8f7ef;
  --warn:     #a86400;
  --warn-bg:  #fdf3e2;
  --bad:      #c4321f;
  --bad-bg:   #fdeeec;

  /* Shape */
  --r-sm: 8px;
  --r:    14px;
  --r-lg: 20px;
  --shadow:    0 1px 2px rgba(0,0,0,.04), 0 8px 24px rgba(0,0,0,.06);
  --shadow-lg: 0 2px 6px rgba(0,0,0,.05), 0 20px 48px rgba(0,0,0,.10);

  --maxw: 1080px;
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto,
          Helvetica, Arial, sans-serif;
  --mono: "SF Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* Dark tokens are declared twice on purpose. The viewer has three states: an explicit
   light/dark choice stamps data-theme on <html>, and the default "system" setting stamps
   nothing — so prefers-color-scheme has to carry the un-stamped case on its own, while
   [data-theme="dark"] has to win when the OS says light. Components only ever read tokens,
   never colours declared inside these blocks. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ink:      #f5f5f7;
    --ink-2:    #d8d8de;
    --muted:    #9a9aa2;
    --line:     #2c2c31;
    --line-2:   #3a3a41;
    --bg:       #0f0f12;
    --surface:  #17171b;
    --surface-2:#1c1c21;
    --tfc-purple-wash: #23103a;
    --good-bg:  #0f2a1e;
    --warn-bg:  #2c2110;
    --bad-bg:   #2e1512;
    --shadow:    0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.45);
    --shadow-lg: 0 2px 6px rgba(0,0,0,.5), 0 20px 48px rgba(0,0,0,.55);
  }
}
:root[data-theme="dark"] {
  --ink:      #f5f5f7;
  --ink-2:    #d8d8de;
  --muted:    #9a9aa2;
  --line:     #2c2c31;
  --line-2:   #3a3a41;
  --bg:       #0f0f12;
  --surface:  #17171b;
  --surface-2:#1c1c21;
  --tfc-purple-wash: #23103a;
  --good-bg:  #0f2a1e;
  --warn-bg:  #2c2110;
  --bad-bg:   #2e1512;
  --shadow:    0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.45);
  --shadow-lg: 0 2px 6px rgba(0,0,0,.5), 0 20px 48px rgba(0,0,0,.55);
}

/* ---------- Base ---------- */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font);
  color: var(--ink);
  background: var(--bg);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--tfc-purple); text-decoration: none; }
a:hover { text-decoration: underline; }
img { max-width: 100%; height: auto; }

.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 20px; }
/* Auto margins matter as much as the width: without them this sits flush left in
   the 1040px column, so a centred hero centres on 820px of a wider page and lands
   110px left of the card below it. Only ever used on .hero today. */
.narrow { max-width: 820px; margin-left: auto; margin-right: auto; }

/* ---------- Header ---------- */
.tfc-header {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--line);
}
.tfc-header .wrap {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; height: 60px;
}
/* Scoped to the header: a bare `.brand` would collide with the `.note.brand` callout tone. */
.tfc-header .brand { display: flex; align-items: center; gap: 10px; font-weight: 650; color: var(--ink); letter-spacing: -.01em; }
.tfc-header .brand:hover { text-decoration: none; }
.brand-mark {
  width: 30px; height: 30px; border-radius: 8px; flex: none;
  background: linear-gradient(135deg, var(--tfc-purple) 0%, var(--tfc-purple-deep) 100%);
  display: grid; place-items: center; color: #fff; font-size: 14px; font-weight: 800;
}
/* "TrueFans CALCULATORS" — the second word is the product, so it carries the accent. */
.brand-name { font-size: 15px; font-weight: 500; }
.brand-name span { color: var(--tfc-purple); font-weight: 750; letter-spacing: .015em; }
.header-nav { display: flex; align-items: center; gap: 18px; font-size: 14px; }
.header-nav a { color: var(--ink-2); }
@media (max-width: 640px) { .header-nav .hide-sm { display: none; } }

/* ---------- Hero ---------- */
.hero { padding: 56px 0 28px; text-align: center; }
.eyebrow {
  display: inline-block; font-size: 12px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--tfc-purple);
  background: var(--tfc-purple-wash); padding: 6px 12px; border-radius: 999px;
  margin-bottom: 18px;
}
h1 { font-size: clamp(30px, 5vw, 46px); line-height: 1.08; letter-spacing: -.025em; margin: 0 0 14px; font-weight: 700; }
/* text-wrap: pretty stops the lede ending on a single trailing word. It pulls a word
   down from the line above instead of widening the measure, so the Paul build keeps
   the 600px lede width transcribed from his site. Browsers without it just wrap as
   before — no layout shift, no fallback needed. */
.lede { font-size: clamp(16px, 2vw, 19px); color: var(--muted); margin: 0; max-width: 62ch; text-wrap: pretty; }
/* Two ledes ship on the hub pages: the full one, split in two paragraphs so it
   is not a wall of text, and a short one for phones. Nine lines of subhead was
   pushing the first calculator most of a screen down. display:none keeps the
   hidden one out of the accessibility tree, so nothing is read out twice. */
.hero .lede + .lede { margin-top: 14px; }
.lede-short { display: none; }
@media (max-width: 700px) {
  .lede-full { display: none; }
  .lede-short { display: block; }
}
/* The hero is centred, so its lede has to centre its own 62ch measure too —
   text-align alone would leave the block hard against the left edge. */
.hero .lede { margin-left: auto; margin-right: auto; }

/* ---------- Cards & sections ---------- */
.card {
  background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow);
  padding: 28px; margin: 24px 0;
}
.card.flat { box-shadow: none; background: var(--surface-2); }
.section { margin: 0 0 26px; }
.section:last-child { margin-bottom: 0; }
.section-title {
  font-size: 12px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--tfc-purple); margin: 0 0 4px;
}
.section-note { font-size: 13px; color: var(--muted); margin: 0 0 16px; }
hr.rule { border: 0; border-top: 1px solid var(--line); margin: 26px 0; }

/* ---------- Form ---------- */
.grid { display: grid; gap: 14px; grid-template-columns: repeat(3, 1fr); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 860px) { .grid, .grid-4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .grid, .grid-2, .grid-4 { grid-template-columns: 1fr; } }

.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field.span-2 { grid-column: span 2; }
@media (max-width: 560px) { .field.span-2 { grid-column: span 1; } }
.field label { font-size: 13px; font-weight: 600; color: var(--ink-2); }
.field .hint { font-size: 11.5px; color: var(--muted); line-height: 1.35; }

.input-wrap { position: relative; display: flex; align-items: center; }
.input-wrap .affix {
  position: absolute; font-size: 14px; color: var(--muted); pointer-events: none; font-weight: 500;
}
.input-wrap .affix.pre  { left: 12px; }
.input-wrap .affix.post { right: 12px; }
.input-wrap.has-pre  input { padding-left: 26px; }
.input-wrap.has-post input { padding-right: 32px; }

input[type="number"], input[type="text"], input[type="date"],
input[type="email"], input[type="tel"], input[type="search"], select, textarea {
  width: 100%; font: inherit; font-size: 15px; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 10px 12px; transition: border-color .15s, box-shadow .15s;
  appearance: none; -webkit-appearance: none;
}
select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%236e6e73' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center; padding-right: 32px;
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--tfc-purple);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--tfc-purple) 18%, transparent);
  /* background-color, not the shorthand — the shorthand would drop the select
     arrow image the moment the field is focused. */
  background-color: var(--bg);
}
input::placeholder { color: color-mix(in srgb, var(--muted) 70%, transparent); }
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[type=number] { -moz-appearance: textfield; }

/* checkbox rows */
.checks { display: flex; flex-wrap: wrap; gap: 10px; }
.check {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  font-size: 14px; color: var(--ink-2); background: var(--surface);
  border: 1px solid var(--line); border-radius: 999px; padding: 8px 14px;
  transition: all .15s; user-select: none;
}
.check:has(input:checked) {
  border-color: var(--tfc-purple); background: var(--tfc-purple-wash);
  color: var(--tfc-purple-deep); font-weight: 600;
}
.check input { accent-color: var(--tfc-purple); width: 15px; height: 15px; margin: 0; }

/* segmented control */
.seg {
  display: inline-flex; background: var(--surface); border: 1px solid var(--line);
  border-radius: 999px; padding: 3px; gap: 2px;
}
.seg button {
  font: inherit; font-size: 13px; font-weight: 600; color: var(--muted);
  background: transparent; border: 0; border-radius: 999px; padding: 7px 16px;
  cursor: pointer; transition: all .15s; white-space: nowrap;
}
.seg button[aria-pressed="true"] {
  background: var(--bg); color: var(--tfc-purple-deep);
  box-shadow: 0 1px 3px rgba(0,0,0,.10);
}
.seg-row { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px; margin-bottom: 18px; }

/* ---------- Buttons ---------- */
.actions { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin-top: 8px; }
.btn {
  font: inherit; font-size: 15px; font-weight: 650; letter-spacing: .01em;
  border-radius: 999px; padding: 13px 28px; cursor: pointer; border: 1px solid transparent;
  transition: transform .12s, box-shadow .15s, background .15s; display: inline-flex;
  align-items: center; gap: 8px; text-decoration: none;
}
.btn:hover { text-decoration: none; }
.btn:active { transform: scale(.98); }
.btn-primary {
  background: linear-gradient(135deg, var(--tfc-purple) 0%, var(--tfc-purple-deep) 100%);
  color: #fff; box-shadow: 0 4px 14px color-mix(in srgb, var(--tfc-purple) 34%, transparent);
}
.btn-primary:hover { box-shadow: 0 6px 20px color-mix(in srgb, var(--tfc-purple) 45%, transparent); }
.btn-ghost { background: var(--surface); color: var(--ink-2); border-color: var(--line-2); }
.btn-ghost:hover { background: var(--line); }
.btn-sm { font-size: 13px; padding: 9px 18px; }

/* ---------- Results ---------- */
.results { display: none; margin-top: 8px; }
.results.show { display: block; animation: fade .35s ease; }
@keyframes fade { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

.headline {
  background: linear-gradient(135deg, var(--tfc-purple) 0%, var(--tfc-purple-deep) 100%);
  color: #fff; border-radius: var(--r-lg); padding: 32px 28px; text-align: center;
  box-shadow: var(--shadow-lg);
}
.headline .label {
  font-size: 12px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  opacity: .8; margin-bottom: 8px;
}
.headline .value {
  font-size: clamp(38px, 8vw, 60px); font-weight: 700; letter-spacing: -.03em; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.headline .sub { font-size: 15px; opacity: .88; margin-top: 10px; }
.headline.is-bad { background: linear-gradient(135deg, #d6503c 0%, #a5271a 100%); }
.headline.is-good { background: linear-gradient(135deg, #0f9e5e 0%, #076b3e 100%); }

.stats { display: grid; gap: 12px; grid-template-columns: repeat(4, 1fr); margin-top: 16px; }
@media (max-width: 860px) { .stats { grid-template-columns: repeat(2, 1fr); } }
.stat {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
  padding: 16px 18px;
}
.stat .k { font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.stat .v {
  font-size: 24px; font-weight: 700; letter-spacing: -.02em; margin-top: 5px;
  font-variant-numeric: tabular-nums;
}
.stat .n { font-size: 12px; color: var(--muted); margin-top: 3px; line-height: 1.35; }
.stat.pos .v { color: var(--good); }
.stat.neg .v { color: var(--bad); }
.stat.accent .v { color: var(--tfc-purple); }

/* table */
.tbl-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; margin-top: 16px; }
table.tfc {
  width: 100%; border-collapse: collapse; font-size: 14px; min-width: 460px;
}
table.tfc th, table.tfc td {
  text-align: right; padding: 11px 14px; border-bottom: 1px solid var(--line);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
table.tfc th:first-child, table.tfc td:first-child { text-align: left; white-space: normal; }
table.tfc thead th {
  font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); border-bottom: 1px solid var(--line-2);
}
table.tfc tbody tr:hover { background: var(--surface-2); }
table.tfc tfoot td { font-weight: 700; border-top: 2px solid var(--line-2); border-bottom: 0; }
table.tfc td.pos { color: var(--good); font-weight: 600; }
table.tfc td.neg { color: var(--bad); font-weight: 600; }
table.tfc td.dim { color: var(--muted); }

/* callouts */
.note {
  border-radius: var(--r); padding: 14px 18px; font-size: 14.5px; margin-top: 12px;
  border: 1px solid var(--line); background: var(--surface); line-height: 1.5;
}
.note strong { font-weight: 700; }
.note.good { background: var(--good-bg); border-color: color-mix(in srgb, var(--good) 25%, transparent); color: var(--good); }
.note.warn { background: var(--warn-bg); border-color: color-mix(in srgb, var(--warn) 25%, transparent); color: var(--warn); }
.note.bad  { background: var(--bad-bg);  border-color: color-mix(in srgb, var(--bad) 25%, transparent);  color: var(--bad); }
.note.brand { background: var(--tfc-purple-wash); border-color: color-mix(in srgb, var(--tfc-purple) 25%, transparent); color: var(--tfc-purple-deep); }
.notes-list { display: flex; flex-direction: column; gap: 0; }

h3.res-h {
  font-size: 17px; font-weight: 700; letter-spacing: -.01em; margin: 28px 0 2px;
}
p.res-p { font-size: 14px; color: var(--muted); margin: 0 0 4px; }

/* ---------- Timeline (release planner) ---------- */
.timeline { margin-top: 18px; position: relative; }
.phase {
  position: relative; padding-left: 30px; padding-bottom: 26px; border-left: 2px solid var(--line);
}
.phase:last-child { border-left-color: transparent; padding-bottom: 0; }
.phase::before {
  content: ""; position: absolute; left: -7px; top: 4px; width: 12px; height: 12px;
  border-radius: 50%; background: var(--tfc-purple); box-shadow: 0 0 0 4px var(--bg);
}
.phase-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px; }
.phase-name { font-size: 16px; font-weight: 700; letter-spacing: -.01em; }
.phase-when {
  font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--tfc-purple); background: var(--tfc-purple-wash); padding: 3px 9px; border-radius: 999px;
}
.phase-date { font-size: 12.5px; color: var(--muted); }
.phase ul { margin: 10px 0 0; padding-left: 18px; }
.phase li { font-size: 14.5px; color: var(--ink-2); margin-bottom: 5px; line-height: 1.45; }
.phase li b { color: var(--ink); }

/* bar meter */
.bars { margin-top: 14px; display: flex; flex-direction: column; gap: 10px; }
.bar-row { display: grid; grid-template-columns: minmax(120px, 1.1fr) 3fr minmax(90px, auto); gap: 12px; align-items: center; font-size: 13.5px; }
@media (max-width: 560px) { .bar-row { grid-template-columns: 1fr; gap: 4px; } }
.bar-track { background: var(--surface); border-radius: 999px; height: 10px; overflow: hidden; border: 1px solid var(--line); }
.bar-fill { height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--tfc-purple-soft), var(--tfc-purple)); }
.bar-val { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }

/* ---------- Tool name lockup: "TrueFans SPLITS" ----------
   Used in tool <h1>s, hub card <h3>s and the "where to start" timeline. */
.tf-word { color: var(--tfc-purple); }
.phase-name .tf-word { color: var(--tfc-purple); }

/* ---------- Collaborator rows (splits) ---------- */
.collab-head, .collab {
  display: grid; grid-template-columns: 2.2fr 1.5fr 1fr 1fr 38px;
  gap: 10px; align-items: center;
}
.collab-head {
  font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 8px;
}
.collab { margin-bottom: 10px; }
.collab .rm {
  font: inherit; font-size: 20px; line-height: 1; color: var(--muted);
  background: transparent; border: 1px solid var(--line); border-radius: var(--r-sm);
  height: 40px; cursor: pointer; transition: all .15s;
}
.collab .rm:hover { color: var(--bad); border-color: var(--bad); background: var(--bad-bg); }
@media (max-width: 700px) {
  .collab-head { display: none; }
  .collab {
    grid-template-columns: 1fr 1fr; gap: 8px;
    border: 1px solid var(--line); border-radius: var(--r); padding: 12px; margin-bottom: 12px;
  }
  .collab [data-f="name"] { grid-column: 1 / -1; }
  .collab .rm { grid-column: 1 / -1; height: 34px; }
}

.tot {
  display: inline-block; font-size: 12px; font-weight: 700; border-radius: 999px;
  padding: 4px 11px; margin-left: 8px; font-variant-numeric: tabular-nums;
}
.tot.good { background: var(--good-bg); color: var(--good); }
.tot.warn { background: var(--warn-bg); color: var(--warn); }
.tot.bad  { background: var(--bad-bg);  color: var(--bad); }

/* ---------- Printable split sheet ---------- */
.sheet {
  border: 1px solid var(--line-2); border-radius: var(--r);
  background: var(--surface-2); padding: 26px 28px; margin-top: 16px;
}
.sheet-title {
  font-size: 13px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--tfc-purple); margin-bottom: 6px;
}
.sheet-meta { font-size: 15px; margin-bottom: 14px; }
.sheet-intro, .sheet-foot { font-size: 13px; color: var(--muted); line-height: 1.55; }
.sheet-intro { margin: 0 0 18px; }
.sheet-foot { margin: 18px 0 0; }
.sheet-row {
  display: grid; grid-template-columns: 2fr 1fr 1fr 2.2fr; gap: 14px;
  align-items: center; padding: 12px 0; border-bottom: 1px solid var(--line);
  font-variant-numeric: tabular-nums;
}
.sheet-row.sheet-head {
  font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); padding-top: 0;
}
.sheet-row.sheet-total { border-bottom: 0; border-top: 2px solid var(--line-2); }
.sig { display: block; border-bottom: 1px solid var(--line-2); height: 26px; }
@media (max-width: 640px) {
  .sheet-row { grid-template-columns: 1fr 1fr; }
  .sheet-row.sheet-head { display: none; }
}

/* ---------- Assumptions disclosure ---------- */
details.assump {
  margin-top: 18px; border: 1px solid var(--line); border-radius: var(--r);
  background: var(--surface-2); padding: 0 18px;
}
details.assump summary {
  cursor: pointer; font-size: 13.5px; font-weight: 650; color: var(--ink-2);
  padding: 14px 0; list-style: none;
}
details.assump summary::-webkit-details-marker { display: none; }
details.assump summary::before { content: "▸ "; color: var(--tfc-purple); }
details.assump[open] summary::before { content: "▾ "; }
details.assump .body { padding-bottom: 16px; font-size: 13.5px; color: var(--muted); line-height: 1.6; }
details.assump ul { padding-left: 18px; margin: 8px 0; }
details.assump li { margin-bottom: 4px; }

/* ---------- Tool index grid ---------- */
.tools { display: grid; gap: 18px; grid-template-columns: repeat(3, 1fr); margin: 32px 0 8px; }
@media (max-width: 900px) { .tools { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px) { .tools { grid-template-columns: 1fr; } }
.tool {
  display: flex; flex-direction: column; background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 24px; box-shadow: var(--shadow);
  transition: transform .18s, box-shadow .18s, border-color .18s; color: inherit;
}
.tool:hover {
  text-decoration: none; transform: translateY(-3px);
  box-shadow: var(--shadow-lg); border-color: color-mix(in srgb, var(--tfc-purple) 35%, var(--line));
}
.tool-icon {
  width: 42px; height: 42px; border-radius: 12px; display: grid; place-items: center;
  background: var(--tfc-purple-wash); color: var(--tfc-purple-deep); font-size: 20px; margin-bottom: 14px;
}
.tool h3 { font-size: 17px; font-weight: 700; letter-spacing: -.015em; margin: 0 0 7px; }
.tool p { font-size: 14px; color: var(--muted); margin: 0 0 16px; line-height: 1.45; flex: 1; }
.tool .go { font-size: 13.5px; font-weight: 650; color: var(--tfc-purple); }

/* ---------- Studio band (hub) ---------- */
.studio {
  display: grid; grid-template-columns: auto 1fr auto; gap: 22px; align-items: center;
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 26px 28px; margin: 22px 0 8px; box-shadow: var(--shadow); color: inherit;
  transition: transform .18s, box-shadow .18s, border-color .18s;
}
.studio:hover {
  text-decoration: none; transform: translateY(-3px);
  box-shadow: var(--shadow-lg); border-color: color-mix(in srgb, var(--tfc-purple) 35%, var(--line));
}
.studio-icon {
  width: 54px; height: 54px; border-radius: 14px; display: grid; place-items: center;
  background: linear-gradient(135deg, var(--tfc-purple) 0%, var(--tfc-purple-deep) 100%);
  color: #fff; font-size: 24px;
}
.studio-kicker {
  display: block; font-size: 11px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--tfc-purple); margin-bottom: 6px;
}
.studio h3 { font-size: 18px; font-weight: 700; letter-spacing: -.015em; margin: 0 0 6px; }
.studio p { font-size: 14.5px; color: var(--muted); margin: 0; line-height: 1.45; max-width: 62ch; }
.studio .go { font-size: 13.5px; font-weight: 650; color: var(--tfc-purple); white-space: nowrap; }
@media (max-width: 760px) {
  .studio { grid-template-columns: auto 1fr; gap: 16px; }
  .studio .go { grid-column: 1 / -1; }
}

/* ---------- Dropzone (master) ---------- */
.dropzone {
  border: 2px dashed var(--line-2); border-radius: var(--r-lg);
  padding: 44px 24px; text-align: center; cursor: pointer;
  background: var(--surface-2); transition: all .18s;
}
.dropzone:hover, .dropzone.over, .dropzone:focus-visible {
  border-color: var(--tfc-purple); background: var(--tfc-purple-wash);
}
.dz-icon {
  width: 44px; height: 44px; margin: 0 auto 14px; border-radius: 50%;
  background: var(--tfc-purple); color: #fff; display: grid; place-items: center;
  font-size: 20px; font-weight: 700;
}
.dz-main { font-size: 16px; font-weight: 650; color: var(--ink); }
.dz-sub { font-size: 13px; color: var(--muted); margin-top: 6px; }

.loaded {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  flex-wrap: wrap; padding: 14px 18px; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r); margin-bottom: 4px;
}

/* ---------- Preset grid ---------- */
.presets { display: grid; gap: 10px; grid-template-columns: repeat(5, 1fr); }
@media (max-width: 1000px) { .presets { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 620px)  { .presets { grid-template-columns: repeat(2, 1fr); } }
.preset {
  font: inherit; text-align: left; cursor: pointer; display: flex; flex-direction: column; gap: 3px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
  padding: 13px 15px; transition: all .15s; color: var(--ink);
}
.preset:hover { border-color: var(--line-2); background: var(--surface-2); }
.preset.on {
  border-color: var(--tfc-purple); background: var(--tfc-purple-wash);
  box-shadow: 0 0 0 1px var(--tfc-purple);
}
.preset .p-name { font-size: 13.5px; font-weight: 700; letter-spacing: -.01em; }
.preset.on .p-name { color: var(--tfc-purple-deep); }
.preset .p-desc { font-size: 11.5px; color: var(--muted); line-height: 1.35; }
.preset .p-lufs {
  font-size: 11px; font-weight: 700; color: var(--muted);
  font-variant-numeric: tabular-nums; margin-top: 2px;
}
.ref-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 16px; }

/* ---------- A/B transport ---------- */
.ab {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); padding: 20px; margin-top: 14px;
}
.ab-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }

/* ---------- CTA ---------- */
.cta {
  margin: 40px 0 8px; border-radius: var(--r-lg); padding: 36px 32px; text-align: center;
  background: var(--surface); border: 1px solid var(--line);
}
.cta h2 { font-size: clamp(22px, 3.4vw, 30px); letter-spacing: -.02em; margin: 0 0 10px; font-weight: 700; }
.cta p { color: var(--muted); margin: 0 auto 22px; max-width: 56ch; font-size: 16px; }

/* ---------- Footer ---------- */
.tfc-footer {
  border-top: 1px solid var(--line); margin-top: 56px; padding: 32px 0 44px;
  font-size: 13.5px; color: var(--muted);
}
.tfc-footer .wrap { display: flex; flex-wrap: wrap; gap: 14px; justify-content: space-between; align-items: center; }
.tfc-footer .links { display: flex; flex-wrap: wrap; gap: 18px; }
.tfc-footer a { color: var(--muted); }
.tfc-footer a:hover { color: var(--tfc-purple); }
.disclaimer { margin-top: 14px; font-size: 12px; line-height: 1.5; max-width: 72ch; }

/* ---------- Utilities ---------- */
.mt-0 { margin-top: 0; } .mt-8 { margin-top: 8px; } .mt-16 { margin-top: 16px; } .mt-24 { margin-top: 24px; }
.mb-0 { margin-bottom: 0; }
.tc { text-align: center; }
.hidden { display: none !important; }
.nowrap { white-space: nowrap; }
.small { font-size: 13px; color: var(--muted); }

/* ---------- Print ---------- */
@media print {
  .tfc-header, .actions, .cta, .tfc-footer .links, .btn { display: none !important; }
  body { background: #fff; color: #000; }
  .card { box-shadow: none; border-color: #ccc; page-break-inside: avoid; }
  .headline { background: #f0f0f0 !important; color: #000 !important; }
  .results { display: block !important; }
}

/* ---------- "Email me these results" ---------- */
.emailer {
  margin-top: 28px; border: 1px solid var(--line);
  border-radius: var(--r); background: var(--surface); overflow: hidden;
}
.emailer-head { padding: 22px 24px 0; }
.emailer-head h3 { font-size: 17px; font-weight: 700; letter-spacing: -.01em; margin: 0 0 6px; }
.emailer-head p { font-size: 14px; color: var(--muted); margin: 0; line-height: 1.5; }
.emailer-form { padding: 16px 24px 24px; }
.emailer-fields { display: grid; grid-template-columns: 1fr 1.4fr; gap: 10px; margin-bottom: 12px; }
@media (max-width: 560px) { .emailer-fields { grid-template-columns: 1fr; } }
.emailer-fields input[type="text"], .emailer-fields input[type="email"] { width: 100%; }
/* honeypot — off-screen rather than display:none, which bots skip */
.emailer-fields input[tabindex="-1"] {
  position: absolute !important; left: -9999px; width: 1px; height: 1px;
  opacity: 0; pointer-events: none;
}
.emailer-consent {
  align-items: flex-start; border-radius: var(--r-sm); padding: 10px 14px;
  font-size: 13px; line-height: 1.45; margin-bottom: 4px; width: 100%;
}
.emailer-consent input { margin-top: 2px; flex: none; }
.emailer-status { margin: 10px 0 0; min-height: 1.2em; }
.emailer-status.good { color: var(--good); font-weight: 600; }
.emailer-status.warn { color: var(--warn); }
.emailer-status.bad  { color: var(--bad); }
@media print { .emailer { display: none !important; } }

/* ---------- The unlock gate, and the membership pitch after it ----------
   The gate stands in for the results panel, so it carries the same measure and
   sits on the page background like #res does — not on a card. Both builds get
   their surface colours from the same tokens, so this needs no per-brand rule. */
.gate {
  border: 1px solid var(--line); border-radius: var(--r-lg);
  background: var(--surface); padding: 30px 28px; text-align: center;
  max-width: 560px; margin: 0 auto;
}
.gate-lock { color: var(--tfc-purple); font-size: 22px; line-height: 1; margin-bottom: 12px; }
.gate h3 { font-size: 20px; font-weight: 700; letter-spacing: -.015em; margin: 0 0 8px; }
.gate > p { font-size: 15px; color: var(--muted); line-height: 1.6; margin: 0 0 20px; text-wrap: pretty; }
.gate-fields { display: grid; grid-template-columns: 1fr 1.4fr; gap: 10px; margin-bottom: 12px; }
@media (max-width: 560px) { .gate-fields { grid-template-columns: 1fr; } }
.gate-fields input { width: 100%; }
/* honeypot — off-screen rather than display:none, which bots skip */
.gate-fields input[tabindex="-1"] {
  position: absolute !important; left: -9999px; width: 1px; height: 1px;
  opacity: 0; pointer-events: none;
}
.gate-consent {
  align-items: flex-start; text-align: left; border-radius: var(--r-sm);
  padding: 10px 14px; font-size: 13px; line-height: 1.45; margin-bottom: 14px; width: 100%;
}
.gate-consent input { margin-top: 2px; flex: none; }
.gate .btn-primary { width: 100%; }
.gate-status { margin: 12px 0 0; min-height: 1.2em; }
.gate-status.bad { color: var(--bad); font-weight: 600; }
.gate-fine { color: var(--muted); margin: 12px 0 0; font-size: 12.5px; }

.pitch {
  margin-top: 28px; border: 1px solid var(--tfc-purple); border-radius: var(--r-lg);
  background: var(--tfc-purple-wash); padding: 26px 28px; text-align: center;
}
.pitch h3 { font-size: 18px; font-weight: 700; letter-spacing: -.015em; margin: 0 0 8px; }
.pitch p { font-size: 14.5px; color: var(--ink-2); line-height: 1.6; margin: 0 0 18px; text-wrap: pretty; }
@media print { .gate, .pitch { display: none !important; } }

/* ---------- Free / gated badges ---------- */
.badge {
  display: inline-block; font-size: 11px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; padding: 4px 9px; border-radius: 999px; white-space: nowrap;
}
.badge-free { color: var(--good); background: var(--good-bg); }
.badge-gated { color: var(--tfc-purple); background: var(--tfc-purple-wash); }
/* On a hub card the badge sits with the icon, so the title keeps the full width. */
.tool-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
/* At the top of a tool page, above the h1. */
/* This row sits inside .hero, which is centred, but a flex container packs its
   items to the start regardless of text-align — so the badge and note hung off
   the left edge while the eyebrow, h1 and lede above and below were centred. */
.tool-access { display: flex; align-items: center; justify-content: center; gap: 10px; margin: 0 0 14px; flex-wrap: wrap; }
.tool-access .small { color: var(--muted); margin: 0; }


/* ---------- Mobile ----------
   Found by auditing at 360/375/390px: the four-option segmented control was
   485px wide on a 375px screen, and several controls sat under the 44px
   minimum for a comfortable touch target. */
@media (max-width: 620px) {
  .seg-row { flex-direction: column; align-items: stretch; gap: 14px; }
  .seg {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    width: 100%; gap: 3px;
  }
  .seg button { width: 100%; }
  .actions { gap: 10px; }
  .actions .btn { flex: 1 1 100%; justify-content: center; }
  .actions .btn-sm { flex: 0 1 auto; }
}

@media (pointer: coarse) {
  /* 16px is a hard floor on touch devices: iOS Safari zooms the whole page in
     when you focus a field smaller than this, and never zooms back out. Artists
     filling these in on a phone would have to pinch out after every field. */
  input[type="number"], input[type="text"], input[type="date"],
  input[type="email"], input[type="tel"], input[type="search"], select, textarea {
    font-size: 16px;
  }
  .btn { min-height: 44px; }
  .btn-sm { min-height: 44px; padding: 10px 18px; }
  .seg button { min-height: 44px; }
  .check { min-height: 44px; }
  .collab .rm { min-height: 44px; }
  /* Cross-references sitting inside a sentence are exempt from the 44px rule,
     but they are still links people tap. Vertical padding on an inline element
     grows the hit area without changing line height or how the text wraps —
     inline-block here would break the wrapping mid-sentence. */
  .hint a, .note a, .disclaimer a, .section-note a { padding: 9px 0; }
  /* Secondary links are still links people tap — give them a real target. */
  .tfc-footer .links a { display: inline-block; padding: 12px 0; }
  .header-nav a { display: inline-flex; align-items: center; min-height: 44px; }
  .tfc-header .brand { min-height: 44px; }
  .small a, p.small > a { display: inline-block; padding: 12px 0; }
}

/* Long words in narrow columns shouldn't force the page sideways. */
@media (max-width: 480px) {
  h1, .tool h3, .studio h3, .headline .value { overflow-wrap: anywhere; }
  .headline { padding: 26px 18px; }
  .stat .v { font-size: 21px; }
}

/* ---------- Phone header ---------- */
@media (max-width: 620px) {
  .tfc-header .wrap { height: auto; padding-top: 10px; padding-bottom: 10px; gap: 10px; }
  .brand-name { font-size: 13px; white-space: nowrap; }
  .header-nav { gap: 12px; font-size: 12.5px; }
  .header-nav a { white-space: nowrap; }
  .eyebrow { font-size: 11px; padding: 5px 10px; letter-spacing: .08em; }
}

/* Narrowest phones: shed what isn't essential rather than let the bar overflow. */
@media (max-width: 480px) {
  .wrap { padding: 0 14px; }
  .header-nav .hide-xs { display: none; }
  .brand-mark { width: 26px; height: 26px; font-size: 12px; }
  .brand-name { font-size: 12px; }
  .header-nav { gap: 10px; font-size: 12px; }
  .eyebrow { font-size: 10.5px; letter-spacing: .06em; }
}

/* ---------- Mobile: tables and bars ---------- */
/* Wide tables scroll inside their own box. Without a hint that looks like a
   clipped column, so shade the edges — the shadow only shows when scrollable. */
.tbl-scroll {
  /* The two cover gradients must match whatever the table actually sits on, or
     they paint a smudge at its edges. Results render into #res, which paints no
     background of its own, so that is the body — var(--bg) on both builds. A
     theme that puts tables on some other surface overrides --tbl-cover. */
  background:
    linear-gradient(to right, var(--tbl-cover, var(--bg)) 30%, rgba(0,0,0,0)),
    linear-gradient(to right, rgba(0,0,0,0), var(--tbl-cover, var(--bg)) 70%) 100% 0,
    radial-gradient(farthest-side at 0 50%, rgba(0,0,0,.18), rgba(0,0,0,0)),
    radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,.18), rgba(0,0,0,0)) 100% 0;
  background-repeat: no-repeat;
  background-size: 34px 100%, 34px 100%, 12px 100%, 12px 100%;
  background-attachment: local, local, scroll, scroll;
}

@media (max-width: 560px) {
  /* Label and value on one line, bar full width beneath — the value floating
     alone under the bar read as unrelated to it. */
  .bar-row {
    grid-template-columns: 1fr auto;
    grid-template-areas: "label value" "track track";
    gap: 6px 12px;
  }
  .bar-row > :nth-child(1) { grid-area: label; }
  .bar-row > :nth-child(2) { grid-area: track; }
  .bar-row > :nth-child(3) { grid-area: value; }
  table.tfc { min-width: 380px; }
  .stats { gap: 10px; }
}
