/* Shared design tokens and layout for the EDPY 506 notes site.
   The design is reused from the Computational Memory Lab classifier primer:
   colours come from a validated data-viz palette, and the categorical slots
   are used in a fixed order so a series keeps its colour across every chart. */

:root {
  color-scheme: light;

  --surface-1: #fcfcfb;
  --page: #f9f9f7;
  --raised: #ffffff;
  --text-primary: #0b0b0b;
  --text-secondary: #52514e;
  --text-muted: #898781;
  --gridline: #e1e0d9;
  --baseline: #c3c2b7;
  --border: rgba(11, 11, 11, 0.10);
  --border-strong: rgba(11, 11, 11, 0.18);

  /* categorical slots, fixed order */
  --series-1: #2a78d6;  /* blue    */
  --series-2: #008300;  /* green   */
  --series-3: #e87ba4;  /* magenta */
  --series-4: #eda100;  /* yellow  */
  --series-5: #1baf7a;  /* aqua    */
  --series-6: #eb6834;  /* orange  */
  --series-7: #4a3aa7;  /* violet  */
  --series-8: #e34948;  /* red     */

  /* the two data roles that recur on every page keep these colours everywhere */
  --c-train: var(--series-1);
  --c-test: var(--series-8);
  --c-fit: var(--series-6);

  --good: #0ca30c;
  --warning: #fab219;
  --critical: #d03b3b;

  --accent: #2a78d6;
  --accent-wash: rgba(42, 120, 214, 0.09);

  --radius: 10px;
  --radius-sm: 6px;
  --measure: 34rem;
  --sans: system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    color-scheme: dark;
    --surface-1: #1a1a19;
    --page: #0d0d0d;
    --raised: #202020;
    --text-primary: #ffffff;
    --text-secondary: #c3c2b7;
    --text-muted: #898781;
    --gridline: #2c2c2a;
    --baseline: #383835;
    --border: rgba(255, 255, 255, 0.10);
    --border-strong: rgba(255, 255, 255, 0.20);

    --series-1: #3987e5;
    --series-2: #008300;
    --series-3: #d55181;
    --series-4: #c98500;
    --series-5: #199e70;
    --series-6: #d95926;
    --series-7: #9085e9;
    --series-8: #e66767;

    --accent: #3987e5;
    --accent-wash: rgba(57, 135, 229, 0.16);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --surface-1: #1a1a19;
  --page: #0d0d0d;
  --raised: #202020;
  --text-primary: #ffffff;
  --text-secondary: #c3c2b7;
  --text-muted: #898781;
  --gridline: #2c2c2a;
  --baseline: #383835;
  --border: rgba(255, 255, 255, 0.10);
  --border-strong: rgba(255, 255, 255, 0.20);

  --series-1: #3987e5;
  --series-2: #008300;
  --series-3: #d55181;
  --series-4: #c98500;
  --series-5: #199e70;
  --series-6: #d95926;
  --series-7: #9085e9;
  --series-8: #e66767;

  --accent: #3987e5;
  --accent-wash: rgba(57, 135, 229, 0.16);
}

* { box-sizing: border-box; }

/* Everything below is sized in rem, so this one number is the page's zoom.
   115% of the 16px browser default. Charts scale too: their SVG viewBox
   stretches to a container whose width is set in rem. */
html { font-size: 115%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

body {
  margin: 0;
  background: var(--page);
  color: var(--text-primary);
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

/* ---------- top bar ---------- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.6rem max(1rem, 50vw - 33rem);
  background: color-mix(in srgb, var(--page) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}

.topbar__home {
  font-weight: 620;
  font-size: 0.9rem;
  color: var(--text-primary);
  text-decoration: none;
  white-space: nowrap;
}
.topbar__home span { color: var(--text-muted); font-weight: 400; }

.topbar__spacer { flex: 1; }

.topbar__nav {
  display: flex;
  gap: 0.1rem;
  overflow-x: auto;
  scrollbar-width: none;
  /* Without this a flex item refuses to shrink below its content width, so the
     nav would push the whole page wider than the viewport on a phone. */
  min-width: 0;
}
.topbar__nav::-webkit-scrollbar { display: none; }

.topbar__nav a {
  /* Trimmed sides so a full term of lecture tabs fits the bar at 1280 wide;
     the nav keeps min-width:0 so it can still scroll on a phone. */
  padding: 0.25rem 0.38rem;
  border-radius: var(--radius-sm);
  font-size: 0.82rem;
  color: var(--text-secondary);
  text-decoration: none;
  white-space: nowrap;
}
.topbar__nav a:hover { background: var(--border); color: var(--text-primary); }
.topbar__nav a[aria-current="page"] { background: var(--accent-wash); color: var(--accent); font-weight: 600; }

.theme-toggle {
  flex: none;
  width: 30px; height: 30px;
  display: grid; place-items: center;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-1);
  color: var(--text-secondary);
  cursor: pointer;
  font-size: 0.85rem;
}
.theme-toggle:hover { color: var(--text-primary); border-color: var(--border-strong); }

/* ---------- layout ---------- */

.wrap { max-width: 66rem; margin: 0 auto; padding: 0 1rem; }

main { padding-bottom: 6rem; }

.prose { max-width: var(--measure); margin-inline: auto; }
.prose > * + * { margin-top: 1.05em; }

h1, h2, h3 { line-height: 1.22; letter-spacing: -0.015em; margin: 0; }
h1 { font-size: clamp(2rem, 5vw, 2.9rem); font-weight: 680; }
h2 { font-size: clamp(1.4rem, 3vw, 1.75rem); font-weight: 650; }
h3 { font-size: 1.08rem; font-weight: 640; }

p { margin: 0; }
a { color: var(--accent); text-underline-offset: 2px; }

.lede { font-size: 1.18rem; line-height: 1.55; color: var(--text-secondary); }

.eyebrow {
  font-size: 0.72rem;
  font-weight: 660;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-muted);
}

section.chapter { margin-top: 3.5rem; }
section.chapter > .prose > h2 { margin-bottom: 0.2rem; }

hr.rule { border: 0; border-top: 1px solid var(--border); margin: 3rem 0; }

/* Side-by-side figure panels that collapse to one column on narrow screens. */
.split { display: grid; gap: 1.2rem; align-items: start; }
/* A grid item's default min-width is auto, meaning it refuses to shrink below
   its content. A wide table inside one therefore pushes the whole page wider
   than the viewport instead of letting its own .table-scroll scroll. */
.split > * { min-width: 0; }
.split--wide-left { grid-template-columns: 1.35fr 1fr; }
.split--controls { grid-template-columns: 1fr 17rem; }
.split--roc { grid-template-columns: 1.55fr 1fr; }
.split--three { grid-template-columns: repeat(3, 1fr); }
.split--even { grid-template-columns: 1fr 1fr; }
@media (max-width: 820px) {
  .split { grid-template-columns: 1fr; }
}

/* ---------- reusable blocks ---------- */

.card {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.1rem 1.2rem;
}

.figure {
  margin: 1.8rem auto;
  max-width: 52rem;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.1rem;
}
.figure--wide { max-width: 62rem; }
.figure__title { font-weight: 640; font-size: 0.95rem; margin-bottom: 0.15rem; }
.figure__sub { font-size: 0.85rem; color: var(--text-secondary); margin-bottom: 0.9rem; }
.figure__note { font-size: 0.8rem; color: var(--text-muted); margin-top: 0.85rem; line-height: 1.5; }

.callout {
  border-left: 3px solid var(--accent);
  background: var(--accent-wash);
  padding: 0.85rem 1rem;
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  font-size: 0.94rem;
}
.callout strong { font-weight: 640; }
/* Paragraph spacing comes from `.prose > * + *`, which only reaches direct
   children of .prose -- so a callout or keypoint holding more than one
   paragraph runs them together. Restore it inside the boxes themselves. */
.callout > * + *, .keypoint > * + * { margin-top: 0.75em; }
.callout--warn { border-left-color: var(--warning); background: color-mix(in srgb, var(--warning) 10%, transparent); }

.keypoint {
  border: 1px solid var(--border);
  border-left: 3px solid var(--good);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: var(--surface-1);
  padding: 0.85rem 1rem;
  font-size: 0.94rem;
}

/* ---------- controls ---------- */

.controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.55rem;
  margin-bottom: 0.95rem;
}

.btn {
  font: inherit;
  font-size: 0.85rem;
  font-weight: 560;
  padding: 0.34rem 0.75rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--surface-1);
  color: var(--text-primary);
  cursor: pointer;
}
.btn:hover { border-color: var(--accent); color: var(--accent); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn--primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn--primary:hover { filter: brightness(1.08); color: #fff; }
.btn--small { font-size: 0.78rem; padding: 0.25rem 0.55rem; }

.segmented {
  display: inline-flex;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.segmented button {
  font: inherit;
  font-size: 0.82rem;
  padding: 0.3rem 0.7rem;
  border: 0;
  border-right: 1px solid var(--border-strong);
  background: var(--surface-1);
  color: var(--text-secondary);
  cursor: pointer;
}
.segmented button:last-child { border-right: 0; }
.segmented button:hover { color: var(--text-primary); }
/* No weight change on selection: bold is wider, so the pressed button would grow
   and shove its neighbours sideways every time it was clicked. The accent fill
   carries the state on its own. */
.segmented button[aria-pressed="true"] { background: var(--accent); color: #fff; }

.field { display: inline-flex; align-items: center; gap: 0.45rem; font-size: 0.82rem; color: var(--text-secondary); }
/* A flex container makes every child a flex item, which strips <sub> and <sup>
   of their vertical offset and drops them onto the baseline. Keeping the label
   text in one inline box restores normal inline layout inside it. */
.field > .field__name { display: inline-block; }
.field input[type="range"] { width: 150px; accent-color: var(--accent); }
.field select {
  font: inherit; font-size: 0.82rem;
  padding: 0.25rem 0.4rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--surface-1);
  color: var(--text-primary);
}
.field output { font-variant-numeric: tabular-nums; color: var(--text-primary); font-weight: 600; min-width: 3.2em; }

/* ---------- legend ---------- */

.legend { display: flex; flex-wrap: wrap; gap: 0.9rem; font-size: 0.8rem; color: var(--text-secondary); }
.legend__item { display: inline-flex; align-items: center; gap: 0.35rem; }
.legend__swatch { width: 11px; height: 11px; border-radius: 3px; flex: none; }
.legend__swatch--line { height: 3px; width: 14px; border-radius: 2px; }
.legend__swatch--dot { border-radius: 50%; }

/* ---------- stat tiles ---------- */

/* minmax(9rem, …) alone sets a floor the column cannot go under, so three
   tiles overflow a phone. min(9rem, 100%) keeps the floor on a wide screen and
   drops it on a narrow one. The fixed-count modifiers below collapse for the
   same reason, and they are classes rather than inline styles because an
   inline grid-template-columns would win against the media query. */
.stats { display: grid; gap: 0.7rem; grid-template-columns: repeat(auto-fit, minmax(min(9rem, 100%), 1fr)); }
.stats--1 { grid-template-columns: 1fr; }
.stats--2 { grid-template-columns: 1fr 1fr; }
.stats--3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 620px) {
  .stats--2, .stats--3 { grid-template-columns: 1fr; }
}
.stat {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.8rem 0.9rem;
  min-width: 0;
  overflow-wrap: anywhere;
}
.stat__value { font-size: 1.7rem; font-weight: 660; letter-spacing: -0.02em; line-height: 1.1; font-variant-numeric: tabular-nums; }
.stat__label { font-size: 0.76rem; color: var(--text-muted); margin-top: 0.15rem; }
.stat--train .stat__value { color: var(--c-train); }
.stat--test .stat__value { color: var(--c-test); }
.stat--muted .stat__value { color: var(--text-muted); }

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

.table-scroll { overflow-x: auto; }
table.data {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
}
/* Numbers must not wrap, so nowrap is the default. Tables whose cells hold
   sentences need the --prose modifier or they get clipped instead of wrapping. */
table.data th, table.data td {
  text-align: right;
  padding: 0.42rem 0.6rem;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
  vertical-align: top;
}

table.data--prose th, table.data--prose td { white-space: normal; }
table.data--prose td { line-height: 1.5; }
table.data th:first-child, table.data td:first-child { text-align: left; }
table.data thead th {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  font-weight: 620;
  border-bottom: 1px solid var(--baseline);
}
table.data tbody tr:hover { background: var(--border); }
table.data tfoot td { border-bottom: 0; padding-top: 0.6rem; }
/* A table with a column per feature needs every column visible at once, so
   this modifier trims the padding rather than letting it scroll sideways. */
table.data--tight { font-size: 0.78rem; }
table.data--tight th, table.data--tight td { padding: 0.34rem 0.4rem; }
table.data td.num { font-weight: 560; }
table.data td.zero { color: var(--text-muted); }

/* ---------- lecture cards on the index ---------- */

.cards { display: grid; gap: 0.85rem; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
.cards a {
  display: block;
  text-decoration: none;
  color: inherit;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem 1.1rem;
  transition: border-color 0.12s, transform 0.12s;
}
.cards a:hover { border-color: var(--accent); transform: translateY(-2px); }
.cards .n { font-size: 0.72rem; font-weight: 660; color: var(--accent); letter-spacing: 0.06em; }
.cards h3 { margin: 0.3rem 0 0.25rem; }
.cards p { font-size: 0.87rem; color: var(--text-secondary); line-height: 1.5; }

/* ---------- chapter footer nav ---------- */

.pager { display: flex; justify-content: space-between; gap: 1rem; margin-top: 4rem; }
.pager a {
  flex: 1;
  text-decoration: none;
  color: inherit;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.75rem 0.95rem;
  background: var(--surface-1);
}
.pager a:hover { border-color: var(--accent); }
.pager .dir { font-size: 0.72rem; color: var(--text-muted); }
.pager .ttl { font-weight: 600; font-size: 0.92rem; }
.pager .next { text-align: right; }

/* ---------- svg chart primitives ---------- */

/* A chart must never be taller than the screen it is read on.
   width:100% + a fixed viewBox locks the aspect ratio, so height follows width.
   Capping the height makes the SVG scale down and centre itself
   (preserveAspectRatio is xMidYMid meet), which is the one constraint that
   actually tracks the reader's screen rather than guessing at a pixel width. */
svg.chart {
  display: block;
  width: 100%;
  height: auto;
  max-height: min(42vh, 24rem);
  overflow: visible;
}

/* Tree diagrams are tall by nature and need more room than a wide chart. */
svg.chart--tall { max-height: min(70vh, 36rem); }
svg.chart .grid { stroke: var(--gridline); stroke-width: 1; }
svg.chart .axis { stroke: var(--baseline); stroke-width: 1; }
svg.chart .tick { fill: var(--text-muted); font-size: 10px; }
svg.chart .axis-label { fill: var(--text-secondary); font-size: 11px; }
svg.chart .series-line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
svg.chart .direct-label { font-size: 11px; font-weight: 600; }
svg.chart .annot { font-size: 11px; fill: var(--text-secondary); }

.tooltip {
  position: fixed;
  z-index: 60;
  pointer-events: none;
  background: var(--raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 0.4rem 0.55rem;
  font-size: 0.78rem;
  line-height: 1.45;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.16);
  opacity: 0;
  transition: opacity 0.1s;
  max-width: 16rem;
}
.tooltip[data-show] { opacity: 1; }
.tooltip b { font-weight: 640; }

/* ---------- misc ---------- */

code, .mono { font-family: var(--mono); font-size: 0.88em; }
code {
  background: var(--border);
  padding: 0.1em 0.35em;
  border-radius: 4px;
}
.muted { color: var(--text-muted); }
.small { font-size: 0.85rem; }
.nowrap { white-space: nowrap; }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

details.aside {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.6rem 0.85rem;
  background: var(--surface-1);
  font-size: 0.9rem;
}
details.aside summary { cursor: pointer; font-weight: 600; font-size: 0.87rem; color: var(--text-secondary); }
details.aside summary:hover { color: var(--accent); }
details.aside > *:not(summary) { margin-top: 0.7rem; }

.footer {
  border-top: 1px solid var(--border);
  margin-top: 5rem;
  padding: 1.6rem 0 3rem;
  font-size: 0.82rem;
  color: var(--text-muted);
}
.footer a { color: var(--text-secondary); }

/* ---------- dropdown menu in the topbar ---------- */
/* The <details> button sits in .topbar as a sibling of .topbar__nav; the panel
   itself is parented to <body> and positioned by JS. Two properties of this bar
   make anything else break -- see the long comment in site.js. */
.navmenu { position: relative; flex: none; }

.navmenu > summary {
  list-style: none;
  cursor: pointer;
  padding: 0.25rem 0.45rem 0.25rem 0.55rem;
  border-radius: var(--radius-sm);
  font-size: 0.82rem;
  color: var(--text-secondary);
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 0.35rem;
  user-select: none;
}
.navmenu > summary::-webkit-details-marker { display: none; }
.navmenu > summary::marker { content: ''; }
.navmenu > summary:hover { background: var(--border); color: var(--text-primary); }
.navmenu > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.navmenu[data-current] > summary { background: var(--accent-wash); color: var(--accent); font-weight: 600; }

/* Drawn with borders rather than set as the "▾" glyph, which rendered at about
   8px on this font stack however it was sized. */
.navmenu__caret {
  flex: none;
  width: 0; height: 0;
  font-size: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 6px solid currentColor;
  transition: transform 0.14s ease;
}
.navmenu[open] .navmenu__caret { transform: rotate(180deg); }

.navmenu__panel {
  position: fixed;
  top: 0; left: 0;
  display: none;
  z-index: 200;
  width: 19rem;
  max-width: calc(100vw - 1rem);
  padding: 0.3rem;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 10px 30px rgb(0 0 0 / 0.18);
  flex-direction: column;
  gap: 0.1rem;
}
.navmenu__panel[data-open] { display: flex; }
.navmenu__panel a {
  display: block;
  white-space: normal;
  padding: 0.5rem 0.55rem;
  border-radius: var(--radius-sm);
  text-decoration: none;
}
.navmenu__ttl { display: block; font-size: 0.85rem; color: var(--text-primary); font-weight: 560; }
.navmenu__sub { display: block; font-size: 0.76rem; color: var(--text-muted); line-height: 1.35; margin-top: 0.12rem; }
.navmenu__panel a:hover { background: var(--accent-wash); }
.navmenu__panel a:hover .navmenu__ttl { color: var(--accent); }
.navmenu__panel a[aria-current="page"] { background: var(--accent-wash); }
.navmenu__panel a[aria-current="page"] .navmenu__ttl { color: var(--accent); font-weight: 650; }

/* ---------- display formulas and step markers ---------- */
.formula {
  margin: 1.1rem 0;
  padding: 0.85rem 1rem;
  background: var(--accent-wash);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  text-align: center;
  font-size: 1.02rem;
  line-height: 1.7;
  overflow-x: auto;
}
.formula .lbl { display: block; margin-top: 0.4rem; font-size: 0.78rem; color: var(--text-muted); }
.formula--left { text-align: left; }
.formula .row { display: block; }
.formula .row + .row { margin-top: 0.35rem; }

/* Fractions and roots are built from HTML so no maths library is needed. */
.frac {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  vertical-align: middle;
  margin: 0 0.15em;
  line-height: 1.25;
  font-size: 0.95em;
}
.frac > span { display: block; padding: 0 0.3em; }
.frac > span:first-child { border-bottom: 1px solid currentColor; }
/* A radical in a DISPLAY formula is two boxes side by side: the sign, and a
   body carrying the bar as its top border. Putting the border on a span that
   merely wraps the radicand does not work once the radicand contains a
   fraction, because the fraction is taller than the line box and the bar ends
   up drawn through it. The body is inline-block, not flex: a flex container
   turns every child into a flex item, which strips the sub- and superscripts
   inside it of their inline layout and runs the symbols together. */
.radical { display: inline-flex; align-items: stretch; margin: 0 0.1em; vertical-align: middle; }
.radical__sign {
  display: flex;
  align-items: flex-end;
  font-size: 1.05em;
  line-height: 1;
  transform: scaleY(var(--radical-stretch, 1.3));
  transform-origin: bottom;
  margin-right: 0.02em;
}
.radical__body {
  display: inline-block;
  border-top: 1.2px solid currentColor;
  padding: 0.2em 0.3em 0 0.2em;
  white-space: nowrap;
}
/* A radicand as tall as a fraction needs a taller sign. */
.radical--tall { --radical-stretch: 2.2; }

/* In RUNNING PROSE the flex version is wrong: it inflates the line box and the
   paragraph's leading opens up around it. A radicand of one or two characters
   needs nothing more than an overline. */
.root { white-space: nowrap; }
.root__body { border-top: 1px solid currentColor; padding: 0.05em 0.12em 0 0.06em; }

.sum { font-size: 1.15em; vertical-align: -0.05em; }

.steplabel {
  display: inline-block;
  margin-right: 0.5rem;
  padding: 0.05rem 0.45rem;
  border-radius: 999px;
  background: var(--accent-wash);
  color: var(--accent);
  font-size: 0.72rem;
  font-weight: 700;
  vertical-align: 0.15em;
}


/* ---------- icon-style trait cards (advantages / limitations) ---------- */
.traits { display: grid; gap: 0.7rem; grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr)); }
.trait {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.85rem 0.9rem;
  font-size: 0.9rem;
  font-weight: 600;
  text-align: center;
}
.trait--good { border-top: 3px solid var(--good); }
.trait--bad { border-top: 3px solid var(--critical); }
.trait small { display: block; font-weight: 400; font-size: 0.78rem; color: var(--text-secondary); margin-top: 0.25rem; line-height: 1.4; }

/* ---------- chips (feature subsets, retained variables) ---------- */
.chips { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.chip {
  font-size: 0.78rem;
  padding: 0.18rem 0.55rem;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  color: var(--text-secondary);
  background: var(--surface-1);
  font-variant-numeric: tabular-nums;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.chip[data-on] { background: var(--accent); border-color: var(--accent); color: #fff; }
.chip[data-off] { opacity: 0.45; text-decoration: line-through; }

/* ---------- horizontal bar list (importance ranking) ---------- */
.bars { display: grid; gap: 0.45rem; }
.bars__row { display: grid; grid-template-columns: 9rem 1fr 5.5rem; gap: 0.6rem; align-items: center; font-size: 0.82rem; }
.bars__name { color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bars__track { height: 9px; background: var(--border); border-radius: 5px; overflow: hidden; }
.bars__fill { height: 100%; background: var(--accent); border-radius: 5px; width: 0; transition: width 0.4s ease; }
.bars__fill--pending { background: var(--baseline); }
.bars__val { text-align: right; font-variant-numeric: tabular-nums; color: var(--text-secondary); }
@media (max-width: 560px) { .bars__row { grid-template-columns: 6.5rem 1fr 4.5rem; } }

/* ---------- confusion matrix ---------- */
/* Rows are the actual class and columns the predicted one, which is the
   arrangement every metric formula assumes. Cells stretch to the row's height:
   centring them instead offsets any cell whose caption wraps to a second line
   against its neighbour, which is how the first version looked. Tint strength
   follows each cell's share of the total, so the grid reads as a heat map. */
.cm {
  display: grid;
  grid-template-columns: 1.6rem 6.2rem 1fr 1fr;
  grid-auto-rows: auto;
  gap: 0.35rem;
  align-items: stretch;
  font-variant-numeric: tabular-nums;
}
.cm__head {
  font-size: 0.7rem;
  font-weight: 660;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding-bottom: 0.15rem;
}
.cm__head--side {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  align-items: center;
  justify-content: center;
  padding: 0;
}
.cm__rowlab {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  justify-content: flex-end;
  text-align: right;
  line-height: 1.25;
  padding-right: 0.3rem;
}
.cm__collab {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text-secondary);
  text-align: center;
  padding-bottom: 0.1rem;
}
.cm__cell {
  --tint: var(--good);
  border-radius: var(--radius-sm);
  padding: 0.65rem 0.7rem 0.6rem;
  background: color-mix(in srgb, var(--tint) calc(var(--share, 0.2) * 38% + 6%), var(--surface-1));
  border: 1px solid color-mix(in srgb, var(--tint) 35%, transparent);
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 4.6rem;
}
.cm__cell--wrong { --tint: var(--critical); }
.cm__n { font-size: 1.55rem; font-weight: 680; line-height: 1.05; }
.cm__label { font-size: 0.76rem; font-weight: 640; margin-top: 0.15rem; }
.cm__sub { font-size: 0.7rem; color: var(--text-secondary); line-height: 1.3; }
@media (max-width: 560px) {
  .cm { grid-template-columns: 0 5rem 1fr 1fr; gap: 0.3rem; }
  .cm__head--side { visibility: hidden; }
}

/* ---------- the tuning workflow ---------- */
.wf { display: grid; grid-template-columns: repeat(5, 1fr); gap: 0.5rem; }
.wf__step {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-top: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  padding: 0.7rem 0.75rem;
  font-size: 0.86rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.wf__step small { color: var(--text-secondary); font-size: 0.76rem; line-height: 1.4; }
.wf__step .steplabel { align-self: flex-start; margin: 0 0 0.2rem; }
.wf__step--test { border-top-color: var(--series-6); background: color-mix(in srgb, var(--series-6) 7%, var(--surface-1)); }
.wf__bands { display: grid; grid-template-columns: 4fr 1fr; gap: 0.5rem; margin-top: 0.45rem; }
.wf__bands span {
  font-size: 0.7rem; font-weight: 660; letter-spacing: 0.06em; text-transform: uppercase;
  text-align: center; color: var(--text-muted); border-top: 2px solid var(--accent); padding-top: 0.25rem;
}
.wf__bands span:last-child { border-top-color: var(--series-6); }
@media (max-width: 720px) {
  .wf { grid-template-columns: 1fr; }
  .wf__bands { display: none; }
}

/* ---------- in-page section index ---------- */
.toc { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 1.2rem; }
.toc a {
  font-size: 0.78rem;
  padding: 0.22rem 0.6rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface-1);
  color: var(--text-secondary);
  text-decoration: none;
}
.toc a:hover { border-color: var(--accent); color: var(--accent); }
