/* Alegreya Sans SC — the whole site, self-hosted.
   🔴 Self-hosted deliberately: a site that fetches its fonts from another
   company's server stops working when that server does, and tells that
   company who is reading the page.
   ⚠️ "SC" is small caps — there is no lowercase in this family, so every
   word on every page renders in capital forms, including the questions
   respondents read. See docs/fonts.md for what this replaced, how to revert,
   and the two middle paths if the full effect is too much.
   📌 font-display:swap so text is readable immediately in the system font
   and reflows when the file arrives, rather than showing nothing. */
@font-face{
  font-family:"Alegreya Sans SC"; font-style:normal; font-weight:400;
  font-display:swap;
  src:url("fonts/alegreya-sans-sc-400-latin.woff2") format("woff2");
}
@font-face{
  font-family:"Alegreya Sans SC"; font-style:normal; font-weight:400;
  font-display:swap;
  src:url("fonts/alegreya-sans-sc-400-ext.woff2") format("woff2");
}
@font-face{
  font-family:"Alegreya Sans SC"; font-style:normal; font-weight:500;
  font-display:swap;
  src:url("fonts/alegreya-sans-sc-500-latin.woff2") format("woff2");
}
@font-face{
  font-family:"Alegreya Sans SC"; font-style:normal; font-weight:500;
  font-display:swap;
  src:url("fonts/alegreya-sans-sc-500-ext.woff2") format("woff2");
}
@font-face{
  font-family:"Alegreya Sans SC"; font-style:normal; font-weight:700;
  font-display:swap;
  src:url("fonts/alegreya-sans-sc-700-latin.woff2") format("woff2");
}
@font-face{
  font-family:"Alegreya Sans SC"; font-style:normal; font-weight:700;
  font-display:swap;
  src:url("fonts/alegreya-sans-sc-700-ext.woff2") format("woff2");
}
@font-face{
  font-family:"Alegreya Sans SC"; font-style:italic; font-weight:400;
  font-display:swap;
  src:url("fonts/alegreya-sans-sc-400-italic-latin.woff2") format("woff2");
}
@font-face{
  font-family:"Alegreya Sans SC"; font-style:italic; font-weight:400;
  font-display:swap;
  src:url("fonts/alegreya-sans-sc-400-italic-ext.woff2") format("woff2");
}

:root{--ink:#1a1d21;--dim:#5b6470;--line:#d8dde3;--bg:#fff;--soft:#f5f7f9;
  --accent:#1f5fbf;--bad:#b3261e;--good:#1a6f3c;--warn:#8a5a00}
/* Dark comes from the OS preference, and from an explicit data-theme stamp.
   Both are needed: the chart tokens below honour data-theme, and if the base
   palette did not, an explicit theme would flip the charts while the page
   stayed light. */
@media (prefers-color-scheme:dark){
  :root:where(:not([data-theme="light"])){--ink:#e6e9ee;--dim:#9aa4b1;--line:#333a44;
  --bg:#14171b;--soft:#1c2026;--accent:#7aa8f0;--bad:#f2857c;--good:#7fd8a0;--warn:#e0b25c}}
:root[data-theme="dark"]{--ink:#e6e9ee;--dim:#9aa4b1;--line:#333a44;
  --bg:#14171b;--soft:#1c2026;--accent:#7aa8f0;--bad:#f2857c;--good:#7fd8a0;--warn:#e0b25c}

/* Dark-mode solid buttons take dark text, not white — the fills are light
   there. Both scopes named so the theme toggle wins in either direction. */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) button.primary{color:#14171b}
}
:root[data-theme="dark"] button.primary{color:#14171b}
*{box-sizing:border-box}
@font-face{
  font-family:"Alegreya Sans"; font-style:normal; font-weight:400;
  font-display:swap;
  src:url("fonts/alegreya-sans-400-latin.woff2") format("woff2");
}
@font-face{
  font-family:"Alegreya Sans"; font-style:normal; font-weight:400;
  font-display:swap;
  src:url("fonts/alegreya-sans-400-ext.woff2") format("woff2");
}
@font-face{
  font-family:"Alegreya Sans"; font-style:normal; font-weight:500;
  font-display:swap;
  src:url("fonts/alegreya-sans-500-latin.woff2") format("woff2");
}
@font-face{
  font-family:"Alegreya Sans"; font-style:normal; font-weight:500;
  font-display:swap;
  src:url("fonts/alegreya-sans-500-ext.woff2") format("woff2");
}
@font-face{
  font-family:"Alegreya Sans"; font-style:normal; font-weight:700;
  font-display:swap;
  src:url("fonts/alegreya-sans-700-latin.woff2") format("woff2");
}
@font-face{
  font-family:"Alegreya Sans"; font-style:normal; font-weight:700;
  font-display:swap;
  src:url("fonts/alegreya-sans-700-ext.woff2") format("woff2");
}
@font-face{
  font-family:"Alegreya Sans"; font-style:italic; font-weight:400;
  font-display:swap;
  src:url("fonts/alegreya-sans-400-italic-latin.woff2") format("woff2");
}
@font-face{
  font-family:"Alegreya Sans"; font-style:italic; font-weight:400;
  font-display:swap;
  src:url("fonts/alegreya-sans-400-italic-ext.woff2") format("woff2");
}


body{margin:0;font:16px/1.55 "Alegreya Sans SC",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  color:var(--ink);background:var(--bg)}
main{max-width:56rem;margin:0 auto;padding:1.5rem 1rem 5rem}
/* 🔴 Hidden by clipping, never by `left:-9999px` — in a right-to-left page
   (Arabic, Hebrew) a box parked far to the left is scrollable space, and the
   whole page scrolled 9,000px sideways until a walk found it, 23 Oct 2026. */
.skip{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.skip:focus{width:auto;height:auto;overflow:visible;clip:auto;inset-inline-start:1rem;top:.5rem;position:fixed;background:var(--bg);padding:.5rem;z-index:9}
.top{display:flex;justify-content:space-between;align-items:center;gap:1rem;
  padding:.75rem 1rem;border-bottom:1px solid var(--line)}
.brand{font-weight:700;text-decoration:none;color:var(--ink)}
h1{font-size:1.6rem;margin:.4em 0} h2{font-size:1.2rem;margin:1.2em 0 .4em}
h3{font-size:1rem;margin:0}
a{color:var(--accent)}
.help{color:var(--dim);font-size:.875rem;margin:.25rem 0}
/* Statistics 3d: a figure that matters less, still readable (--dim is the
   help text's colour, measured with it) — a non-significant correlation, a
   small loading. Never colour alone: each also carries a mark or a word. */
.ns,.faint{color:var(--dim)}
.lede{color:var(--dim)}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
/* ⚠️ Stated rather than left to the browser's default: a later rule that
   gives an element a display value would otherwise un-hide it. */
[hidden]{display:none!important}
.panel{border:1px solid var(--line);border-radius:10px;padding:1rem;margin:1rem 0;background:var(--soft)}
.panel .head{display:flex;justify-content:space-between;align-items:flex-start;gap:1rem;flex-wrap:wrap}
.crumbs{font-size:.875rem;color:var(--dim);margin-bottom:.5rem}
.q{margin:.9rem 0}
.q>label,fieldset legend{display:block;font-weight:600;margin-bottom:.3rem}
/* 🔴 #B096 — `min-width:0`. A fieldset's default minimum width is its
   CONTENT, so a six-point matrix stretched its question past a phone's edge
   and the whole respondent's page scrolled sideways — the `.scroll-x` box
   inside it, meant to scroll on its own, never got the chance. Found by the
   release check measuring at 375px, 19 Oct 2026. */
fieldset{border:0;padding:0;margin:.9rem 0;min-width:0}
input,textarea,select{width:100%;padding:.5rem;border:1px solid var(--line);
  border-radius:6px;background:var(--bg);color:var(--ink);font:inherit}
input[type=radio],input[type=checkbox]{width:auto;min-width:1.1rem;min-height:1.1rem}
.option{display:flex;align-items:baseline;gap:.5rem;padding:.2rem 0}
.option label{font-weight:400}
.options.inline{display:flex;gap:1.25rem;flex-wrap:wrap}
.options.inline .option{flex-direction:column;align-items:center}
.q.check{display:flex;align-items:center;gap:.5rem}
.q.check label{font-weight:400;margin:0}
/* A time and the clock it is on, kept as one phrase (#B012). The box sizes
   to its own contents so the three letters sit against it rather than
   stranded at the far side of the panel. */
.when{display:inline-flex;align-items:center;gap:.45rem;max-width:100%}
.when input{width:auto}
.zone{font-weight:600;letter-spacing:.04em;white-space:nowrap}
/* Greys with the box it names — switched off is still a state worth
   reading, so it dims rather than disappearing. */
.zone.dim{opacity:.45}
button{font:inherit;padding:.5rem .9rem;border:1px solid var(--line);border-radius:6px;
  background:var(--bg);color:var(--ink);cursor:pointer}
button:hover{border-color:var(--accent)}
/* 🔴 The fill is light in dark mode, so white text on it measured 2.42:1 —
   well under the 4.5 minimum, and the main action button on the page. The
   text colour has to follow the theme, not be hard-coded white. */
button.primary{background:var(--accent);border-color:var(--accent);color:#fff}

/* Saved. Green from the same palette as the blue, so they belong together:
   light #1a6f3c on white text is 6.21:1, dark #7fd8a0 on dark ink 10.47:1.
   ⚠️ Never colour alone — app.js changes the label to "Saved ✓" as well,
   because green and blue are the same button to somebody who cannot tell
   them apart, and identical to a screen reader. */
button.primary.saved{background:var(--good);border-color:var(--good)}
/* ⚠️ `:not(.primary)` matters. Without it this rule's green text landed on
   the green fill above — equal specificity, later wins, so the saved button
   was green on green and unreadable. Caught by reading the computed colour
   in a real browser, not by looking at a screenshot. */
button.saved:not(.primary){border-color:var(--good);color:var(--good)}
button.danger{color:var(--bad);border-color:var(--bad)}
button.link{border:0;background:none;color:var(--accent);padding:0;text-decoration:underline}
button[disabled]{opacity:.45;cursor:default}
.actions{display:flex;gap:.6rem;flex-wrap:wrap;align-items:center;margin-top:1rem}
.actions form{display:inline}
.row-actions{display:flex;gap:.4rem;flex-wrap:wrap}
.row-actions form{display:flex;gap:.4rem}
.inline-form{display:flex;gap:.5rem;align-items:flex-end;flex-wrap:wrap;margin:1rem 0}
.inline-form label{font-weight:600;display:block}
.narrow{max-width:24rem}
.grid-3{display:grid;grid-template-columns:repeat(auto-fit,minmax(11rem,1fr));gap:.75rem}
.grid-4{display:grid;grid-template-columns:repeat(auto-fit,minmax(9rem,1fr));gap:.75rem}
.notice{padding:.6rem .8rem;border-radius:8px;border:1px solid var(--line);margin:.6rem 0}
.notice.ok{border-color:var(--good)} .notice.error{border-color:var(--bad)}
.notice.warn{border-color:var(--warn)}
.problem{color:var(--bad);font-size:.875rem;margin:.25rem 0}
.has-problem{border-left:3px solid var(--bad);padding-left:.75rem}
.req{color:var(--bad)}
.rule{background:var(--bg);border-left:3px solid var(--accent);padding:.4rem .7rem;
  font-size:.9rem;border-radius:0 6px 6px 0}
.badge{display:inline-block;font-size:.75rem;padding:.1rem .5rem;border-radius:999px;
  border:1px solid var(--line);text-transform:uppercase;letter-spacing:.03em}
.badge.open,.badge.live{border-color:var(--good);color:var(--good)}
.badge.draft{border-color:var(--warn);color:var(--warn)}
.badge.closed{border-color:var(--dim);color:var(--dim)}
/* 🔴 A pill sitting in a line of text sits on the BASELINE, so its bottom
   padding and the font's descender hang below that line and its visual
   centre lands low. Measured at +1.20px off the centre of the survey-link
   box, which is what the owner saw and reported (5 Oct 2026).
   ⚠️ Scoped to `.notice` deliberately — the same pill is used in the cards
   list and on the home page, and nobody asked for those to move.
   📌 `tests/browser/badge_alignment.py` measures it; do not adjust this by
   eye. */
.notice .badge{vertical-align:middle}
.cards{list-style:none;padding:0}
.cards li{border:1px solid var(--line);border-radius:8px;padding:.7rem;margin:.5rem 0;
  display:flex;gap:.75rem;align-items:center;flex-wrap:wrap}
table{border-collapse:collapse;width:100%}
th,td{text-align:left;padding:.4rem .6rem;border-bottom:1px solid var(--line);vertical-align:middle}
.matrix td{text-align:center}
.matrix th[scope=col]{text-align:center;font-size:.875rem}
/* 🔴 position:relative — hidden screen-reader words (.sr-only, absolutely
   positioned) inside a wide table were placed against the PAGE when no
   ancestor was positioned, escaping this box and making a phone's page
   scroll 400px sideways. Found walking the crosstab at 375px, 22 Oct 2026. */
.scroll-x{overflow-x:auto;position:relative}
/* R-200 — a crosstab cell holds several figures; each gets its own line, or
   a count of 7 above 20.0% reads as "720.0%". */
.crosstab .line{display:block;white-space:nowrap}
.crosstab td{font-variant-numeric:tabular-nums}
.crosstab .sig{font-weight:700}
/* Walked 22 Oct 2026: a nested table's long answer labels wrapped into
   towers one word wide. The table scrolls in its own box, so give each
   heading room instead. */
.crosstab thead th{min-width:7rem}
.results .bar{width:40%}
.results .bar span{display:block;height:.7rem;background:var(--accent);border-radius:3px;min-width:1px}
.answers{padding-left:1.1rem}
.answers li{margin:.3rem 0}
.take .q{margin:1.6rem 0}
code{background:var(--bg);padding:.1rem .35rem;border-radius:4px;word-break:break-all}
/* R-193. `break-all` above exists so a long survey link wraps instead of
   overflowing its box — but it also lets the browser break a SHORT example
   anywhere, and `?store_id=14` was splitting after the `?`, leaving the
   question mark stranded on the line above the word it belongs to. */
code.whole{word-break:normal;white-space:nowrap}
*:focus-visible{outline:3px solid var(--accent);outline-offset:2px}
.pager{margin:.5rem 0 1.25rem}
.pager label{display:block;font-size:.875rem;color:var(--dim);margin-bottom:.25rem}
.pager progress{width:100%;height:.5rem}
.block-title{margin-top:0;font-size:1.15rem}
.block{border:1px solid var(--line);border-radius:10px;padding:.75rem 1rem;margin:1rem 0}
.block>.head{display:flex;justify-content:space-between;gap:1rem;flex-wrap:wrap;align-items:flex-start}
.block-questions{margin-left:.25rem}
.responses td,.responses th{white-space:nowrap;max-width:22rem;overflow:hidden;text-overflow:ellipsis}
.narrow-table{max-width:32rem}
details.panel summary{cursor:pointer;font-weight:600}
dl.detail{margin:0}
dl.detail dt{font-weight:600;margin-top:1rem}
dl.detail dd{margin:.2rem 0 0 0;padding-left:0}
dl.detail dt.content-item{font-weight:400;font-style:italic;color:var(--dim)}
.filter-row{align-items:end;margin-bottom:.5rem}
.filter-row label{display:block;font-size:.875rem;color:var(--dim)}
/* #Q053 — several answers on one filter line: a column of ticks, the
   answers in the face for words a person wrote. */
.filter-picks{border:0;margin:0;padding:0;min-width:0}
.filter-row .filter-picks label.pick{display:flex;gap:.4rem;align-items:center;
  font-size:1rem;color:var(--ink)}
.filter-match{margin:.25rem 0 .75rem}
.filter-row + .filter-row{border-top:1px solid var(--line);padding-top:.5rem}
/* Statistics' Relate cards. Arrows carry words for a screen reader. */
.verdict{font-size:1.1rem;margin:.25rem 0}
.arrow{font-size:.8rem;letter-spacing:-.1em}
.arrow.up{color:var(--good, #1a7f37)}.arrow.down{color:var(--bad, #b42318)}
.test-details dl.facts{display:grid;grid-template-columns:max-content 1fr;gap:.25rem 1rem}
.filter-match label{display:block;font-size:.875rem;color:var(--dim)}

.take.narrow{max-width:30rem}

/* --- charts -------------------------------------------------------------
   Values from the dataviz skill's validated default palette, checked with
   its own validator rather than by eye. Dark is a *selected* set of steps
   for the dark surface, not an automatic flip.

   Light categorical slots 3 and 4 sit under 3:1 against the surface, so the
   relief rule applies — every chart here ships direct labels AND a table. */
.viz {
  --chart-ink:      var(--ink);
  --chart-muted:    var(--dim);
  --chart-axis:     var(--line);
  --chart-one:      #2a78d6;                /* single-series bars */
  --chart-seg-0:    #86b6ef;                /* ordinal ramp, light→dark */
  --chart-seg-1:    #5598e7;
  --chart-seg-2:    #2a78d6;
  --chart-seg-3:    #1c5cab;
  --chart-seg-4:    #104281;
  --chart-series-0: #2a78d6;                /* categorical, fixed order */
  --chart-series-1: #eb6834;
  --chart-series-2: #1baf7a;
  --chart-series-3: #eda100;
  --chart-series-4: #e87ba4;
  --chart-series-5: #008300;
  --chart-series-6: #4a3aa7;
  --chart-series-7: #e34948;
}
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) .viz {
    --chart-one:      #3987e5;
    --chart-seg-0:    #cde2fb;
    --chart-seg-1:    #86b6ef;
    --chart-seg-2:    #3987e5;
    --chart-seg-3:    #256abf;
    --chart-seg-4:    #184f95;
    --chart-series-0: #3987e5;
    --chart-series-1: #d95926;
    --chart-series-2: #199e70;
    --chart-series-3: #c98500;
    --chart-series-4: #d55181;
    --chart-series-5: #008300;
    --chart-series-6: #9085e9;
    --chart-series-7: #e66767;
  }
}
:root[data-theme="dark"] .viz {
  --chart-one:      #3987e5;
  --chart-seg-0:    #cde2fb;  --chart-seg-1:    #86b6ef;
  --chart-seg-2:    #3987e5;  --chart-seg-3:    #256abf;
  --chart-seg-4:    #184f95;
  --chart-series-0: #3987e5;  --chart-series-1: #d95926;
  --chart-series-2: #199e70;  --chart-series-3: #c98500;
  --chart-series-4: #d55181;  --chart-series-5: #008300;
  --chart-series-6: #9085e9;  --chart-series-7: #e66767;
}
/* 🔴 A count and its share are ONE fact, so they stay on one line. The
   column was narrow enough to wrap "1" onto one row and "(100.0%)" onto the
   next, which reads as two numbers and makes that row taller than its
   neighbours for no reason. */
.count-cell{white-space:nowrap}
.results td{white-space:nowrap}
.results th[scope="row"]{white-space:normal}

/* ⚠️ SVG defaults to overflow:hidden, so a label wider than the chart's box
   is CUT rather than allowed to spill. That is invisible while the web font
   is applied — Alegreya Sans SC is narrow — and appears the moment a wider
   fallback is painted instead, which is what happens when Chrome repaints an
   unfocused window. The label came back on refocus, which is the tell.
   🔴 Two fixes, because either alone leaves the other cause live: pin the
   family so the text cannot be measured in one font and painted in another,
   and let it overflow rather than clip if it ever is. */
.chart{width:100%;height:auto;max-width:40rem;display:block;margin:.5rem 0;
  overflow:visible}
.chart text{font-family:"Alegreya Sans SC",-apple-system,BlinkMacSystemFont,
  "Segoe UI",Roboto,sans-serif}
.chart-label{fill:var(--chart-ink);font-size:13px}
.chart-value{fill:var(--chart-muted);font-size:12px}
.chart-axis{stroke:var(--chart-axis);stroke-width:1}
.chart-bar path,.chart-bar rect{fill:var(--chart-one)}
.chart-seg-0 path,.chart-seg-0 rect{fill:var(--chart-seg-0)}
.chart-seg-1 path,.chart-seg-1 rect{fill:var(--chart-seg-1)}
.chart-seg-2 path,.chart-seg-2 rect{fill:var(--chart-seg-2)}
.chart-seg-3 path,.chart-seg-3 rect{fill:var(--chart-seg-3)}
.chart-seg-4 path,.chart-seg-4 rect{fill:var(--chart-seg-4)}
.chart-series-0 path,.chart-series-0 rect{fill:var(--chart-series-0)}
.chart-series-1 path,.chart-series-1 rect{fill:var(--chart-series-1)}
.chart-series-2 path,.chart-series-2 rect{fill:var(--chart-series-2)}
.chart-series-3 path,.chart-series-3 rect{fill:var(--chart-series-3)}
.chart-series-4 path,.chart-series-4 rect{fill:var(--chart-series-4)}
.chart-series-5 path,.chart-series-5 rect{fill:var(--chart-series-5)}
.chart-series-6 path,.chart-series-6 rect{fill:var(--chart-series-6)}
.chart-series-7 path,.chart-series-7 rect{fill:var(--chart-series-7)}
/* Identity is never colour alone: a legend is present for every multi-series
   chart, and each key carries its label. */
.legend{display:flex;flex-wrap:wrap;gap:.75rem;margin:.4rem 0;font-size:.875rem}
.legend span{display:inline-flex;align-items:center;gap:.35rem}
.legend i{width:.75rem;height:.75rem;border-radius:3px;display:inline-block}
.stat-row{display:flex;flex-wrap:wrap;gap:1.25rem;margin:.5rem 0}
.stat{min-width:5rem}
.stat b{display:block;font-size:1.25rem;font-weight:600}
.stat span{color:var(--dim);font-size:.8rem}
.small-group{border-left:3px solid var(--warn);padding-left:.6rem}

/* --- print ---------------------------------------------------------------
   "Save as PDF" is the browser's own Print command. No renderer on the
   server, nothing to install, and it works on the shared results page — so
   the privacy rules that page enforces come along unchanged.

   🔴 Colours are forced back to light. A reader in dark mode would otherwise
   print white text on white paper and get blank sheets. The dark rules above
   include `:root[data-theme="dark"]`, which out-specifies a plain `:root`,
   so every scope has to be named here to win.
   🔴 Controls are hidden — and the share panel especially, because it lists
   access codes in plain text and those must not end up on paper. */
/* A trial or subscription warning, above the page rather than inside it —
   it is about the whole account, not about whatever is on screen. */
.banner{margin:0;padding:.55rem 1rem;border-bottom:1px solid var(--line);
  background:var(--soft);font-size:.95rem}
.banner.warn{border-bottom-color:var(--warn)}
/* 🔴 Centred only where it is asked for (`.centered`), not on every banner.
   The owner wanted the one-line "Click Billing to subscribe." centered; the
   trial countdown beside it is a longer sentence that reads better ranged
   left, and centring both would have been a guess. */
.banner.centered{text-align:center}
/* ⚠️ NOT on a centered banner. The margin exists to separate a trailing
   "Billing" link from the sentence before it, and inside a centered one-line
   banner the link sits mid-sentence, where an extra 0.4rem reads as the
   double space the owner just had removed. */
.banner a{margin-left:.4rem}
.banner.centered a{margin-left:0}

@media print {
  :root, :root[data-theme="dark"], :root[data-theme="light"] {
    --ink:#111; --dim:#555; --line:#bbb; --bg:#fff; --soft:#fff;
    --accent:#1a1a1a; --bad:#000; --good:#000; --warn:#000;
  }
  .viz, :root[data-theme="dark"] .viz {
    --chart-one:#2a78d6;
    --chart-seg-0:#86b6ef; --chart-seg-1:#5598e7; --chart-seg-2:#2a78d6;
    --chart-seg-3:#1c5cab; --chart-seg-4:#104281;
    --chart-series-0:#2a78d6; --chart-series-1:#eb6834; --chart-series-2:#1baf7a;
    --chart-series-3:#eda100; --chart-series-4:#e87ba4; --chart-series-5:#008300;
    --chart-series-6:#4a3aa7; --chart-series-7:#e34948;
  }
  @page { margin: 16mm; }
  body { background:#fff; font-size: 11pt }
  main { max-width:none; padding:0 }
  .banner { display:none }

  /* Anything that only makes sense on a screen. */
  .top, .crumbs, .flashes, .no-print,
  form, details, button, .actions, .pager { display:none !important }

  /* 🔴 ...except the survey itself, which IS a form.
     The rule above is right for the filter form on a results page and was
     catastrophic here: every question on a survey page lives inside this one
     element, so printing a survey produced a title and nothing else.
     ⚠️ MEASURED with Playwright emulating print media, 2 Oct 2026 — a survey
     page printed to 79 readable characters against the results page's 1,811.
     📌 The controls are deliberately left visible: a radio button prints as an
     empty circle and a text box as a line, which is exactly what somebody
     wants on a paper questionnaire. Only the submit buttons go, and they go
     via `.actions` above. */
  form.questionnaire { display:block !important }

  .print-only { display:block !important }

  /* A question and its chart must not be split across a page turn. */
  .panel, section.panel, table, .stat-row { break-inside: avoid; page-break-inside: avoid }
  h1, h2 { break-after: avoid; page-break-after: avoid }

  .panel { border:0; border-top:1px solid var(--line); border-radius:0;
           padding:.5rem 0; margin:.75rem 0 }
  .chart { max-width:100% }
  .rule { border-left:3px solid #666; background:none }
  .notice { border:1px solid #999 }
  a { color:inherit; text-decoration:none }
}

.print-only { display:none }
.print-head { margin-bottom:1rem }
.print-head h1 { margin:0 0 .2rem }
.print-head p { margin:0; color:var(--dim); font-size:.9rem }


/* ============================================================
   THE PAIRING
   The site speaks in small caps. Anything a PERSON wrote does not.

   🔴 Why it is a real distinction and not decoration: capitals cost word
   shape — the pattern of ascenders and descenders that lets somebody
   recognise a word without spelling it out. That is a fair trade for a
   label read a hundred times and a poor one for a sentence written once.

   ⚠️ These rules must come after the `font:inherit` on inputs and buttons
   above. `font` is a shorthand, so it resets font-family; an earlier version
   of this block sat higher in the file and silently lost.
   ============================================================ */

/* -- the customer's and the respondent's own words -------------------- */
input, textarea, .typed,
.take,                       /* the respondent's page is almost all content */
.lede,                       /* a survey's description */
.block-title,                /* a page heading the customer wrote */
.take h1,                    /* the survey's title */
.take legend,                /* the question itself */
.take .options label,        /* the answer choices */
.take fieldset .help,        /* the customer's guidance under a question */
.question legend + .help,    /* and its help text there */
/* 🔴 The home page's sentences. The same rule, applied honestly: small caps
   are for a label read a hundred times, not a paragraph read once. The
   headings, buttons and badges around them stay SC, because those ARE the
   product's furniture. docs/fonts.md. */
.home .prose
{
  font-family:"Alegreya Sans","Alegreya Sans SC",-apple-system,
    BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
}

/* -- but the product's own furniture, even inside those pages --------- */
.take .pager, .take .pager *,
.take button, .take .notice, .take .problem, .take .req,
.take progress, .take .sr-only,
/* ⚠️ An explicit escape hatch for our words sitting inside a page of
   theirs. Add `ours` to the class list rather than growing this selector
   every time. */
.ours, .ours *
{
  font-family:"Alegreya Sans SC",-apple-system,BlinkMacSystemFont,
    "Segoe UI",Roboto,sans-serif;
}


/* The masthead. The brand is the size of a survey's title, and the links sit
   beside it on the left rather than being pushed to the far edge. */
.top{justify-content:flex-start;gap:1.5rem}

.brand{font-size:1.5rem;line-height:1.2}


/* Account, as a <details> menu — see base.html for why it is not scripted. */
.menu{position:relative}
.menu>summary{cursor:pointer;list-style:none;color:var(--accent);
  text-decoration:underline}
.menu>summary::-webkit-details-marker{display:none}
.menu>summary::after{content:" ▾";text-decoration:none}
.menu-items{position:absolute;right:0;top:calc(100% + .4rem);z-index:20;
  min-width:11rem;padding:.4rem;background:var(--bg);
  border:1px solid var(--line);border-radius:8px;
  box-shadow:0 6px 20px rgba(0,0,0,.12)}
.menu-items a,.menu-items button{display:block;width:100%;text-align:left;
  padding:.4rem .6rem;border:0;background:none}
.menu-items a:hover,.menu-items button:hover{background:var(--soft)}
.menu-items form{margin:0}


/* The survey at a glance: two columns, four rows each.
   Left says what the survey IS; right holds the numbers, values aligned
   right so a reader can run down the column instead of hunting. */
.summary-grid{display:grid;grid-template-columns:1fr 1fr;gap:.75rem 2.5rem}
@media (max-width:40rem){.summary-grid{grid-template-columns:1fr}}

.summary-col{margin:0;display:grid;gap:.35rem;align-content:start}
.summary-col .fact{display:flex;gap:.6rem;align-items:baseline}
.summary-col dt{font-size:1rem;color:var(--dim);white-space:nowrap}
.summary-col dd{margin:0;font-size:1rem}

/* The name is the page heading as well as a field, so it is larger — but it
   must not push the rows beside it out of line. */
.summary-col dd h1{font-size:1.15rem;margin:0;line-height:1.2;
  font-weight:700}

/* The numbers column: label left, value hard right. */
.summary-col.numbers .fact{justify-content:space-between}
.summary-col.numbers dd{text-align:right;font-variant-numeric:tabular-nums}

/* Results and Responses share the last row. */
.summary-col .fact.links{gap:1.5rem}
.summary-col .fact.links dd{margin-top:.2rem}
.summary-col .help{font-size:.85rem}

/* The top navigation, in one place.
   ⚠️ It used to be three separate .topnav rules scattered through this file,
   one of which set `margin-right:auto`. Adding `margin-left:auto` elsewhere
   to push it right would have centered it instead — two auto margins share
   the space rather than picking a side. */
.topnav{display:flex;align-items:center;gap:1.25rem;
  margin-left:auto;margin-right:0}

/* The "Other — please specify" box sits under its option, indented to show
   it belongs to it. */
.option.other-box{margin-left:1.6rem;margin-top:-.2rem}
.option.other-box input{max-width:26rem}

/* A picture in a content block. Never wider than the page, and never
   stretched — a survey should not distort somebody's diagram. */
.content-image{max-width:100%;height:auto;border-radius:8px;margin:.6rem 0}

/* The "who can answer" grid. Ordinary markup, so it wears the site font —
   which the list a <select> drops open never can. */
.access-grid table{margin:.4rem 0}
.access-grid th{font-size:.9rem;white-space:nowrap}
.access-grid td{vertical-align:baseline}
.access-grid td label{display:block;font-weight:400;cursor:pointer}
.access-grid input[type=radio]{margin-top:.2rem}

/* NPS. 🔴 The score is large because it is what somebody came for — but the
   denominator sits beside it, never omitted. */
.nps-headline{display:flex;align-items:baseline;gap:.7rem;margin:.8rem 0}
.nps-score{font-size:2.4rem;font-variant-numeric:tabular-nums;line-height:1}

/* Ranking — a menu per item. 📌 The label and its menu stay on one line so
   the relationship is obvious; they wrap together on a narrow screen. */
.rank-row{display:flex;align-items:center;gap:.8rem;padding:.3rem 0;
  flex-wrap:wrap}
.rank-row label{font-weight:400;flex:1 1 12rem}
.rank-row select{width:auto;min-width:4.5rem}

/* Several boxes at once. 📌 Stacked, not side by side — a label above its
   box is the layout every form guide agrees on, and it survives a narrow
   screen without reflowing into confusion. */
.formfield{margin:.6rem 0}
.formfield label{display:block;font-weight:400;margin-bottom:.2rem}

/* R-1172 — constant sum. 📌 Label and box on one line, the boxes in a column
   so the numbers line up for adding; on a narrow screen the label wraps
   above. The unit sits against its box. */
/* ⚠️ Capped, or on a wide screen the box drifts a page-width away from
   its label and the pair stop reading as one. */
.sumfields{max-width:30rem}
.sumfield{display:flex;flex-wrap:wrap;align-items:center;gap:.25rem 1rem;
  margin:.45rem 0}
.sumfield label{flex:1 1 12rem;font-weight:400}
.sum-box{display:inline-flex;align-items:center;gap:.3rem}
.sum-box input{width:6rem;text-align:right}
.sum-running{font-weight:600;margin:.6rem 0 0}
/* Words carry the state; the colour only repeats it. */
.sum-running.sum-matched{color:var(--good)}
.sum-running.sum-off{color:var(--bad)}

/* Slider. 📌 The number box is deliberately narrow and beside the track, so
   it reads as one control rather than two questions. */
.slider-row{display:flex;align-items:center;gap:1rem}
.slider-row .slider{flex:1 1 auto;width:auto;padding:0}
/* 🔴 A real box now, not a readout (1 Oct 2026). It has to LOOK typeable or
   nobody tries, which was the whole complaint: a bare number at the far right
   reads as output, so people drag and give up on getting an exact figure.
   ⚠️ It arrives disabled from the server and app.js enables it — see
   take.html for why. The disabled state deliberately still shows its value. */
.slider-row .slider-value{flex:0 0 6rem;width:6rem;text-align:center;
  padding:.4rem .3rem}
.slider-row .slider-value:disabled{opacity:.55;cursor:not-allowed}

/* 🔴 The two ends of a scale, sitting over the two ends of the scale.
   They were one short line at the far left — "Not at all → Extremely"
   floating above eleven numbers and belonging to none of them.
   📌 space-between puts each label against its own end of the row, which is
   the same width as the options beneath. ⚠️ Not mathematically centered on the
   first and last number: "Not at all likely" is five times wider than the "0"
   it describes, so centring it on that digit would hang it off the left edge
   of the question. Aligned to the ends is what every well-drawn scale does. */
/* 🔴 Only as wide as the numbers it labels. Left full-width, "Extremely
   likely" sat far to the right of the 10 it describes — the labels stretched
   to the question, not to the scale. */
.scale-block{width:fit-content;max-width:100%}
/* ✅ The owner's rule, 19 Oct 2026 — the first circle centred under the
   left label, the right label centred over the last circle. Measured and
   applied by `alignScaleEnds` in app.js; without scripting the rule above
   (each label against its own end) is what shows. */
.scale-block .scale-ends{box-sizing:border-box;max-width:none}
.scale-ends{display:flex;align-items:baseline;gap:.75rem;
  justify-content:space-between;margin:.25rem 0 .5rem}
.scale-ends>span:first-child{text-align:left}
.scale-ends>span:last-child{text-align:right}
/* The arrow floats in the middle of whatever gap is left, equidistant from
   both labels, rather than sitting against one of them. */
.scale-ends .arrow{flex:1 1 auto;text-align:center;opacity:.6}

/* 🔴 Buttons line up with the words above them. `.cta-row` centres on the
   home page, where everything is centered; on a left-aligned page that left
   the two buttons floating in the middle of the column with the sentence
   they belong to starting at the margin. */
.cta-row.left{justify-content:flex-start}

/* Options editor. 📌 The new-option row puts its button beside the box, so
   "type here, press that" reads as one action rather than two fields. */
.option-row{margin:.35rem 0}
/* R-050 — a recode number sits beside its answer, sized for a number. */
.recode-row{display:flex;align-items:center;gap:.75rem;margin:.35rem 0}
.recode-row label{flex:0 1 18rem;min-width:0;margin:0}
.recode-row input{width:6rem;flex:none}
.new-option-row{display:flex;gap:.6rem;align-items:center}
.new-option-row input{flex:1 1 auto}
.new-option-row .add-option{flex:0 0 auto;white-space:nowrap}
.bulk{margin:.6rem 0}

/* 🔴 `R-076` — the rule on ONE choice, folded under the choice it governs.
   Indented against a line so it reads as belonging to the box above it rather
   than to the next one, the same device `.other-detail` uses. ⚠️ The summary
   is a SENTENCE, not a label, so it is sized down: it is a thing to read when
   you want it, not a heading competing with the option boxes. 📌 `#B034` says
   this page is already too long, which is why the whole control collapses to
   one line per choice. */
.item-rule{margin:.1rem 0 .5rem 1.1rem;border-left:3px solid var(--line);
  padding-left:.8rem}
.item-rule > summary{font-size:.85rem}
.item-rule .grid-3{margin:.4rem 0}

/* 🔴 Every <details> on the site, not just this one.
   A <summary> is clickable and looks like a heading. Nothing said otherwise
   — no pointer, no colour, no hover — so nobody knew any of them opened.
   Reported as "doesn't give any indication it's clickable", and it was true
   of every fold in the product, not only the one that was noticed.
   ⚠️ Scoped away from the two that carry their own look. */
details:not(.menu):not(.danger-fold) > summary{
  cursor:pointer;color:var(--accent);display:inline-block;padding:.15rem 0}
details:not(.menu):not(.danger-fold) > summary:hover{text-decoration:underline}
.other-detail{border-left:3px solid var(--line);padding-left:.8rem}

/* Deleting a survey.
   ⚠️ The first version was small red text trailing the end of a row, and the
   owner could not find it at all. "Never the thing your eye lands on" is not
   the same as invisible — a control nobody can locate is not a cautious
   control, it is a missing feature. So: a real bordered control, pushed to
   the right of the row where actions belong, still folded so the dangerous
   part takes a deliberate click. */
.cards li{display:flex;align-items:center;gap:.7rem;flex-wrap:wrap}
/* ⚠️ Kept for any card that still puts the fold directly in the <li>. On the
   surveys list it now lives inside .row-bottom, which does its own pushing —
   see that rule. A selector that matches nothing is not a bug, but a TEST
   pinning one is, so the test asserts the rule that actually applies. */
.cards li > .danger-fold{margin-left:auto}
.danger-fold summary{color:var(--bad);font-size:.85rem;cursor:pointer;
  border:1px solid var(--line);border-radius:6px;padding:.2rem .6rem;
  list-style:none;white-space:nowrap}
.danger-fold summary::-webkit-details-marker{display:none}
.danger-fold summary:hover{border-color:var(--bad)}
.danger-fold[open] summary{border-color:var(--bad);font-weight:600}
/* The form drops out of the flex row and takes the full width beneath it. */
.danger-fold[open]{flex:1 1 100%}
.danger-fold form{border:1px solid var(--bad);border-radius:8px;padding:.8rem;
  margin-top:.5rem;max-width:34rem}
button.danger{background:var(--bad);border-color:var(--bad);color:#fff}
:root[data-theme="dark"] button.danger{color:#14171b}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) button.danger{color:#14171b}}

/* #B033 — what a survey row offers. The ordinary actions read as a line of
   links; Delete keeps its own fold below and its own red, so the dangerous
   thing is still the one that looks dangerous without being the only one
   that looks like anything. */
/* ⚠️ The row is a wrapping flex line, so anything added to it becomes a
   flex item and lands wherever there happens to be room. These two are told
   to take a whole line each, which is what makes the row read as three
   deliberate lines — what it is, what you can do, where the link is —
   rather than as things that spilled. */
/* 🔴 The card is itself a flex row, so a child that should occupy a whole
   line has to say so. ⚠️ `.row-bottom` was added without this and shrank to
   fit its contents — which left `margin-left:auto` inside it nothing to push
   against, so Delete trailed Copy link instead of sitting at the far right.
   📌 `.link-line` is no longer a direct child (it lives inside `.row-bottom`),
   but the selector is harmless and other cards may still use it. */
.cards li > .row-actions, .cards li > .link-line,
.cards li > .row-bottom{flex:1 1 100%}
.row-actions{display:flex;gap:.9rem;flex-wrap:wrap;margin:.35rem 0 0;font-size:.95rem}
/* Delete goes last rather than sitting at the end of the title line. It is
   still red and still unmistakable; it is no longer the first thing the eye
   lands on in a row somebody opened to read their results. */
.cards li > .danger-fold{order:99}
.row-bottom > .danger-fold{order:99}
.cards .when{opacity:.85}
/* 🔴 The link, Copy and Delete share one row, Delete pushed to the far right
   (the owner's layout, 29 Sep 2026). Delete used to take a line of its own
   below the link, spending a whole row on every card.
   ⚠️ The OPEN danger fold takes the full width instead of staying a narrow
   column squeezed against the right edge — closed it is a small button,
   opened it is a panel. */
.row-bottom{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;
  margin:.4rem 0 0}
.row-bottom > .danger-fold{margin-left:auto}
.row-bottom > .danger-fold[open]{flex:1 0 100%;margin-left:0}
/* The link and its Copy button sit together at the left of that row.
   ⚠️ The gap supplies the spacing, so the button's own margin is cancelled —
   otherwise the two add up and the button drifts away from its box. */
.link-line{margin:0;display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}
.link-line .copy-link{margin-left:0}
/* The button that files a survey without scripting. Removed by app.js once
   the dropdown has been wired to act the moment you pick. */
.assign-go{font-size:.85rem;padding:.15rem .5rem}
/* 🔴 As wide as the link, never wider. The width comes from the `size`
   attribute, which the template sets to the link's own length.
   ⚠️ **`width:auto` has to be said out loud.** Line 136 sets
   `input,textarea,select{width:100%}` for every field in the product, and a
   `size` attribute loses to any CSS width. Simply *deleting* the width from
   this rule does nothing at all — the global one takes over and the box is
   full-width again, which is how it looked before and after the first attempt
   at this fix. 📌 Found by screenshotting the page; the test written
   alongside the broken fix asserted "no width here" and passed happily.
   `max-width` still caps it at the column, so a long link on a narrow screen
   shrinks instead of overflowing. */
.survey-link{width:auto;max-width:100%;font-family:ui-monospace,SFMono-Regular,
  Menlo,monospace;font-size:.85rem;padding:.3rem .45rem;
  background:var(--soft);border:1px solid var(--line);border-radius:6px}
.primary-link{font-weight:600}

/* The Copy button beside a survey link. Small, quiet, and the same green as
   a saved Save button when it has just worked — one vocabulary for "done". */
.copy-link{font-size:.8rem;padding:.2rem .6rem;margin-left:.5rem;
  vertical-align:middle}
.copy-link.saved{background:var(--good);border-color:var(--good);color:#fff}

/* Ranking: draggable bars, best at the top (26 Sep 2026, the owner's
   decision and the way Qualtrics does it). 🔴 The order of the list IS the
   answer — the number on the left is a readout, not a control. */
ol.ranking{list-style:none;margin:.6rem 0;padding:0;max-width:34rem}
.rank-bar{display:flex;align-items:center;gap:.7rem;margin:.35rem 0;
  padding:.6rem .8rem;border:1px solid var(--line);border-radius:8px;
  background:var(--bg);cursor:grab}
.rank-bar:active{cursor:grabbing}
.rank-bar.is-dragging{opacity:.5;border-style:dashed}
.rank-number{flex:0 0 1.6rem;text-align:center;font-weight:700;
  color:var(--dim)}
.rank-text{flex:1}
/* ⚠️ A grab handle drawn in CSS rather than an image, so it inherits the
   theme and needs no file. Decorative, so it is hidden from readers. */
.rank-bar::after{content:"⠿";color:var(--dim);font-size:1.1rem}

/* R-200 — the crosstab's two boxes, added by app.js (setUpCrosstabPicker).
   Drawn like the ranking bars, because they are the same gesture: drag to
   order, arrows on the keyboard. */
.xt-boxes{display:grid;grid-template-columns:repeat(auto-fit,minmax(14rem,1fr));
  gap:.75rem;margin:0 0 1rem}
.xt-box{border:1px dashed var(--line);border-radius:8px;padding:.6rem;
  background:var(--bg);min-width:0}
.xt-box.is-over{border-style:solid;border-color:var(--warn)}
.xt-title{font-weight:600;margin:0 0 .3rem}
.xt-list{list-style:none;margin:0;padding:0}
.xt-item{display:flex;align-items:center;justify-content:space-between;
  gap:.5rem;margin:.3rem 0;padding:.45rem .7rem;border:1px solid var(--line);
  border-radius:8px;background:var(--soft);cursor:grab}
.xt-item:active{cursor:grabbing}
.xt-item.is-dragging{opacity:.5;border-style:dashed}
.xt-text{flex:1;min-width:0;overflow-wrap:anywhere}
.xt-remove{font-size:1.2rem;line-height:1}
.xt-draggable{cursor:grab}

/* A date box switched off by "No end date". ⚠️ It has to LOOK inert, or it
   reads as a field somebody forgot to fill in — and in Safari the browser
   draws a grey sample date inside an empty one, which looks like a value. */
input:disabled{background:var(--soft);color:var(--dim);cursor:not-allowed}

/* Create on the far left, Folders on the far right, level with each other —
   the two things people come to the surveys page to reach. */
.list-controls{display:flex;justify-content:space-between;align-items:center;
  gap:1rem;flex-wrap:wrap;margin:.6rem 0}
.list-controls form{margin:0}
/* The Folders menu opens leftwards: it sits at the right edge, so a menu
   anchored on the left would hang off the page. */
.folders-menu{position:relative}
.folders-menu > .menu-items{right:0;left:auto}
.folders-menu .menu-items form{display:block;padding:.4rem .2rem}
.folders-menu .menu-items label{display:block;font-size:.85rem;
  margin:0 0 .25rem}
.folders-menu .menu-items input{margin-bottom:.4rem}
.folders-menu .menu-items hr{border:0;border-top:1px solid var(--line);
  margin:.4rem 0}

.survey-search{display:flex;gap:.5rem;align-items:center;flex-wrap:wrap;
  margin:.6rem 0 1rem}
.survey-search input{width:auto;min-width:16rem;max-width:100%}

/* The folder a survey is in, beside its version — quiet, like the date.
   ⚠️ No decorative glyph: the site face is Alegreya Sans SC, which has no
   folder character, so it rendered as nothing here and would be a tofu box on
   another machine. The word is the label. */
.folder-name{opacity:.85}

/* Filing sits with the row's other actions rather than below them. */
/* Sits inside the row's actions, immediately after Preview, so filing reads
   as one more thing you can do with this survey rather than a separate step. */
.assign-folder{display:flex;gap:.4rem;align-items:center;margin:0}
.assign-folder select{width:auto;max-width:11rem;font-size:.85rem;
  padding:.15rem .3rem}
.assign-folder button{font-size:.85rem;padding:.15rem .5rem}

/* The account name in the masthead, beside the word Account. Regular weight
   would let it blur into the label; it is the part that identifies the page. */
.account-name{font-weight:600}

/* ===================================================================== *
 * THE PUBLIC HOME PAGE                                                  *
 *                                                                       *
 * 🔴 Everything here is scoped under `.home` so it cannot reach the      *
 * product's own pages. The page uses the SAME tokens as everything else  *
 * (--ink, --bg, --soft, --line, --accent), so it follows light and dark  *
 * for free rather than carrying its own palette.                        *
 *                                                                       *
 * ⚠️ `--on-accent` exists because the accent inverts between schemes.    *
 * White on #1f5fbf is about 6.5:1 in light; white on the dark scheme's   *
 * #7aa8f0 would be roughly 2:1 and unreadable. Dark text on it is about  *
 * 7:1. So the foreground has to flip with the background, not be fixed. *
 * ===================================================================== */

/* ⚠️ The token is declared on BOTH, because `.cta` escaped `.home` on
   1 Oct 2026 — the demo thank-you page needed the same two buttons. A
   `.cta.primary` outside `.home` would otherwise inherit no --on-accent and
   fall back to transparent text on a solid fill. */
.home,.cta-row{--on-accent:#fff}
.home{max-width:62rem; margin:0 auto}
@media (prefers-color-scheme:dark){
  .home:where(:not([data-theme="light"]) *),
  .cta-row:where(:not([data-theme="light"]) *){--on-accent:#101317}}
:root[data-theme="dark"] .home,
:root[data-theme="dark"] .cta-row{--on-accent:#101317}
:root[data-theme="light"] .home,
:root[data-theme="light"] .cta-row{--on-accent:#fff}

/* -- hero ------------------------------------------------------------- */
.home .hero{text-align:center;padding:2.5rem 0 1rem}
/* 📌 40ch, not 34. The reason was a longer headline — it broke across four
   lines at the narrower measure and left "RECEIVE as" straddling a line end,
   putting the one capitalised word in the weakest position on the page. That
   headline is gone (5 Oct 2026) and the present one is short enough that the
   measure no longer bites; 40ch is kept because it is the width the sentence
   is balanced at, not because it is still rescuing anything.
   `text-wrap:balance` evens the lines; it cannot add room that is not there. */
.home .hero-head{font-size:clamp(1.7rem,4.2vw,2.75rem);line-height:1.15;
  margin:0 auto .9rem;max-width:40ch;text-wrap:balance}
.home .hero-sub{font-size:1.1rem;color:var(--dim);max-width:52ch;
  margin:0 auto 2rem}

/* The price, as the one thing the eye lands on. */
.home .price-card{border:1px solid var(--line);border-radius:14px;
  background:var(--soft);padding:1.5rem;margin:0 auto 1.75rem;
  display:flex;gap:1.75rem;align-items:center;text-align:left;
  max-width:46rem;flex-wrap:wrap;justify-content:center}
.home .price{display:flex;align-items:baseline;gap:.5rem;margin:0;
  flex:0 0 auto}
.home .price .amount{font-size:3.4rem;font-weight:700;line-height:1;
  color:var(--accent)}
.home .price .per{font-size:.9rem;color:var(--dim);line-height:1.25}
.home .price-points{list-style:none;margin:0;padding:0;flex:1 1 20rem;
  display:grid;gap:.6rem}
.home .price-points li{padding-left:1.5rem;position:relative;font-size:.97rem}
/* A tick drawn in CSS — no icon font, no SVG request, and it inherits colour. */
.home .price-points li::before{content:"";position:absolute;left:0;top:.42em;
  width:.5rem;height:.28rem;border-left:2.5px solid var(--good);
  border-bottom:2.5px solid var(--good);transform:rotate(-45deg)}

/* -- calls to action -------------------------------------------------- */
.cta-row{display:flex;gap:.75rem;justify-content:center;flex-wrap:wrap;
  margin:0 0 1.5rem}
.cta{display:inline-block;padding:.72rem 1.5rem;border-radius:8px;
  text-decoration:none;font-weight:600;font-size:1.02rem;
  border:2px solid transparent;transition:transform .08s ease-out}
.cta.primary{background:var(--accent);color:var(--on-accent);
  border-color:var(--accent)}
.cta.secondary{color:var(--accent);border-color:var(--line)}
.cta:hover{transform:translateY(-1px)}
.cta.secondary:hover{border-color:var(--accent)}
/* 🔴 A visible focus ring, not the removed one. Keyboard users land here. */
.cta:focus-visible{outline:3px solid var(--accent);outline-offset:3px}
@media (prefers-reduced-motion:reduce){.cta{transition:none}
  .cta:hover{transform:none}}

/* 📌 The trust panel and the separate demo call-to-action were removed from
   the home page on 1 Oct 2026 (their content moved into the price-card
   bullets), and their rules went with them. Dead CSS is cheap to keep and
   expensive to trust — a later session reads a selector, assumes something
   uses it, and designs around a thing that is not there. */

/* -- bands ------------------------------------------------------------ */
.home .band{padding:2.75rem 0;border-top:1px solid var(--line)}
/* `alt` is a full-bleed tint, so alternating sections read as separate
   without drawing more lines. */
/* ⚠️ Its own margin must NOT stack on top of the previous band's bottom
   padding — that put about eight rems of nothing between two sections and
   read as the page having ended. A screenshot caught it; the rule looked
   reasonable on its own. */
.home .band.alt{background:var(--soft);border-radius:14px;
  padding:2.25rem 1.5rem;border-top:0;margin:0}
.home .band + .band.alt{margin-top:-.5rem}
.home .band h2{font-size:clamp(1.25rem,2.6vw,1.75rem);margin:0 0 .5rem;
  text-wrap:balance}
.home .section-lede{color:var(--dim);max-width:58ch;margin:0 0 1.5rem}
/* 📌 Breathing room between the table and the invitation beneath it (the
   owner, 5 Oct 2026). The paragraph used to sit above the table; moved below
   it, the default spacing left it looking like a stray last row. */
.home .section-lede.after-table{margin-top:2.25rem}
.home .count-note,.home .footnote,.home .provenance{font-size:.88rem;
  color:var(--dim);max-width:62ch}
.home .provenance{margin-top:1rem}

/* -- tables ----------------------------------------------------------- */
/* ⚠️ Wide content scrolls inside its own box. The page body must never
   scroll sideways — on a phone that hides the right-hand column of a
   comparison, which is the column that makes the point. */
.home .scroller{overflow-x:auto;border:1px solid var(--line);border-radius:10px;
  background:var(--bg)}
.home table{border-collapse:collapse;width:100%;min-width:34rem}
.home th,.home td{text-align:left;padding:.72rem .9rem;
  border-bottom:1px solid var(--line);vertical-align:top}
.home thead th{font-size:.78rem;letter-spacing:.07em;text-transform:uppercase;
  color:var(--dim);background:var(--soft);position:sticky;top:0}
.home tbody tr:last-child th,.home tbody tr:last-child td{border-bottom:0}
.home tbody th[scope="row"]{font-weight:600;white-space:nowrap}
.home .types tbody tr:nth-child(odd) th,
.home .types tbody tr:nth-child(odd) td{background:color-mix(in srgb,var(--soft) 55%,transparent)}
.home .compare .price-cell{white-space:nowrap;font-variant-numeric:tabular-nums}
.home .compare .tiny{display:block;font-size:.8rem;color:var(--dim);
  white-space:normal}
/* 🔴 Our own row marked, but with a border and weight rather than a loud
   fill — a comparison table that shouts about itself reads as advertising
   and stops being believed. */
.home .compare tr.us th,.home .compare tr.us td{
  background:color-mix(in srgb,var(--accent) 9%,transparent)}
.home .compare tr.us th[scope="row"]{box-shadow:inset 3px 0 0 var(--accent)}

/* -- feature lists ---------------------------------------------------- */
.home .feature-list{list-style:none;margin:0;padding:0;display:grid;
  gap:1rem;grid-template-columns:repeat(auto-fit,minmax(min(100%,22rem),1fr))}
.home .feature{border:1px solid var(--line);border-radius:10px;
  padding:1.1rem;background:var(--bg)}
.home .feature-name{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;
  font-weight:600;font-size:1.03rem;margin:0 0 .5rem}
.home .feature p.prose{margin:0 0 .6rem;font-size:.94rem}
.home .feature .elsewhere{margin:0;font-size:.88rem;color:var(--dim);
  border-top:1px solid var(--line);padding-top:.6rem}
.home .elsewhere .label{display:block;font-family:"Alegreya Sans SC",sans-serif;
  font-size:.72rem;letter-spacing:.08em;text-transform:uppercase;
  color:var(--dim);margin-bottom:.15rem}
/* Reuses the product's own `.badge` pill. The states are ours. */
.home .badge.yes{border-color:var(--good);color:var(--good)}
.home .badge.roadmap{border-color:var(--warn);color:var(--warn)}
.home .badge.no{border-color:var(--dim);color:var(--dim)}

/* -- closer ----------------------------------------------------------- */
.home .closer{text-align:center;padding:3rem 0 2.5rem;
  border-top:1px solid var(--line)}
.home .closer h2{margin-bottom:.6rem}
.home .closer .prose{color:var(--dim);max-width:48ch;margin:0 auto 1.6rem}

@media (max-width:40rem){
  .home .price-card{flex-direction:column;gap:1rem;align-items:flex-start}
  .home .price .amount{font-size:2.8rem}
  .home .band.alt{padding-inline:1rem;border-radius:10px}
  .cta{width:100%;text-align:center}
}

/* 🔴 The site footer — on every page, including the one a respondent sees.
   ⚠️ `no-print` on the printed copy of a results page: a sheet of paper
   already says what it is and when it was taken, and a support address at the
   bottom of somebody's board pack is noise. */
.site-foot{max-width:56rem;margin:0 auto;padding:1.5rem 1rem 2.5rem;
  border-top:1px solid var(--line);color:var(--dim);font-size:.85rem;
  display:flex;gap:.5rem 2rem;flex-wrap:wrap;justify-content:space-between}
.site-foot p{margin:0}
@media print{.site-foot{display:none}}

/* 🔴 #B077 — the "show each one to about the same number of people" tick sat
   flush beneath the list of PIN ticks, so it scanned as one more option to
   pin rather than a different kind of setting. Found by screenshotting the
   panel and reading it; no test could see it. */
.balance-check { border-top:1px solid var(--line); padding-top:.6rem; margin-top:.75rem }

/* The "Show password" checkbox — added by app.js beside every password box. */
.reveal{display:block;font-size:.875rem;margin:.3rem 0 .2rem;color:var(--dim)}
.reveal input{width:auto;margin-right:.3rem}

/* 🔴 Phone width — nothing may push the page sideways (16 Oct 2026).
   Measured at 375px, signed in: the page was 425px wide. Two causes.
   1. A flex item will not shrink below its content unless told to: the
      survey card's rows held the link box at its full `size`, 397px, so the
      `max-width:100%` on the box never had a narrower parent to obey.
   2. The masthead's links never wrapped, so the Account menu sat past the
      right edge. On a phone they wrap under the brand instead. */
.row-bottom,.link-line{min-width:0}
.link-line .survey-link{flex:0 1 auto;min-width:0}
/* The builder's "who can answer" grid is a real table of radios; on a phone
   it scrolls inside its own box. ⚠️ `min-width:0` is the half that matters:
   a FIELDSET's browser default is `min-width:min-content`, so without it the
   box grows to the table and there is nothing to scroll. */
.access-grid{overflow-x:auto;min-width:0}
@media (max-width:40rem){
  .top{flex-wrap:wrap;row-gap:.5rem}
  .topnav{flex-wrap:wrap;margin-left:0;gap:.5rem 1.25rem;min-width:0}
  /* The menus now sit at the LEFT, so they open rightwards — opening from
     their right edge would push a short account name's menu off-screen. */
  .topnav .menu-items{left:0;right:auto}
}

/* R-042 — the version history. View and Restore side by side. */
.history td.nb{display:flex;align-items:center;gap:.75rem}
.history form.inline{margin:0}

/* R-043 — the progress bar: "0%" and "100%" at its ends, the Qualtrics way. */
.pager .bar-row{display:flex;align-items:center;gap:.5rem}
.pager .bar-row progress{flex:1 1 auto}
.pager .bar-end,.pager .bar-name{font-size:.8rem;opacity:.8}
.pager .bar-name{margin:0 0 .2rem}

/* R-038 — a date box and a time box, side by side, each with its label. */
.when-row{display:flex;flex-wrap:wrap;gap:.5rem 1.25rem}
.when-part{display:flex;flex-direction:column;gap:.2rem}
.when-part input{width:auto}

/* R-053 — how a choice question's options are laid out (the owner's
   decision, 16 Oct 2026). Columns use CSS columns, which fill DOWN, so the
   order on screen is the order a screen reader follows. 🔴 On a phone every
   layout stacks into one column. */
.options.layout-horizontal{display:flex;flex-wrap:wrap;gap:.25rem 1.5rem}
.options.layout-cols-2{column-count:2;column-gap:1.5rem}
.options.layout-cols-3{column-count:3;column-gap:1.5rem}
.options.layout-cols-4{column-count:4;column-gap:1.5rem}
[class*="layout-cols-"] .option{break-inside:avoid}
/* The "Other" box stays with its option rather than heading a new column. */
[class*="layout-cols-"] .option.other-box{break-before:avoid-column}
@media (max-width:40rem){
  .options.layout-horizontal{display:block}
  .options[class*="layout-cols-"]{column-count:1}
}

/* #B090 — staging says so on every page. Black on amber: 11.5:1, and not a
   colour any theme uses, so it cannot be read as part of the customer's page. */
.staging-banner{background:#f4c430;color:#111;text-align:center;font-weight:500;
  padding:.35rem 1rem;letter-spacing:.04em}
@media print{.staging-banner{border-bottom:2px solid #111}}

/* ✅ The owner's decision, 19 Oct 2026: each choice on an email list's rows
   explained in plain words, above the table. */
.choices-key{display:grid;grid-template-columns:max-content 1fr;gap:.25rem .9rem;
  margin:.5rem 0 1rem}
.choices-key dt{margin:0}
.choices-key dd{margin:0}
@media (max-width:600px){.choices-key{grid-template-columns:1fr}
  .choices-key dd{margin-bottom:.5rem}}

/* #B034 — a question folds to one line: number and type, then its words.
   Open, the words are in the box below, so the line keeps only the type. */
details.q-fold > summary.q-line{display:flex;align-items:baseline;gap:.75rem;
  cursor:pointer;list-style-position:inside;min-width:0}
details.q-fold > summary.q-line h4{display:inline;margin:0;flex:none}
details.q-fold > summary .q-words{color:var(--dim);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;min-width:0}
details.q-fold[open] > summary .q-words{display:none}
details.q-fold[open] > summary{margin-bottom:.5rem}
.fold-page{display:inline-flex;gap:.5rem}

/* ✅ Piped text's picker (`R-096`). The code beside each choice is real text
   to copy when scripting is off, so it wraps rather than overflowing a phone. */
.pipe-picker{margin:.25rem 0 .75rem}
.pipe-group{margin:.6rem 0 .2rem}
.pipe-items{list-style:none;margin:0;padding:0;display:grid;gap:.25rem}
.pipe-items code{font-size:.85em;overflow-wrap:anywhere}

/* ✅ Carry forward (E-128) — a carried choice is read, not typed into. */
.option-row.carried{margin:.25rem 0;padding:.3rem 0;color:var(--dim)}
.option-row.carried .badge{margin-right:.4rem}
details.carry{margin:.75rem 0}
details.carry .grid-3{margin:.4rem 0}

/* ✅ R-055 — notes between colleagues, under a question in the builder. */
details.notes{margin:.75rem 0}
details.notes .note{border-left:3px solid var(--line);padding:.1rem 0 .4rem .6rem;margin:.4rem 0}
details.notes .note-by{margin:0}
details.notes .note-body{margin:.15rem 0 .3rem;white-space:pre-wrap}

/* ✅ R-002 — the template catalogue on the surveys page. */
details.starters{margin:1rem 0}
details.starters > summary{font-weight:600}
.starter-purpose{font-size:1rem;margin:1rem 0 .4rem}
.starter-list{list-style:none;padding:0;margin:0;display:grid;
  grid-template-columns:repeat(auto-fill,minmax(15rem,1fr));gap:.75rem}
.starter-list li{border:1px solid var(--line);border-radius:6px;padding:.6rem .75rem}
.starter-list p{margin:.1rem 0 .4rem}

/* ✅ The author's own ending message — their line breaks kept. */
.ending-message{white-space:pre-wrap}

/* ✅ Languages — the menu on a respondent's page, after its own buttons. */
.language-menu{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;margin:1rem 0}
.language-menu label{margin:0}

.language-row{border-top:1px solid var(--line);padding:.5rem 0}
.language-row p{margin:.2rem 0}

/* ✅ PRD E-247 — a rating drawn as stars. The radios stay real and
   focusable (clipped, not removed); each label draws an outlined star,
   and every star up to the one picked is filled — shape AND colour. */
.options.stars{gap:.15rem}
.options.stars .option{position:relative}
.options.stars input{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);margin:0}
.options.stars label{cursor:pointer;padding:.15rem .1rem;font-size:1.9rem;line-height:1}
.options.stars .star::before{content:"\2606";color:var(--dim)}
.options.stars input:checked + label .star::before{content:"\2605";color:var(--accent)}
.options.stars input:focus-visible + label{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
.options.stars:has(.option:nth-child(1) input:checked) .option:nth-child(-n+1) .star::before{content:"\2605";color:var(--accent)}
.options.stars:has(.option:nth-child(2) input:checked) .option:nth-child(-n+2) .star::before{content:"\2605";color:var(--accent)}
.options.stars:has(.option:nth-child(3) input:checked) .option:nth-child(-n+3) .star::before{content:"\2605";color:var(--accent)}
.options.stars:has(.option:nth-child(4) input:checked) .option:nth-child(-n+4) .star::before{content:"\2605";color:var(--accent)}
.options.stars:has(.option:nth-child(5) input:checked) .option:nth-child(-n+5) .star::before{content:"\2605";color:var(--accent)}
.options.stars:has(.option:nth-child(6) input:checked) .option:nth-child(-n+6) .star::before{content:"\2605";color:var(--accent)}
.options.stars:has(.option:nth-child(7) input:checked) .option:nth-child(-n+7) .star::before{content:"\2605";color:var(--accent)}
.options.stars:has(.option:nth-child(8) input:checked) .option:nth-child(-n+8) .star::before{content:"\2605";color:var(--accent)}
.options.stars:has(.option:nth-child(9) input:checked) .option:nth-child(-n+9) .star::before{content:"\2605";color:var(--accent)}
.options.stars:has(.option:nth-child(10) input:checked) .option:nth-child(-n+10) .star::before{content:"\2605";color:var(--accent)}
