/* ==========================================================================
   results.css — dashboard, welcome-page grids, tooltips
   ========================================================================== */

/* ---------- welcome page ---------- */
/* Nine modules, so three by three. auto-fill gave five and then four, which
   left a ragged half-row and made the set look like an arbitrary list rather
   than a fixed programme. */
.mod-grid {
  display: grid; gap: var(--s-3);
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin-top: var(--s-5);
}
@media (max-width: 900px) { .mod-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .mod-grid { grid-template-columns: 1fr; } }

.mod-card-top {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s-2);
}
.mod-num {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: var(--t-tiny); color: var(--txt-4); letter-spacing: .08em;
}
.mod-time { font-size: var(--t-tiny); color: var(--txt-4); }
.mod-name { margin-top: var(--s-3); font-size: var(--t-head); }
.mod-tag {
  margin-top: var(--s-1); font-size: var(--t-small);
  color: var(--txt-2); line-height: var(--lh-snug);
}
.mod-card {
  position: relative; overflow: hidden;
  padding: var(--s-4);
  background: var(--bg-1); border: 1px solid var(--line);
  border-radius: var(--radius);
  transition: border-color var(--mid) var(--ease), transform var(--mid) var(--ease);
}
.mod-card:hover { border-color: var(--line-2); transform: translateY(-2px); }

.two-col {
  display: grid; gap: var(--s-4);
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  margin-top: var(--s-5);
}

.tick-list, .cross-list { list-style: none; display: flex; flex-direction: column; gap: var(--s-2); }
.tick-list li, .cross-list li {
  position: relative; padding-left: var(--s-5);
  font-size: var(--t-small); color: var(--txt-2); line-height: 1.45;
}
.tick-list li::before, .cross-list li::before {
  position: absolute; left: 0; top: -.03em;
  font-family: var(--mono); font-size: var(--t-body);
}
.tick-list li::before  { content: '✓'; color: var(--good); }
.cross-list li::before { content: '✕'; color: var(--txt-4); }

/* ---------- pre-flight ---------- */
/* One edge, drawn once, on the page side of the panel.
   Outset rather than inset, for two reasons. An inset ring lies ON the
   sample, and its contrast then depends on whatever the sample happens to be
   — against the near-black end of the shadow wedge it read clearly, against
   the mid-greys four steps along it disappeared, so the same strip had an
   edge at one end and none at the other. Drawn outside, it sits on the page
   ground, which is constant, so both wedges and the grey panel get an edge of
   identical weight. It also keeps ink off the sample, which is the same rule
   the stimulus field follows.

   A shadow and not a `border`, so it costs no layout width: the strip stays
   exactly as wide as the column gave it, and `overflow: hidden` keeps the
   canvas inside the radius. */
.wedge,
.check-flat-inner {
  border-radius: var(--radius-sm);
  overflow: hidden;
  box-shadow: 0 0 0 1px var(--line-2);
}
/* `block` and a matched height, so the canvas box is exactly the panel box —
   an inline canvas leaves a baseline gap under it and the bottom edge of the
   border then floats a few pixels clear of the last row of pixels. */
.wedge canvas { width: 100%; height: 100%; display: block; }

/* ---------- display setup ----------
   The instructions come before the test patterns, so they are the first thing
   on the page and have to read like instructions: a numbered list with room
   to breathe, not a paragraph of advice under a diagram. */
.check-step {
  font-size: var(--t-title); letter-spacing: -.022em;
  padding-bottom: var(--s-3); border-bottom: 1px solid var(--line);
}
.setup-list {
  list-style: none; margin-top: var(--s-5);
  display: flex; flex-direction: column; gap: var(--s-5);
}
.setup-item { display: grid; grid-template-columns: auto 1fr; gap: var(--s-4); align-items: start; }
.setup-num {
  width: 2.25rem; height: 2.25rem; flex: 0 0 auto;
  display: grid; place-items: center;
  border-radius: var(--radius-sm);
  background: var(--bg-2); border: 1px solid var(--line);
  color: var(--accent);
}
.setup-num svg { width: 1.1rem; height: 1.1rem; }
.setup-title { font-size: var(--t-body); font-weight: 580; color: var(--txt); letter-spacing: -.01em; }
.setup-body {
  margin-top: var(--s-2);
  font-size: var(--t-small); color: var(--txt-2); line-height: var(--lh-body);
  max-width: 66ch;
}
@media (max-width: 560px) {
  .setup-item { grid-template-columns: 1fr; gap: var(--s-3); }
}

/* A flat grey field — the pattern that shows a colour cast, and the only one
   that needs no reference to read. Deliberately large: a tint is far easier to
   see across a broad area than in a swatch. */
.check-flat { position: relative; margin-top: var(--s-3); }
.check-flat-inner {
  height: clamp(7rem, 18vh, 11rem);
  background: #808080;
}
.check-flat-cap {
  position: absolute; left: var(--s-3); bottom: var(--s-3);
  font-size: var(--t-micro); letter-spacing: .12em; text-transform: uppercase;
  color: rgba(0, 0, 0, .42);
}

.check-opts { display: flex; gap: var(--s-2); flex-wrap: wrap; }
.check-opts .opt-btn {
  min-width: 2.6rem; padding: var(--s-2) var(--s-3);
  background: var(--bg-2); border-color: var(--line-2); color: var(--txt-2);
}
.check-opts .opt-btn:hover { background: var(--bg-3); color: var(--txt); }
.check-opts .opt-btn.is-on { background: var(--txt); color: var(--bg); border-color: var(--txt); }

.env-grid {
  display: grid; gap: var(--s-2) var(--s-5);
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
}
.env-item dt { font-size: var(--t-micro); letter-spacing: .09em; text-transform: uppercase; color: var(--txt-4); }
.env-item dd { font-size: var(--t-small); color: var(--txt); margin-top: var(--s-0); }

/* ---------- results hero ---------- */
.res-hero {
  display: flex; align-items: center; gap: clamp(1.4rem, 4vw, 3rem);
  padding: clamp(1.4rem, 3vw, 2.2rem);
  background:
    radial-gradient(90% 130% at 12% 0%, rgba(141,180,216,.10), transparent 62%),
    var(--bg-1);
  border: 1px solid var(--line-2);
  border-radius: var(--radius-lg);
  flex-wrap: wrap;
}
.res-hero-ring { position: relative; flex: 0 0 auto; width: clamp(8rem, 16vw, 11rem); aspect-ratio: 1; }
.res-hero-ring canvas { width: 100%; height: 100%; }
.res-hero-num {
  position: absolute; inset: 0; display: grid; place-content: center; text-align: center;
}
.res-num {
  display: block; font-size: clamp(2.4rem, 5vw, 3.4rem); font-weight: 600;
  letter-spacing: -.045em; line-height: 1; font-variant-numeric: tabular-nums;
}
.res-den { display: block; font-size: var(--t-tiny); color: var(--txt-3); margin-top: var(--s-1); font-family: var(--mono); }
.res-hero-body { flex: 1 1 22rem; min-width: 0; }

.res-reading p { font-size: var(--t-body); line-height: 1.6; }

/* ---------- sections & grids ---------- */
.res-section { margin-top: var(--s-7); }
.res-section + .res-grid-2, .res-section + .frame { margin-top: var(--s-5); }

.res-grid-2 {
  display: grid; gap: var(--s-4);
  grid-template-columns: repeat(auto-fit, minmax(23rem, 1fr));
}
@media (max-width: 720px) {
  .res-grid-2 { grid-template-columns: 1fr; }
}

.frame-body { min-height: 12rem; }
.scene-body { padding: 0; }
.scene-body canvas { width: 100%; height: 100%; min-height: 26rem; }

/* ---------- module cards ---------- */
.res-modules { display: flex; flex-direction: column; gap: var(--s-3); margin-top: var(--s-5); }
.res-mod {
  padding: var(--s-4) var(--s-5);
  background: var(--bg-1); border: 1px solid var(--line);
  border-radius: var(--radius);
}
.res-mod-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); flex-wrap: wrap; }
.res-mod-score {
  font-size: var(--t-sub); font-weight: 600; letter-spacing: -.03em;
  color: var(--txt); font-variant-numeric: tabular-nums;
}
.res-metrics {
  display: grid; gap: var(--s-3) var(--s-5); margin-top: var(--s-4);
  grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr));
}
.res-metric dt { font-size: var(--t-micro); letter-spacing: .09em; text-transform: uppercase; color: var(--txt-4); }
.res-metric dd { font-size: var(--t-head); color: var(--txt); margin-top: var(--s-0); letter-spacing: -.01em; }
.res-insight {
  margin-top: var(--s-4); padding-top: var(--s-3); border-top: 1px solid var(--line);
  line-height: var(--lh-body);
}

/* ---------- caveats ---------- */
.res-caveats { background: var(--bg-2); }
.res-caveat-list { list-style: none; display: flex; flex-direction: column; gap: var(--s-2); }
.res-caveat-list li {
  position: relative; padding-left: var(--s-4);
  font-size: var(--t-small); color: var(--txt-2); line-height: 1.5;
}
.res-caveat-list li::before {
  content: ''; position: absolute; left: 0; top: .6em;
  width: .32rem; height: .32rem; border-radius: 99px; background: var(--warn);
}

/* ---------- raw data ---------- */
.res-raw {
  width: 100%; margin-top: var(--s-3);
  background: var(--bg); color: var(--txt-2);
  border: 1px solid var(--line-2); border-radius: var(--radius-sm);
  padding: var(--s-3); font-family: var(--mono); font-size: var(--t-tiny); line-height: 1.5;
  resize: vertical;
}

/* ---------- chart tooltip ---------- */
.viz-tip {
  position: fixed; z-index: 120; display: none; pointer-events: none;
  background: rgba(24,27,31,.97);
  border: 1px solid var(--line-2);
  border-radius: var(--radius-sm);
  padding: var(--s-2) .65rem;
  font-size: var(--t-tiny); line-height: 1.45; color: var(--txt);
  box-shadow: var(--shadow-1);
  max-width: 16rem;
}
.viz-tip b { font-weight: 600; }
.viz-tip .dim { color: var(--txt-3); }

/* ---------- welcome hero ---------- */
.hero-grid {
  display: grid; gap: clamp(1.5rem, 4vw, 3.2rem);
  grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
  align-items: center;
}
@media (max-width: 900px) {
  .hero-grid { grid-template-columns: 1fr; }
  .hero-viz { order: -1; }
}
.hero-viz { min-width: 0; }
.hero-viz canvas {
  width: 100%; aspect-ratio: 1 / 1; max-height: 26rem;
  display: block; margin-inline: auto;
}
.hero-viz-cap {
  margin-top: var(--s-2); text-align: center;
  font-size: var(--t-tiny); color: var(--txt-4); line-height: 1.5;
}
.hero-grid h1 { max-width: 15ch; }

/* ==========================================================================
   Confidence table
   --------------------------------------------------------------------------
   Three columns of the same row are three different kinds of claim: what was
   measured, the number, and how much the number is worth. Keeping them in one
   line rather than three stacked cards is what makes the last column readable
   as a qualifier rather than as another statistic.
   ========================================================================== */
.conf-rows { margin-top: var(--s-4); display: flex; flex-direction: column; }
.conf-row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(7rem, auto);
  gap: var(--s-3); align-items: baseline;
  padding: var(--s-2) 0;
  border-top: 1px solid var(--line);
  font-size: var(--t-small);
}
.conf-row:first-child { border-top: 0; }
.conf-label { color: var(--txt-2); min-width: 0; }
.conf-value { color: var(--txt); font-weight: 500; }
.conf-ci { color: var(--txt-4); font-size: var(--t-tiny); text-align: right; }
/* a run that never resolved is dimmed rather than flagged red — it is an
   absence of measurement, not an error */
.conf-row.is-weak .conf-value { color: var(--txt-3); }
.conf-row.is-weak .conf-ci { color: var(--warn); }
@media (max-width: 560px) {
  .conf-row { grid-template-columns: 1fr auto; }
  .conf-ci { grid-column: 1 / -1; text-align: left; }
}

/* ==========================================================================
   Run-to-run comparison
   ========================================================================== */
.cmp-grid {
  display: grid; gap: var(--s-2);
  grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
}
.cmp-item {
  padding: var(--s-3) var(--s-3); border-radius: var(--radius-sm);
  background: var(--bg-2); border: 1px solid var(--line);
  border-left: 2px solid var(--line-2);
}
.cmp-item dt { font-size: var(--t-micro); letter-spacing: .09em; text-transform: uppercase; color: var(--txt-4); }
.cmp-item dd { font-size: var(--t-sub); color: var(--txt); margin-top: var(--s-1); line-height: 1.1; }
.cmp-item .tiny { margin-top: var(--s-1); }
/* Direction is carried by the border, not by a coloured number: a green or
   red figure beside a colour swatch is exactly the kind of chromatic noise
   this project keeps out of judging surfaces, and the results page shares its
   palette. */
.cmp-item.is-up    { border-left-color: var(--good); }
.cmp-item.is-down  { border-left-color: var(--warn); }
.cmp-item.is-level { border-left-color: var(--line-3); }

/* ==========================================================================
   Author credit
   --------------------------------------------------------------------------
   A credit, not a bio page. The monogram is a flat neutral tile rather than a
   photograph or a coloured badge: this block sits on the same page as colour
   swatches, and the project's rule against saturated chrome next to a stimulus
   holds here too.
   ========================================================================== */
.author-card { border-color: var(--line-2); }
.author-head { display: flex; align-items: center; gap: var(--s-3); }
.author-mark {
  width: 2.4rem; height: 2.4rem; flex: 0 0 auto;
  border-radius: var(--radius-sm);
  display: grid; place-items: center;
  background: var(--bg-3); border: 1px solid var(--line-2);
  font-size: var(--t-tiny); font-weight: 620; letter-spacing: .06em;
  color: var(--txt-2);
}
.author-name { font-size: var(--t-body); font-weight: 580; letter-spacing: -.012em; }
.author-role { font-size: var(--t-tiny); color: var(--txt-3); }
.author-block { border-top: 1px solid var(--line); padding-top: var(--s-4); }

.res-credit {
  font-size: var(--t-small); color: var(--txt-3); line-height: 1.6;
  padding-top: var(--s-5); border-top: 1px solid var(--line);
}
.res-credit a { color: var(--txt-2); text-decoration-color: var(--line-3); }
.res-credit a:hover { color: var(--accent); }

/* ---------- folded chart notes ---------- */
.how-to-read > summary {
  cursor: pointer; list-style: none;
  font-size: var(--t-tiny); font-weight: 560; color: var(--txt-4);
  display: inline-flex; align-items: center; gap: var(--s-2);
  padding: var(--s-1) 0;
  transition: color .15s var(--ease);
}
.how-to-read > summary::-webkit-details-marker { display: none; }
.how-to-read > summary::before {
  content: ''; width: .38rem; height: .38rem; flex: 0 0 auto;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(-45deg) translate(-1px, -1px);
  transition: transform .18s var(--ease);
}
.how-to-read[open] > summary::before { transform: rotate(45deg) translate(-1px, -1px); }
.how-to-read > summary:hover { color: var(--txt-2); }
.how-to-read p { max-width: 78ch; }


/* ==========================================================================
   Welcome page — sections and hero
   ========================================================================== */

/* Vertical rhythm for the whole page, from the space scale. */
.page-body { padding: var(--s-8) 0 var(--s-8); }

/* Every section opens the same distance from what precedes it. There is no
   :first-of-type reset — the hero is not a .section, so the first heading
   needs the gap as much as the rest. */
.section { margin-top: var(--s-8); }
.section-sub {
  margin-top: var(--s-2);
  font-size: var(--t-small); color: var(--txt-3);
  max-width: 62ch; line-height: var(--lh-snug);
}

/* The one place the accent is allowed to carry emphasis in a headline. */
.hero-head em { font-style: normal; color: var(--accent); }
.hero-head { max-width: 15ch; }

/* A card with a semantic rule down its left edge. Used only where the two
   cards mean opposite things and the reader benefits from telling them apart
   before reading either. */
.card-rule { border-left-width: 2px; }
.card-rule.is-good { border-left-color: color-mix(in srgb, var(--good) 55%, var(--line)); }
.card-rule.is-warn { border-left-color: color-mix(in srgb, var(--warn) 50%, var(--line)); }

/* ---------- author ---------- */
/* Two columns: who, then what. As one column the bio filled half the card's
   width and left the rest empty. */
.author-card {
  display: grid; gap: var(--s-5);
  grid-template-columns: minmax(0, 13rem) minmax(0, 1fr);
  align-items: start;
  /* Narrower than the page. At full width the bio ran out at its reading
     measure and left a third of the card empty; sizing the card to the
     content makes the two columns fill it. */
  width: min(100%, 58rem);
  margin-top: var(--s-8);
  padding: var(--s-5);
}
@media (max-width: 760px) { .author-card { grid-template-columns: 1fr; gap: var(--s-4); } }
.author-card .author-head { flex-direction: column; align-items: flex-start; gap: var(--s-3); }
.author-card .author-mark { width: 2.9rem; height: 2.9rem; font-size: var(--t-small); }
.author-body { display: flex; flex-direction: column; gap: var(--s-3); }
.author-body p { max-width: 62ch; }
