/* ==========================================================================
   knoi.me -- the report. Extends the tokens in styles.css; defines none.

   THREE GROUNDS AND ONE COLUMN (DESIGN.md 5). Plum for the way in -- the
   code gate, then the opening once a report loads -- paper for everything
   that is read, plum again for the fun part, and the last field of the Arc
   under the code at the end. One left-aligned column at every width.

   TWO BASES, TWO TREATMENTS. A measured thing is a row on a ruled track in a
   domain hue with a range drawn on it; a reflected thing is quoted material
   on a set colour with no track, no hue from the domain ramp and no numeral.
   The reader tells them apart without a legend because only one of them has
   an axis under it. The plain sections ("About you", "Your life") say the
   measurement in words: ruled rows, no track, no bar, no number.

   COLOUR NEVER SAYS WHETHER A RESULT IS GOOD. The five --dom-* hues mark
   WHICH part of you a line belongs to and nothing else, so the same hue sits
   on a row at either end of the scale. The twelve --field-* / --arc-* set
   colours mark WHERE IN THE SESSION a quoted-back line came from and are
   identical for every person. Controls are the ink of their surface: plum on
   paper, porcelain on plum. Nothing here moves: no entrances, no reveals.

   Every ratio named below is recomputed from this file by
   tests/test_report_page.py, tests/test_palette.py and tests/test_redesign.py.
   ========================================================================== */

/* The `hidden` attribute is only display:none in the UA stylesheet, so ANY
   author rule that sets `display` silently beats it. Assert it once here. */
[hidden] {
  display: none !important;
}

/* -- the page ------------------------------------------------------------ */

.report-main {
  --ground: var(--paper);
  /* The rules between rows: plum at a quarter and at a half, on paper. */
  --rule: color-mix(in srgb, var(--night-plum) 24%, transparent);
  --rule-strong: color-mix(in srgb, var(--night-plum) 48%, transparent);
  background: var(--ground);
}

/* One column, left-aligned, 32em: 544px at 17px, about 73 characters of
   this page's own prose in Atkinson (its `ch` is wide; 66ch would render
   727px). From 1280 the column steps in by 96px (DESIGN.md 5). */
.report-col {
  --col-offset: 0px;
  max-width: 32em;
  /* The same left edge as a centred .shell (24px, or the centring margin
     once the page is wider than 1248px), never centred itself. */
  margin-inline: calc(max(24px, (100% - 1200px) / 2) + var(--col-offset)) auto;
}

.report-reading {
  padding-block: clamp(48px, 7vw, 80px);
}

/* The test's and the report's h1 sit on the h2 step; the landing hero is the
   one h1 that gets the h1 step. */
.report-main h1 {
  margin-bottom: var(--s-6);
  font-size: var(--fs-h2);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.03em;
}

/* The code and its placeholder: Atkinson 700, figures that line up, a
   little air between the characters so a code reads one character at a
   time. Named for what it does; it was `.mono`, a name that invited a
   monospace face back. */
.figures {
  font-family: var(--body);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.muted {
  color: var(--muted);
}

/* -- the motif ----------------------------------------------------------- */

/* The site's one picture, above the gate and above the opening: twelve
   ranges of the same length in the Arc's tints, on plum only. Identical for
   everyone, so it can never be mistaken for a result; hidden from a screen
   reader. Static here -- the report has no motion. */
.report-motif {
  display: grid;
  gap: 6px;
  width: 100%;
  margin-bottom: var(--s-8);
}

.report-motif > span {
  display: block;
  height: 6px;
  border-radius: var(--r-pill);
  background: var(--tint);
}

.report-motif > :nth-child(1) { --tint: var(--tint-01); }
.report-motif > :nth-child(2) { --tint: var(--tint-02); }
.report-motif > :nth-child(3) { --tint: var(--tint-03); }
.report-motif > :nth-child(4) { --tint: var(--tint-04); }
.report-motif > :nth-child(5) { --tint: var(--tint-05); }
.report-motif > :nth-child(6) { --tint: var(--tint-06); }
.report-motif > :nth-child(7) { --tint: var(--tint-07); }
.report-motif > :nth-child(8) { --tint: var(--tint-08); }
.report-motif > :nth-child(9) { --tint: var(--tint-09); }
.report-motif > :nth-child(10) { --tint: var(--tint-10); }
.report-motif > :nth-child(11) { --tint: var(--tint-11); }
.report-motif > :nth-child(12) { --tint: var(--tint-12); }

/* -- the way in: the code gate, the erase page, the opening -------------- */

.report-gate {
  padding-block: clamp(48px, 10vh, 112px);
}

.report-gate .lead {
  max-width: 32em;
}

/* The gate sits on plum; the erase page, reached only from the privacy
   policy, sits on the reading ground inside a plate with the alert edge --
   the one place on the page an alert colour is a fill, because the button
   inside it destroys something. */
.report-erase {
  padding-block: clamp(48px, 7vw, 80px);
}

.erase-plate {
  padding: clamp(24px, 4vw, 40px);
  border: 2px solid var(--alert-600);
  border-radius: var(--r-page);
  background: var(--paper);
  color: var(--night-plum);
}

.erase-plate .muted {
  margin: var(--s-6) 0 0;
}

.code-form {
  display: grid;
  gap: var(--s-3);
  max-width: 26rem;
  margin-top: var(--s-8);
}

.code-form label,
.email-form label {
  font-weight: 700;
}

/* The code field (DESIGN.md 6): 56px, Atkinson 700 with tabular figures --
   the face keeps 0/O and 1/l/I apart, which is exactly the code's problem --
   and a 2px edge. Paper fill on either ground; plum ink; the ring is the
   surface's own. */
.code-form input,
.email-form input {
  min-width: 0;
  min-height: 56px;
  padding: 12px 16px;
  border: 2px solid var(--night-plum);
  border-radius: var(--r-control);
  background: var(--paper);
  color: var(--night-plum);
  font-family: var(--body);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}

.email-form input {
  font-weight: 400;
  letter-spacing: 0;
}

.code-form input::placeholder,
.email-form input::placeholder {
  color: var(--muted);
  font-weight: 400;
}

.ground-deep .code-form input {
  border-color: var(--porcelain);
}

.code-form .button {
  justify-self: start;
}

.form-message {
  min-height: 1.5em;
  margin: var(--s-3) 0 0;
  font-size: var(--fs-xs);
}

.form-message.is-error {
  color: var(--alert-600);
  font-weight: 700;
}

.ground-deep .form-message.is-error {
  color: var(--alert-on-deep);
}

.button-erase,
.button-erase:hover {
  border-color: var(--alert-600);
  background: var(--alert-600);
  color: var(--porcelain);
}

.button-erase:hover {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.15em;
}

/* The opening: the motif, the quiet line, the heading, two caveat sentences. */
.report-intro {
  padding-block: clamp(48px, 10vh, 112px) clamp(48px, 8vw, 96px);
}

.report-intro .lead {
  max-width: 32em;
  margin-bottom: 0;
}

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

.report-section {
  margin-bottom: clamp(48px, 8vw, 96px);
}

.report-reading > .report-section:last-child {
  margin-bottom: 0;
}

.report-section h2 {
  margin-top: var(--s-2);
  margin-bottom: var(--s-4);
}

.section-note {
  max-width: 32em;
  margin-bottom: var(--s-6);
  color: var(--muted);
}

/* "Your life" opens with its own sentence, in the ink at the body step,
   and the quiet note under it says how the lines were made. The sentence
   used to be dressed as the section's tag (audit 2026-09-29, item 4). */
.life-lead {
  max-width: 32em;
  margin-bottom: var(--s-2);
  color: var(--night-plum);
  text-wrap: pretty;
}

.scale-note {
  margin-bottom: var(--s-4);
}

/* The per-section basis label. It is a heading, not a legend: it names what
   the section is made of, above every item made of it. Mixed case, the xs
   step, a small tag: filled plum for what was measured, outlined for what
   the person told us, dashed for a pairing of both, dotted for the guess. */
.basis-heading {
  display: inline-block;
  margin: 0;
  padding: 4px 12px;
  border: 1.5px solid var(--night-plum);
  border-radius: var(--r-control);
  font-size: var(--fs-xs);
  font-weight: 700;
  line-height: 1.5;
}

.basis-heading-measured {
  background: var(--night-plum);
  color: var(--porcelain);
}

.basis-heading-reflected {
  background: var(--paper);
  color: var(--night-plum);
}

.basis-heading-both {
  border-style: dashed;
  background: var(--paper);
  color: var(--night-plum);
}

/* The third kind names the INSTRUMENT, and sits on the instrument plate:
   the paper tag on the plate's field ground. Plum on paper 17.00:1. */
.basis-heading-instrument {
  background: var(--paper);
  color: var(--night-plum);
}

/* -- the caution and the instrument plate ------------------------------- */

/* A STATEMENT ABOUT THE SESSION OR THE INSTRUMENT, DRAWN AS NEITHER HALF.
   Measured content is a row on a ruled track; reflected content is quoted
   material on a set colour; this is a filled plate, edged on all four sides,
   holding nothing but prose. Drawn identically at every hedge level: a
   plate that went redder with the hedge would be a severity ramp, and a
   reader would learn that it means something about them. It does not.

   Plum on --field-01 12.58:1 for the prose, --muted on it 5.55:1 for the
   audit line, the plum edge 15.82:1 against the page; recomputed by
   tests/test_report_page.py. The ink is declared ONCE, on the plate. */
.report-caution,
.report-validity {
  max-width: 32em;
  padding: clamp(24px, 4vw, 40px);
  border: 2px solid var(--night-plum);
  border-radius: var(--r-page);
  background: var(--field-01);
  color: var(--night-plum);
}

.report-caution {
  margin-bottom: clamp(48px, 8vw, 96px);
}

.report-caution h2,
.report-validity h2 {
  margin-top: var(--s-2);
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.report-caution p:last-child {
  margin-bottom: 0;
}

.validity-subject {
  margin: 0 0 var(--s-6);
  font-weight: 700;
}

.validity-headline {
  margin: 0 0 var(--s-3);
  font-family: var(--display);
  font-optical-sizing: auto;
  font-size: var(--fs-item);
  font-weight: 700;
  line-height: 1.35;
}

.validity-detail,
.validity-holdback {
  margin: 0 0 var(--s-4);
}

/* What was actually measured, in full, for anybody who wants to check the
   sentences above against it. Ruled off, not boxed: the same statement
   continued. The rule is the boundary between the two voices. */
.validity-figures {
  margin: var(--s-6) 0 0;
  padding-top: var(--s-4);
  border-top: 1px solid var(--night-plum);
  font-size: var(--fs-xs);
  font-variant-numeric: tabular-nums;
  line-height: 1.6;
  color: var(--muted);
}

/* -- domain identity ----------------------------------------------------- */

/* ONE PLACE IN THE WHOLE REPORT CHOOSES A HUE, AND IT IS KEYED ON THE DOMAIN
   NAME. `.is-dom-*` is set from the domain and from nothing else -- never
   from theta, never from a band, never from a tier -- so a domain at the top
   of the scale and the same domain at the bottom resolve to the identical
   pair of inks. Everything downstream reads --row-dom and --row-ink and
   cannot reach the ramp at all.

   --row-ink is the mark drawn ON the hue, and it flips with the hue's
   lightness: porcelain on the three dark ones, plum on the two light ones.
   Measured, never eyeballed -- 8.38 / 13.19 / 5.66 / 8.80 / 5.71, recomputed
   by tests/test_report_page.py. */
.is-dom-o { --row-dom: var(--dom-o); --row-ink: var(--night-plum); }
.is-dom-c { --row-dom: var(--dom-c); --row-ink: var(--porcelain); }
.is-dom-e { --row-dom: var(--dom-e); --row-ink: var(--night-plum); }
.is-dom-a { --row-dom: var(--dom-a); --row-ink: var(--porcelain); }
.is-dom-n { --row-dom: var(--dom-n); --row-ink: var(--porcelain); }

/* Hue is never the only channel: the chip carries the domain's plain name
   beside a swatch of its colour, and nothing written in the swatch. */
.domain-key {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-bottom: var(--s-8);
}

.dom-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: 32px;
  padding: 4px 12px 4px 8px;
  border: 1px solid var(--night-plum);
  border-radius: var(--r-pill);
  background: var(--porcelain);
  color: var(--night-plum);
  font-size: var(--fs-xs);
  font-weight: 700;
  white-space: nowrap;
}

.dom-mark {
  display: inline-block;
  flex: none;
  width: 12px;
  height: 12px;
  border: 1px solid var(--night-plum);
  border-radius: 50%;
  background: var(--row-dom, var(--porcelain));
}

/* -- the ranges, on ruled tracks (inside the fold) ----------------------- */

/* One group per domain, headed by the domain's plain name over a rule; the
   rows inside sit in alphabetical order of their plain name. The heading
   carries no hue of its own: the hue is on each row's bar. */
.band {
  margin-bottom: var(--s-8);
}

.band-heading {
  margin: 0;
  padding-bottom: var(--s-2);
  border-bottom: 2px solid var(--night-plum);
  font-size: var(--fs-item);
  line-height: 1.25;
}

.finding-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

/* THE LABEL AND THE TRACK, AND NOTHING ELSE: a ruled row. */
.finding {
  display: grid;
  grid-template-columns: minmax(8rem, 11rem) minmax(0, 1fr);
  gap: var(--s-4);
  align-items: center;
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--rule);
}

.finding-label {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
}

.finding-name {
  overflow-wrap: anywhere;
}

/* THE INTERVAL, DRAWN. The bar is the 95% range and the primary mark: a
   solid domain hue inside a full-strength plum edge, 17.00:1 against paper
   whichever hue fills it. Two of the five hues (o at 2.03:1, e at 3.00:1)
   could never carry the object on their own, so the edge does the work and
   the hue is left free to say only which domain this is. The point estimate
   is a hairline tick INSIDE the bar, in the ink that clears 3:1 on that hue,
   and never more visible than the range around it.

   The track is the axis: a 1px rule across, and the line down the middle --
   the same for everyone -- at twice its weight. NO OPACITY ON THESE RULES:
   compositing a colour down to a tint is how the bar failed the first time.
   tests/test_report_page.py recomputes every ratio from this file. */
.finding-track {
  position: relative;
  height: 24px;
  background:
    linear-gradient(
      to right,
      transparent calc(50% - 1px),
      var(--rule-strong) calc(50% - 1px),
      var(--rule-strong) calc(50% + 1px),
      transparent calc(50% + 1px)
    ),
    linear-gradient(
      to bottom,
      transparent calc(50% - 0.5px),
      var(--rule) calc(50% - 0.5px),
      var(--rule) calc(50% + 0.5px),
      transparent calc(50% + 0.5px)
    );
}

.finding-bar {
  position: absolute;
  top: 4px;
  height: 16px;
  border: 2px solid var(--night-plum);
  border-radius: var(--r-pill);
  background: var(--row-dom, var(--night-plum));
}

/* A wide error. "Less certain" is carried by the EDGE STYLE, never by fading
   the mark: a dashed edge reads as "we are not sure where this stops" and
   costs nothing in contrast. The hue is unchanged. */
.is-wide .finding-bar {
  border-style: dashed;
}

/* The point estimate: hairline, inside the bar, never larger than it. */
.finding-dot {
  position: absolute;
  top: -2px;
  bottom: -2px;
  width: 2px;
  margin-left: -1px;
  background: var(--row-ink, var(--porcelain));
}

/* -- "Does this fit?" ---------------------------------------------------- */

/* Two identical 44px buttons in the ink (DESIGN.md 6): paper fill, 2px plum
   edge; the chosen one fills. The prompt beside them turns into the thanks
   line. Never a colour: Yes and Not really look the same. */
.finding-feedback {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2) var(--s-3);
  font-size: var(--fs-xs);
}

.feedback-prompt {
  margin-right: var(--s-1);
  font-weight: 700;
  color: var(--night-plum);
}

.feedback-button {
  min-width: 44px;
  min-height: 44px;
  padding: 0 16px;
  border: 2px solid var(--night-plum);
  border-radius: var(--r-control);
  background: var(--paper);
  color: var(--night-plum);
  font: inherit;
  font-weight: 700;
  line-height: 1.2;
  cursor: pointer;
  transition: background-color var(--t-state), color var(--t-state),
              transform var(--t-press);
}

.feedback-button:hover {
  background: var(--porcelain);
}

.feedback-button:active {
  transform: translateY(1px);
}

.feedback-button.is-chosen {
  background: var(--night-plum);
  color: var(--porcelain);
}

/* -- the plain part: About you, Your life ------------------------------- */

/* A SENTENCE ROW: the authored line at the item step, then one line naming
   the part it is about and its strength, then "Does this fit?". No track, no
   bar, no numeral. Rows are ruled, not carded: a solid rule under a plain
   row, a DASHED rule under a row that only leans. The small swatch before
   the part's name is the domain's hue read through --row-dom, exactly as
   the bars in the fold read it, so it says which domain and never how well.
   Plum on paper 17.00:1, --muted on paper 7.47:1. */
.about-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--s-8);
}

.about-group {
  display: grid;
  gap: 0;
}

.about-group-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
}

.about-row {
  --row-mark: var(--row-dom, var(--night-plum));
  display: grid;
  gap: var(--s-3);
  padding: var(--s-4) 0 var(--s-6);
  border-bottom: 1px solid var(--rule);
}

.about-row.is-hedged {
  border-bottom-style: dashed;
  border-bottom-color: var(--rule-strong);
}

.about-text {
  margin: 0;
  font-size: var(--fs-item);
  line-height: 1.35;
  color: var(--night-plum);
  text-wrap: pretty;
}

/* The reason a row leans sits straight under its sentence, before the
   label line -- in the DOM as well as on the page: report.mjs appends it
   before .about-meta, so a screen reader hears the reason before the
   question (design review round 1, finding 3). No `order` here. */
.about-hedge-why {
  margin: calc(-1 * var(--s-1)) 0 0;
  font-size: var(--fs-xs);
  line-height: 1.5;
  color: var(--muted);
}

.about-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2) var(--s-4);
}

/* The control always takes its own line, so every row reads the same:
   the sentence, the part and its strength, then the question. */
.about-meta .finding-feedback {
  flex-basis: 100%;
}

/* The plain name of the part the sentence is about ("worry and fear"), with
   the domain's swatch before it. The only label a plain row carries. */
.about-label {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--muted);
}

.about-label::before {
  content: "";
  flex: none;
  width: 12px;
  height: 12px;
  border: 1px solid var(--night-plum);
  border-radius: 50%;
  background: var(--row-mark);
}

/* ONE badge per row, mixed case, a small pill. It is a strength mark and not
   a verdict: a very low row wears it the same as a very high one. Filled for
   "very clear", outlined for "clear", a dashed outline for "leans that way"
   -- the same dashed edge the row's rule and a wide bar wear. Plum on
   porcelain 15.82:1, porcelain on plum 15.82:1. */
.about-strength {
  background: var(--night-plum);
  color: var(--porcelain);
}

.about-clear {
  background: var(--porcelain);
  color: var(--night-plum);
}

.about-hedge {
  background: var(--porcelain);
  color: var(--night-plum);
}

.about-strength,
.about-clear,
.about-hedge {
  display: inline-block;
  padding: 2px 10px;
  border: 1.5px solid var(--night-plum);
  border-radius: var(--r-pill);
  font-size: var(--fs-xs);
  font-weight: 700;
  line-height: 1.5;
}

.about-hedge {
  border-style: dashed;
}

.about-note {
  margin: 0 0 var(--s-6);
  max-width: 32em;
  font-weight: 700;
  color: var(--night-plum);
}

.about-note:empty {
  display: none;
}

.about-unclear,
.about-heldback {
  margin: var(--s-6) 0 0;
  max-width: 32em;
  color: var(--night-plum);
}

.life-empty {
  margin-top: 0;
}

/* THE FOLDS. One shape for every fold on the page: a 44px summary line in
   the ink with a plus that turns into a minus, the native marker hidden. */
.about-more-summary,
.about-unclear-summary,
.life-more-summary,
.stated-summary {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-height: 44px;
  padding: var(--s-2) 0;
  font-weight: 700;
  color: var(--night-plum);
  cursor: pointer;
  list-style: none;
}

.about-more-summary::-webkit-details-marker,
.about-unclear-summary::-webkit-details-marker,
.life-more-summary::-webkit-details-marker,
.stated-summary::-webkit-details-marker,
.numbers-summary::-webkit-details-marker {
  display: none;
}

.about-more-summary::after,
.about-unclear-summary::after,
.life-more-summary::after,
.stated-summary::after,
.numbers-summary::after {
  content: "+";
  flex: none;
  margin-left: auto;
  font-family: var(--body);
  font-size: 1.5rem;
  font-weight: 400;
  line-height: 1;
}

.about-more[open] > .about-more-summary::after,
.about-unclear-fold[open] > .about-unclear-summary::after,
.life-more[open] > .life-more-summary::after,
.stated-card[open] > .stated-summary::after,
.numbers-fold[open] > .numbers-summary::after {
  content: "\2212";
}

.about-more {
  margin-top: var(--s-2);
}

.about-more-summary,
.about-unclear-summary,
.life-more-summary {
  border-bottom: 1px solid var(--rule);
}

.about-more[open] > .about-more-summary,
.about-unclear-fold[open] > .about-unclear-summary,
.life-more[open] > .life-more-summary {
  border-bottom-color: transparent;
}

.about-unclear-lead {
  margin: 0 0 var(--s-2);
  color: var(--night-plum);
}

.about-unclear-why {
  margin: var(--s-3) 0 var(--s-2);
  color: var(--night-plum);
}

.about-unclear-list {
  margin: 0 0 var(--s-4);
  padding-left: 1.2em;
}

.about-unclear-item {
  break-inside: avoid;
  padding: 2px 0;
}

/* Your life: five plain headings on rules, sentences under each, one
   "Does this part fit you?" per area after every line in it. */
.life-areas {
  display: grid;
  gap: var(--s-12);
}

.life-area {
  padding-top: var(--s-4);
  border-top: 2px solid var(--night-plum);
}

.life-heading {
  margin: 0 0 var(--s-2);
}

.life-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
}

.life-row {
  display: grid;
  gap: var(--s-2);
  padding: var(--s-4) 0;
  border-bottom: 1px solid var(--rule);
}

.life-row.is-hedged {
  border-bottom-style: dashed;
  border-bottom-color: var(--rule-strong);
}

.life-text {
  margin: 0;
  color: var(--night-plum);
  text-wrap: pretty;
}

.life-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2) var(--s-4);
}

.life-more {
  margin-top: var(--s-2);
}

.life-area-fit {
  margin-top: var(--s-4);
}

/* The per-item stamp: what KIND of thing this is, on the item itself, so
   the distinction survives being read out of order or printed. A measured
   line gets a filled mark, a reflected one a hollow ring, a guess (often
   true for people who answer like you) a dotted ring. Mixed case. */
.basis-stamp {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  margin: 0;
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--muted);
}

.basis-dot {
  flex: none;
  width: 10px;
  height: 10px;
  border: 1.5px solid var(--night-plum);
  border-radius: 50%;
}

.is-measured .basis-dot {
  background: var(--night-plum);
}

.is-reflected .basis-dot {
  background: transparent;
}

.is-guess .basis-dot {
  background: transparent;
  border-style: dotted;
}

/* -- for fun ------------------------------------------------------------- */

/* THE ONE PLUM GROUND BETWEEN THE OPENING AND THE FOOTER (DESIGN.md 5), full
   bleed, so it reads as the fun part before a word of it is read: four
   paper cards on plum, radius 28. Porcelain on plum 15.82:1 for everything
   set straight on the plate; plum on paper 17.00:1 and --muted on paper
   7.47:1 inside the cards. tests/test_report_page.py recomputes each pair. */
.fun-section {
  padding-block: clamp(48px, 8vw, 96px);
  background: var(--night-plum);
  color: var(--porcelain);
}

.fun-section.report-section {
  margin-bottom: 0;
}

.fun-section h2 {
  max-width: 32em;
}

.fun-lede {
  max-width: 32em;
  margin: 0 0 var(--s-8);
  color: var(--porcelain);
}

/* Its own stamp: paper with a dotted edge, matching the empty card. Neither
   the measured stamp (filled plum) nor the reflected one (outlined). */
.basis-heading-fun {
  border-style: dotted;
  background: var(--porcelain);
  color: var(--night-plum);
}

.fun-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
  gap: var(--s-4);
  max-width: 56rem;
}

.fun-card {
  display: grid;
  gap: var(--s-3);
  align-content: start;
  padding: clamp(20px, 3vw, 32px);
  border-radius: var(--r-page);
  background: var(--paper);
  color: var(--night-plum);
}

/* A system the payload could not fill: porcelain, a dashed edge, so an
   absence looks like an absence and not like a result. */
.fun-card.is-empty {
  border: 2px dashed var(--night-plum);
  background: var(--porcelain);
}

.fun-title {
  margin: 0;
  font-size: var(--fs-h3);
  line-height: 1.2;
}

.fun-what,
.fun-caveat {
  margin: 0;
  font-size: var(--fs-xs);
  color: var(--muted);
}

.fun-line {
  margin: 0;
  font-weight: 700;
  color: var(--night-plum);
}

.fun-desc,
.fun-note {
  margin: 0;
  color: var(--night-plum);
}

.fun-rough {
  font-weight: 700;
}

.fun-axes {
  list-style: none;
  padding: 0;
  margin: var(--s-1) 0 0;
  display: grid;
  gap: var(--s-2);
}

/* THREE FIXED COLUMNS, so the four rows line up: the pair, the letter in its
   ring, and the phrase. The phrase's cell is `minmax(0, 1fr)` so it wraps
   inside its own column instead of pushing the row wider than the card. */
.fun-axis {
  display: grid;
  grid-template-columns: 2.4rem 2rem minmax(0, 1fr);
  align-items: center;
  column-gap: var(--s-2);
}

.fun-axis-pair {
  font-size: var(--fs-xs);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

.fun-axis-letter {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border: 1.5px solid var(--night-plum);
  border-radius: 50%;
  background: var(--porcelain);
  color: var(--night-plum);
  font-family: var(--display);
  font-optical-sizing: auto;
  font-weight: 700;
}

.fun-axis.is-unclear .fun-axis-letter {
  border-style: dashed;
}

/* A leaning axis has its letter; the dotted ring says it is held more
   lightly than a solid one. */
.fun-axis.is-leaning .fun-axis-letter {
  border-style: dotted;
}

.fun-axis-label {
  min-width: 0;
  font-size: var(--fs-xs);
  overflow-wrap: anywhere;
}

/* What the pair's two letters stand for: one small line under the three
   cells, spanning the row. A key, not a finding. */
.fun-axis-means {
  grid-column: 1 / -1;
  min-width: 0;
  margin: 0 0 var(--s-1);
  font-size: var(--fs-xs);
  line-height: 1.4;
  color: var(--muted);
  overflow-wrap: anywhere;
}

.fun-dims {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--s-3);
}

.fun-dim-name {
  margin: 0 0 2px;
  font-weight: 700;
  font-size: var(--fs-xs);
}

.fun-dim-text {
  margin: 0;
}

/* A dimension that did not resolve: its name underlined dashed, like every
   other "we are not sure" mark on the page. */
.fun-dim.is-unresolved .fun-dim-name {
  text-decoration: underline;
  text-decoration-style: dashed;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 0.2em;
}

.fun-question {
  margin: 0;
  font-size: var(--fs-xs);
  color: var(--muted);
}

.fun-quote {
  margin: 0;
  font-style: italic;
  color: var(--night-plum);
}

.fun-card .basis-stamp {
  margin: 0;
}

/* The card is a grid; the control spans its one column and never opens a
   second (the named areas below are scoped to the band row). */
.fun-card .finding-feedback {
  margin-top: var(--s-2);
  grid-area: auto;
}

/* The one line pointing at the citations, which live on sources.html. */
.fun-sources {
  margin: var(--s-8) 0 0;
  font-size: var(--fs-xs);
  color: var(--porcelain);
}

/* =========================================================================
   THE REFLECTED HALF
   Nothing below draws a track, a bar, a dot or a numeral.
   ========================================================================= */

.reflected-section {
  position: relative;
}

/* -- your own words ------------------------------------------------------ */

/* A field card (DESIGN.md 6): the set's own field for a ground, plum text,
   radius 16, no edge. The one bead at the top of the card is the set's arc
   colour -- the Spine's own mark -- and says which part of the session the
   words came from; it is identical for every person and encodes nothing. */
.quote-stack {
  display: grid;
  gap: var(--s-4);
}

.quote-card,
.stated-card,
.prompt-card {
  --set-arc: var(--arc-now);
  margin: 0;
  padding: clamp(20px, 3vw, 32px);
  border-radius: var(--r-card);
  background: var(--field-now);
  color: var(--night-plum);
}

.quote-card::before,
.stated-card::before,
.prompt-card::before {
  content: "";
  display: block;
  width: 32px;
  height: 8px;
  margin-bottom: var(--s-4);
  border-radius: var(--r-pill);
  background: var(--set-arc);
}

.quote-text {
  margin: 0;
  font-family: var(--display);
  font-optical-sizing: auto;
  font-size: clamp(1.15rem, 2.4vw, 1.5rem);
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: -0.01em;
  color: var(--night-plum);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.quote-followup {
  margin: var(--s-6) 0 0;
  padding-top: var(--s-4);
  border-top: 1px dashed var(--night-plum);
}

.followup-label {
  display: block;
  margin-bottom: var(--s-1);
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--muted);
}

.followup-text {
  margin: 0;
}

.quote-slot-heading {
  margin: 0 0 calc(-1 * var(--s-2));
  font-size: var(--fs-item);
}

/* -- the choices you made ------------------------------------------------ */

.stated-groups {
  display: grid;
  gap: var(--s-12);
}

.stated-heading {
  margin: 0 0 var(--s-1);
  font-size: var(--fs-item);
}

.stated-blurb {
  margin: 0 0 var(--s-4);
  max-width: 32em;
  color: var(--muted);
}

.stated-cards {
  display: grid;
  gap: var(--s-3);
}

.stated-card {
  padding-block: var(--s-4);
}

.stated-summary {
  flex-wrap: wrap;
  align-items: baseline;
}

.stated-summary::after {
  align-self: center;
}

.stated-statement {
  color: var(--night-plum);
}

.stated-source {
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--muted);
}

.stated-detail {
  padding: var(--s-2) 0 var(--s-2);
  border-top: 1px dashed var(--night-plum);
}

.stated-question-label,
.stated-answer-label {
  margin: var(--s-4) 0 2px;
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--muted);
}

.stated-question,
.stated-answer {
  margin: 0;
}

.stated-answer {
  font-weight: 700;
}

/* Provenance, deliberately quiet: the id of the option that was pressed. */
.stated-option-id {
  margin: var(--s-4) 0 0;
  font-size: var(--fs-xs);
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

/* -- depends on the situation --------------------------------------------- */

/* Reflected, and drawn as reflected: the item's own wording on ruled rows,
   a hollow stamp, no track, no bar, no numeral. The domain chip says WHICH
   part of the report the question fed, and nothing about the answer. */
.varies-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
}

.varies-item {
  display: grid;
  gap: var(--s-2);
  padding: var(--s-4) 0;
  border-bottom: 1px solid var(--rule);
}

.varies-text {
  margin: 0;
  font-family: var(--display);
  font-optical-sizing: auto;
  font-size: var(--fs-item);
  font-weight: 700;
  line-height: 1.35;
  letter-spacing: -0.01em;
  color: var(--night-plum);
}

.varies-text.is-unnamed {
  font-family: inherit;
  font-size: var(--fs-body);
  font-weight: 400;
  letter-spacing: 0;
  color: var(--muted);
}

.varies-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2) var(--s-4);
}

.varies-meta .basis-stamp {
  margin: 0;
}

.varies-facet {
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--muted);
}

/* -- what a skip cost ---------------------------------------------------- */

/* This section is about ABSENCE, so it is an outline and never a filled
   card: nothing here is a result. The domain hues appear on the chip beside
   a facet's name to say WHICH domain, never how well. */
.skips-section {
  padding: clamp(20px, 3vw, 32px);
  border: 2px dashed var(--night-plum);
  border-radius: var(--r-page);
}

.basis-heading-gap {
  border-style: dashed;
  background: var(--paper);
  color: var(--night-plum);
}

.skip-kinds {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--s-6);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
}

.skip-kind {
  padding: 4px 12px;
  border: 1px solid var(--night-plum);
  border-radius: var(--r-pill);
  background: var(--porcelain);
  color: var(--night-plum);
  font-size: var(--fs-xs);
  font-weight: 700;
}

.skip-facets {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
}

.skip-facet {
  padding: var(--s-4) 0;
  border-bottom: 1px solid var(--rule);
  color: var(--muted);
}

/* An emptied facet is the loudest thing this section has to say, so it gets
   the only solid rule in it; a thinned one is softer and drawn as one. Both
   are the same ink: neither is a colour on a good/bad ramp. */
.skip-facet.is-gone {
  border-bottom: 2px solid var(--night-plum);
}

.skip-facet.is-thin {
  border-bottom: 2px dotted var(--night-plum);
}

.skip-facet.is-unscored,
.skip-facet.is-unnamed {
  max-width: 32em;
}

.skip-facet-name {
  margin: 0 0 var(--s-1);
  font-weight: 700;
  color: var(--night-plum);
}

.skip-facet-line {
  margin: 0;
  max-width: 32em;
}

.skip-facet-names {
  list-style: none;
  padding: 0;
  margin: var(--s-3) 0 0;
  display: grid;
  gap: var(--s-2);
}

.skip-facet-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
  color: var(--night-plum);
}

.skip-facet-detail {
  font-size: var(--fs-xs);
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

.skip-widths {
  margin-top: var(--s-6);
}

.skip-widths-lede {
  margin: 0 0 var(--s-2);
  font-weight: 700;
  color: var(--night-plum);
}

.skip-widths-list {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--s-4);
  display: grid;
  gap: var(--s-1);
}

.skip-width {
  font-size: var(--fs-xs);
  font-variant-numeric: tabular-nums;
  color: var(--night-plum);
}

.skip-caveat {
  margin: 0;
  max-width: 32em;
  color: var(--muted);
}

/* -- contrasts ----------------------------------------------------------- */

.contrast-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--s-6);
}

.contrast {
  padding: clamp(20px, 3vw, 32px);
  border-radius: var(--r-page);
  background: var(--porcelain);
}

.contrast-kind {
  margin: 0 0 var(--s-4);
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--muted);
}

.contrast-pair {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: stretch;
  gap: var(--s-4);
}

.contrast-and {
  align-self: center;
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--muted);
}

.contrast-side {
  padding: var(--s-4) var(--s-6);
  border-radius: var(--r-card);
}

/* The two sides are deliberately not symmetrical: the measured side is a
   paper card with a plum edge; the told-us side is a set colour with a
   dashed edge and no number anywhere. Two visibly different objects. */
.contrast-side.is-measured {
  border: 2px solid var(--night-plum);
  background: var(--paper);
}

.contrast-side.is-reflected {
  border: 1px dashed var(--night-plum);
  background: var(--field-06);
}

.contrast-lede {
  margin: 0 0 var(--s-2);
  font-weight: 700;
}

.contrast-question {
  margin: var(--s-2) 0 0;
  font-size: var(--fs-xs);
  color: var(--muted);
}

.contrast-range {
  margin: var(--s-2) 0 0;
  font-size: var(--fs-xs);
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

.contrast-note {
  margin: var(--s-4) 0 0;
  max-width: 32em;
  color: var(--muted);
}

/* -- leftover prompts ---------------------------------------------------- */

.prompt-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--s-4);
}

.prompt-text {
  margin: 0;
  font-family: var(--display);
  font-optical-sizing: auto;
  font-size: var(--fs-item);
  font-weight: 700;
  line-height: 1.35;
  letter-spacing: -0.01em;
}

.prompt-anchor {
  margin: var(--s-3) 0 0;
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--muted);
}

/* The twelve set colours: the field for the ground, the arc for the bead.
   They mark which part of the session a card came from and are identical
   for every person, so they cannot encode a result. */
.is-field-01 { background: var(--field-01); --set-arc: var(--arc-01); }
.is-field-02 { background: var(--field-02); --set-arc: var(--arc-02); }
.is-field-03 { background: var(--field-03); --set-arc: var(--arc-03); }
.is-field-04 { background: var(--field-04); --set-arc: var(--arc-04); }
.is-field-05 { background: var(--field-05); --set-arc: var(--arc-05); }
.is-field-06 { background: var(--field-06); --set-arc: var(--arc-06); }
.is-field-07 { background: var(--field-07); --set-arc: var(--arc-07); }
.is-field-08 { background: var(--field-08); --set-arc: var(--arc-08); }
.is-field-09 { background: var(--field-09); --set-arc: var(--arc-09); }
.is-field-10 { background: var(--field-10); --set-arc: var(--arc-10); }
.is-field-11 { background: var(--field-11); --set-arc: var(--arc-11); }
.is-field-12 { background: var(--field-12); --set-arc: var(--arc-12); }

/* -- limits -------------------------------------------------------------- */

.report-limits ul {
  max-width: 32em;
  display: grid;
  gap: var(--s-3);
  margin: 0;
  padding-left: 1.2em;
}

.report-limits li::marker {
  color: var(--night-plum);
}

/* -- the keepsake -------------------------------------------------------- */

/* THE CODE, KEPT (DESIGN.md 5): the last field of the Arc for a ground, the
   dashed code large in Atkinson 700 with tabular figures -- the same type
   it had on the finish screen -- and no red anywhere: the warning is set in
   the ink. Plum on --field-12 12.58:1, --muted on it 5.53:1. */
.report-keep {
  padding: clamp(24px, 4vw, 40px);
  border-radius: var(--r-page);
  background: var(--field-12);
  color: var(--night-plum);
}

.report-keep h2 {
  margin-top: 0;
}

.report-keep .figures {
  display: block;
  margin-top: var(--s-2);
  font-size: clamp(1.5rem, 5vw, 2rem);
  line-height: 1.3;
  overflow-wrap: anywhere;
}

.warn {
  max-width: 32em;
  font-weight: 700;
  color: var(--night-plum);
}

.email-form {
  display: grid;
  gap: var(--s-3);
  max-width: 26rem;
  margin-top: var(--s-6);
}

.email-form .button-small {
  justify-self: start;
  min-height: 48px;
}

.report-keep .muted {
  max-width: 32em;
  margin: var(--s-4) 0 0;
}

/* -- the numbers, folded away --------------------------------------------- */

/* One closed <details> at the foot of the page holding the picture of the
   measurement. Its summary is a ruled row at the h3 step. */
.numbers-fold {
  border-top: 2px solid var(--night-plum);
  border-bottom: 1px solid var(--rule);
}

.numbers-summary {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  min-height: 64px;
  padding: var(--s-3) 0;
  font-family: var(--display);
  font-optical-sizing: auto;
  font-size: var(--fs-h3);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--night-plum);
  cursor: pointer;
  list-style: none;
}

.numbers-fold > .report-section {
  margin: var(--s-6) 0 var(--s-8);
}

/* The fold's own heading sits under its 24px summary, so it takes the
   caution plate's step, not the page's h2 step: an appendix must not
   outrank the control that opens it or the report's real sections
   (design review round 1, finding 1). */
.numbers-fold h2 {
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.numbers-fold > .muted {
  max-width: 32em;
  margin: 0 0 var(--s-6);
}

/* =========================================================================
   MEDIA
   ========================================================================= */

@media (min-width: 1280px) {
  .report-col {
    --col-offset: var(--s-24);
  }

  .fun-shell {
    padding-left: var(--s-24);
  }
}

/* Two columns of unclear names where there is room. */
@media (min-width: 36rem) {
  .about-unclear-list {
    columns: 2;
    column-gap: var(--s-8);
  }
}

@media (max-width: 52rem) {
  .contrast-pair {
    grid-template-columns: 1fr;
  }

  .contrast-and {
    justify-self: start;
  }
}

@media (max-width: 44rem) {
  /* A ROW ON A PHONE: the name over the track, and the track keeps the full
     width because where a bar sits along it is the whole point.

     SCOPED TO THE BAND ROW, AND THAT SCOPE IS LOAD-BEARING. `fitControl()`
     builds the same `.finding-feedback` for the plain rows, the life areas
     and the fun cards, and a fun card is a grid too. Unscoped, a named
     `grid-area` reached every grid on the page. tests/test_report_page.py
     asserts these rules never lose their `.finding` prefix. */
  .finding {
    grid-template-columns: 1fr;
    grid-template-areas:
      "label"
      "track";
    row-gap: var(--s-1);
    padding: var(--s-3) 0;
  }

  .finding .finding-label {
    grid-area: label;
  }

  .finding .finding-track {
    grid-area: track;
  }

  .band {
    margin-bottom: var(--s-6);
  }

  .contrast-side {
    padding: var(--s-4);
  }
}

/* The report has no motion of its own; what stays is the button press, and
   under reduced motion the press keeps its colour and loses its movement. */
@media (prefers-reduced-motion: reduce) {
  .feedback-button:active {
    transform: none;
  }
}

/* Windows High Contrast strips backgrounds: the bars keep their real edge,
   the tick and the motif get one, the swatches get a ring. */
@media (forced-colors: active) {
  .finding-dot,
  .dom-mark,
  .about-label::before,
  .report-motif > span,
  .quote-card::before,
  .stated-card::before,
  .prompt-card::before {
    outline: 1px solid CanvasText;
  }

  .about-strength,
  .feedback-button.is-chosen,
  .basis-heading-measured {
    forced-color-adjust: none;
    background: CanvasText;
    color: Canvas;
  }
}

/* Printed: the reading, without the controls. Colour is what tells the
   domains apart, so it is kept. */
@media print {
  .site-header,
  .site-footer,
  .skip-link,
  .finding-feedback,
  .email-form {
    display: none !important;
  }

  .ground-deep,
  .fun-section,
  .report-keep,
  .fun-card,
  .finding-bar,
  .finding-dot,
  .dom-mark,
  .report-motif > span {
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }
}
