/* ==========================================================================
   PersuaRL project page — formal typeset layout.
   Self-contained: no Bulma, no framework. Edit variables below to retheme.
   ========================================================================== */

:root {
  --ink:        #16181c;
  --ink-soft:   #3d434d;
  --muted:      #6b7280;
  --rule:       #d9d5cd;
  --rule-soft:  #e8e5df;
  --paper:      #fdfcfa;
  --panel:      #f6f4f0;
  --accent:     #1f3a5f;
  --accent-dim: #7d8ba0;

  /* secondary hues, used only as tints behind icons and in the top ribbon —
     enough colour to break up the cream, not enough to fight the navy */
  --tint-blue:   #e6edf7;
  --tint-green:  #e4f0e8;
  --tint-amber:  #f8efdd;
  --tint-violet: #eee9f6;
  --hue-green:   #2f6f5f;
  --hue-amber:   #b8862f;
  --hue-violet:  #6b53a3;

  --serif: "Source Serif 4", "Source Serif Pro", Charter, "Iowan Old Style",
           Georgia, "Times New Roman", serif;
  --sans:  "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
           Helvetica, Arial, sans-serif;
  --mono:  "IBM Plex Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo,
           Consolas, monospace;

  /* One content column for the whole page: text, rules, figures, tables and
     captions all share the same left and right edge. */
  --measure: 48rem;

  /* rounded corners + soft elevation, so panels read as cards rather than
     hard-edged rectangles */
  --r-sm:   8px;
  --r-md:   12px;
  --r-pill: 999px;
  --shadow-sm: 0 1px 2px rgba(22, 24, 28, 0.04),
               0 2px 6px rgba(22, 24, 28, 0.05);
  --shadow-md: 0 1px 2px rgba(22, 24, 28, 0.04),
               0 6px 18px rgba(22, 24, 28, 0.07);
  --shadow-lift: 0 2px 4px rgba(31, 58, 95, 0.10),
                 0 10px 24px rgba(31, 58, 95, 0.14);
}

*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: 5rem;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 1.0625rem;
  /* the column is wide for this size, so the lines get extra leading to keep
     the eye from dropping a row on the return sweep */
  line-height: 1.78;
  font-variant-numeric: oldstyle-nums proportional-nums;
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid var(--accent-dim);
}
a:hover { border-bottom-color: var(--accent); background: rgba(31, 58, 95, 0.05); }

::selection { background: #dfe6ef; }

/* ----------------------------------------------------------- scroll reveal
   Blocks fade up as they enter the viewport, once each. The selector list
   below must stay in step with REVEAL in static/js/paper.js, which adds
   .is-visible. Two rules on purpose: the transition applies at all times, so
   dropping the hidden state animates rather than snaps — and because the
   hidden state is scoped with :not(.is-visible) there is no specificity
   fight with the element's own styles. */

html.js-anim :is(
  .paper-title, .byline, .affil, .tldr, .resources, .lead-figure,
  .section-head, .lead, .abstract, .highlight, .stat, .card, .tabs,
  .tab-panel > p, .tcap, .table-scroll, figure, .section .wrap > p,
  .bibtex-bar, .section pre, .colophon p
) {
  transition: opacity 0.55s ease, transform 0.55s cubic-bezier(0.22, 0.61, 0.36, 1);
}

html.js-anim :is(
  .paper-title, .byline, .affil, .tldr, .resources, .lead-figure,
  .section-head, .lead, .abstract, .highlight, .stat, .card, .tabs,
  .tab-panel > p, .tcap, .table-scroll, figure, .section .wrap > p,
  .bibtex-bar, .section pre, .colophon p
):not(.is-visible) {
  opacity: 0;
  transform: translateY(14px);
}

/* tiles in a row arrive left to right rather than all at once */
html.js-anim .cards .card:nth-child(2),
html.js-anim .stats .stat:nth-child(2),
html.js-anim .highlights .highlight:nth-child(2) { transition-delay: 0.07s; }
html.js-anim .cards .card:nth-child(3),
html.js-anim .stats .stat:nth-child(3),
html.js-anim .highlights .highlight:nth-child(3) { transition-delay: 0.14s; }
html.js-anim .cards .card:nth-child(4),
html.js-anim .stats .stat:nth-child(4) { transition-delay: 0.21s; }

@media (prefers-reduced-motion: reduce) {
  html.js-anim :is(
    .paper-title, .byline, .affil, .tldr, .resources, .lead-figure,
    .section-head, .lead, .abstract, .highlight, .stat, .card, .tabs,
    .tab-panel > p, .tcap, .table-scroll, figure, .section .wrap > p,
    .bibtex-bar, .section pre, .colophon p
  ) {
    opacity: 1;
    transform: none;
    transition: none;
    transition-delay: 0s;
  }
}

/* ---------------------------------------------------------------- masthead */

.masthead {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(253, 252, 250, 0.94);
  backdrop-filter: saturate(180%) blur(8px);
  border-bottom: 1px solid var(--rule-soft);
}

/* colour ribbon across the very top of the page */
.masthead::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--accent), var(--hue-green) 55%, var(--hue-amber));
}

.masthead-inner {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 0.6rem 1.5rem;
  display: flex;
  align-items: baseline;
  gap: 1.5rem;
}

/* The mark holds two labels in the same slot: the short name at the top of
   the page, the full paper title once the title block has scrolled away. */
.masthead-mark {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--sans);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--ink);
  border: 0;
}
.masthead-mark:hover { background: none; }

.mark-short,
.mark-full {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: opacity 0.25s ease, transform 0.25s ease;
}
.mark-short { letter-spacing: 0.08em; text-transform: uppercase; }

.mark-full {
  position: absolute;
  left: 0; right: 0; top: 0;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--ink-soft);
  opacity: 0;
  transform: translateY(4px);
  pointer-events: none;
}

.masthead.is-scrolled .mark-short { opacity: 0; transform: translateY(-4px); }
.masthead.is-scrolled .mark-full  { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .mark-short, .mark-full { transition: none; }
}

.masthead-nav {
  margin-left: auto;
  display: flex;
  gap: 1.25rem;
  overflow-x: auto;
  scrollbar-width: none;
}
.masthead-nav::-webkit-scrollbar { display: none; }

.masthead-nav a {
  font-family: var(--sans);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  border: 0;
  padding-bottom: 2px;
  white-space: nowrap;
}
.masthead-nav a:hover { color: var(--ink); background: none; box-shadow: inset 0 -1px 0 var(--ink); }
.masthead-nav a.is-active { color: var(--ink); box-shadow: inset 0 -1px 0 var(--ink); }

/* ------------------------------------------------- side contents rail
   Sits in the left margin on wide screens and marks the section being
   read. The sticky masthead nav covers narrower windows. */

.side-toc {
  position: fixed;
  top: 50%;
  left: 2rem;
  transform: translateY(-50%);
  width: 13rem;
  display: none;
  z-index: 30;
}

.side-toc a {
  display: flex;
  align-items: baseline;
  gap: 0.7rem;
  padding: 0.5rem 0;
  font-family: var(--sans);
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.4;
  color: var(--muted);
  border: 0;
  border-bottom: 1px solid transparent;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.side-toc a:hover { color: var(--ink); background: none; }

.side-toc .toc-num {
  flex: none;
  font-size: 0.75rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums lining-nums;
  color: var(--accent-dim);
}

.side-toc a.is-active { color: var(--ink); font-weight: 600; border-bottom-color: var(--accent); }
.side-toc a.is-active .toc-num { color: var(--accent); }

/* only where there is genuinely room beside the 58rem column — and where
   the rail is shown, the top bar drops its section links so the two are
   never duplicated */
@media (min-width: 1320px) and (min-height: 34rem) {
  .side-toc { display: block; }
  .masthead-nav { display: none; }

  /* leave the rail its margin: a broken-out figure stops short of it */
  figure { --fig-w: min(62rem, calc(100vw - 32rem)); }
}

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

.wrap {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 0 1.5rem;
}

/* ------------------------------------------------------------- title block */

.titleblock {
  padding: 4rem 0 2.75rem;
  border-bottom: 1px solid var(--rule);
  background: linear-gradient(180deg, #f7f4ee 0%, var(--paper) 62%);
}

/* venue reads as a badge rather than a line of grey caps */
.venue {
  display: inline-flex;
  align-items: center;
  font-family: var(--sans);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  background: rgba(31, 58, 95, 0.08);
  border-radius: var(--r-pill);
  padding: 0.4rem 0.85rem;
  margin: 0 0 1.5rem;
}
.venue span { color: var(--accent-dim); margin: 0 0.5rem; }

.paper-title {
  font-family: var(--serif);
  font-weight: 600;
  /* sized so the title settles into three balanced lines in the 45rem column */
  font-size: clamp(1.5rem, 0.95rem + 1.7vw, 2.2rem);
  line-height: 1.24;
  letter-spacing: -0.012em;
  margin: 0 0 1.75rem;
  max-width: 100%;      /* fills the content column */
  text-align: left;
  text-wrap: balance;
}
.paper-title em {
  font-style: normal;
}

.byline {
  font-family: var(--sans);
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.9;
  color: var(--ink);
  margin: 0 0 0.35rem;
  max-width: var(--measure);
}
.byline a { color: var(--ink); border-bottom-color: var(--rule); }
.byline a:hover { border-bottom-color: var(--ink); background: none; }
.byline sup { font-size: 0.72em; font-weight: 500; color: var(--accent-dim); }

.affil {
  font-family: var(--sans);
  font-size: 0.875rem;
  line-height: 1.75;
  color: var(--muted);
  margin: 0.5rem 0 0;
  max-width: var(--measure);
}
.affil sup { font-size: 0.75em; color: var(--accent-dim); }
.affil .note { font-size: 0.8125rem; font-style: italic; }

/* the line under a section heading follows the heading: centred, no justify */
.lead {
  max-width: 42rem;
  margin: 0 auto 0.5rem;
  text-align: center;
  font-size: 1.125rem;
  line-height: 1.62;
  color: var(--ink-soft);
}

/* one-sentence pitch directly under the authors */
.tldr {
  max-width: var(--measure);
  margin: 1.75rem 0 0;
  padding: 0.15rem 0 0.15rem 1.05rem;
  border-left: 4px solid var(--accent);
  font-size: 1.1875rem;
  line-height: 1.6;
  color: var(--ink);
}
.tldr b { color: var(--accent); }

/* ------------------------------------------------------------- highlights */

.highlights {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.8rem;
  max-width: var(--measure);
  margin: 2rem 0 0;
}

.highlight {
  background: #fff;
  border: 1px solid var(--rule-soft);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
  padding: 1.25rem 1.25rem 1.3rem;
  transition: box-shadow 0.18s ease, transform 0.18s ease;
}
.highlight:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }

.hl-num {
  display: block;
  font-family: var(--serif);
  font-size: 2.35rem;
  font-weight: 600;
  line-height: 1.05;
  color: var(--accent);
  font-variant-numeric: lining-nums;
}
.highlight:nth-child(2) .hl-num { color: var(--hue-green); }
.highlight:nth-child(3) .hl-num { color: var(--hue-amber); }

.highlight p {
  max-width: none;
  text-align: left;
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ink-soft);
  margin: 0.5rem 0 0;
}

/* a single result, called out of the table */
.pullquote {
  max-width: var(--measure);
  margin: 1.4rem 0;
  padding: 1rem 1.15rem;
  background: #fff;
  border: 1px solid var(--rule-soft);
  border-left: 3px solid var(--hue-green);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  box-shadow: var(--shadow-sm);
  font-size: 1.0625rem;
  line-height: 1.6;
  text-align: left;
  color: var(--ink);
}

/* ------------------------------------------------------------------- links */

.resources {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 2.25rem;
}

.resource {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.55rem 1.15rem;
  font-family: var(--sans);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--ink);
  background: linear-gradient(180deg, #fff, #f9f7f3);
  border: 1px solid var(--rule);
  border-radius: var(--r-pill);
  box-shadow: var(--shadow-sm);
  transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease,
              box-shadow 0.18s ease, transform 0.18s ease;
}
.resource:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  box-shadow: var(--shadow-lift);
  transform: translateY(-1px);
}
.resource:active { transform: translateY(0); box-shadow: var(--shadow-sm); }

/* the logo does the recognising, so give it room to be read */
.resource svg { width: 16px; height: 16px; flex: none; }

/* a resource whose link does not exist yet: still legible, plainly not
   clickable, and it never lights up on hover */
/* one filled button so the link row has a colour anchor */
.resource.is-primary {
  background: linear-gradient(180deg, #27476f, var(--accent));
  border-color: var(--accent);
  color: #fff;
  box-shadow: 0 2px 8px rgba(31, 58, 95, 0.30);
}
.resource.is-primary:hover {
  background: #162944;
  border-color: #162944;
  color: #fff;
}

.resource.is-pending {
  color: var(--muted);
  background: transparent;
  border-style: dashed;
  border-color: var(--rule);
  box-shadow: none;
  cursor: default;
}
.resource.is-pending:hover,
.resource.is-pending:active {
  background: transparent;
  border-color: var(--rule);
  color: var(--muted);
  box-shadow: none;
  transform: none;
}

.resource .soon {
  font-size: 0.625rem;
  font-style: normal;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent-dim);
  padding: 0.1rem 0.4rem;
  border: 1px solid var(--rule-soft);
  border-radius: var(--r-pill);
}

@media (prefers-reduced-motion: reduce) {
  .resource, .resource:hover, .resource:active { transform: none; }
}

/* ------------------------------------------------------------------ figure */

/* Figures break out of the text column — a diagram earns more width than a
   line of prose does. Centring is done with margin arithmetic rather than a
   transform, because .is-visible animates transform and would cancel it:
   the column's content box is 100%, so the overhang is half the difference. */
figure {
  --fig-w: min(62rem, calc(100vw - 3rem));
  width: var(--fig-w);
  max-width: none;
  margin: 2.75rem 0;
  margin-left: calc((100% - var(--fig-w)) / 2);
}
figure img {
  display: block;
  width: 100%;
  height: auto;
  padding: 0.75rem;
  border: 1px solid var(--rule-soft);
  border-radius: var(--r-md);
  background: #fff;
  box-shadow: var(--shadow-md);
}
figcaption {
  font-family: var(--sans);
  font-size: 0.875rem;
  line-height: 1.65;
  color: var(--muted);
  margin: 0.95rem auto 0;
  padding-left: 0.9rem;
  border-left: 2px solid var(--rule);
  max-width: 46rem;   /* the picture may be wide; its caption should not be */
}
figcaption b, .tcap b { color: var(--ink-soft); }

/* keeps the break-out margin-left from the rule above */
.lead-figure { margin-top: 3.25rem; margin-bottom: 0; }

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

.section {
  padding: 4.5rem 0;
  border-bottom: 1px solid var(--rule-soft);
}
.section:last-of-type { border-bottom: 0; }
.section.tinted {
  background: linear-gradient(180deg, #f8f6f2 0%, var(--panel) 45%, #f3f0ea 100%);
  border-bottom-color: var(--rule);
}

/* Section openings are centred and set large, so each one reads as a fresh
   chapter rather than a run-on of the previous section. */
.section-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.7rem;
  margin: 0 0 2rem;
  max-width: var(--measure);
  text-align: center;
}
.section-head::after {
  content: "";
  width: 4.5rem;
  height: 4px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--accent), var(--hue-green));
}

.section-num {
  font-family: var(--sans);
  font-size: 0.875rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  color: #fff;
  background: var(--accent);
  border-radius: var(--r-pill);
  padding: 0.35rem 1rem;
  box-shadow: 0 2px 6px rgba(31, 58, 95, 0.22);
  flex: none;
}

h2.section-title {
  font-family: var(--serif);
  font-size: clamp(1.8rem, 1.15rem + 1.9vw, 2.5rem);
  font-weight: 600;
  line-height: 1.16;
  letter-spacing: -0.012em;
  text-transform: none;
  margin: 0;
}

/* ------------------------------------------------------------------ cards
   Stage cards: one per step of the method, two to a row. */

/* square tiles. `aspect-ratio` cannot do this: on a grid item it suppresses
   stretch alignment, so the tiles stop matching each other. Instead the rows
   are 1fr (every tile the same height) and, once the column is at full width,
   a min-height equal to the computed column width squares them off:
   (48rem measure - 3rem padding - 1.1rem gap) / 2. */
.cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: 1fr;
  gap: 1.1rem;
  max-width: var(--measure);
  margin: 1.9rem 0 0;
}

/* each tile carries one hue: a stripe across its head, the icon tile behind
   the emoji, its step number, and the glow it lifts into on hover */
.cards .card:nth-child(1) { --card-hue: var(--accent);       --card-tint: var(--tint-blue); }
.cards .card:nth-child(2) { --card-hue: var(--hue-green);    --card-tint: var(--tint-green); }
.cards .card:nth-child(3) { --card-hue: var(--hue-amber);    --card-tint: var(--tint-amber); }
.cards .card:nth-child(4) { --card-hue: var(--hue-violet);   --card-tint: var(--tint-violet); }

.card {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  background: linear-gradient(180deg, #ffffff 0%, #fdfcfa 100%);
  border: 1px solid var(--rule-soft);
  border-radius: 16px;
  box-shadow: var(--shadow-sm);
  padding: 1.45rem 1.5rem 1.35rem;
  transition: box-shadow 0.2s ease, transform 0.2s ease, border-color 0.2s ease;
}

/* the hue stripe across the top edge */
.card::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 4px;
  background: var(--card-hue);
  opacity: 0.9;
}

.card:hover {
  /* plain values first, so a browser without color-mix() still gets a hover */
  border-color: var(--rule);
  box-shadow: var(--shadow-md);
  border-color: color-mix(in srgb, var(--card-hue) 35%, var(--rule));
  box-shadow: 0 2px 4px rgba(22, 24, 28, 0.05),
              0 14px 28px color-mix(in srgb, var(--card-hue) 16%, transparent);
  transform: translateY(-3px);
}

/* the emoji sits on a tinted tile, ringed in its own hue */
.card-icon {
  display: grid;
  place-items: center;
  width: 2.9rem;
  height: 2.9rem;
  font-size: 1.5rem;
  line-height: 1;
  border-radius: 13px;
  margin-bottom: 0.6rem;
  background: var(--card-tint);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--card-hue) 22%, transparent),
              0 2px 6px color-mix(in srgb, var(--card-hue) 14%, transparent);
}

@media (prefers-reduced-motion: reduce) {
  .card, .card:hover { transform: none; transition: none; }
}

.card h3 {
  font-family: var(--sans);
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--accent);
  margin: 0 0 0.6rem;
}
.card h3 .num { color: var(--card-hue); margin-right: 0.2rem; opacity: 0.85; }

/* inside a card the column is narrow: ragged right beats justified */
.card p,
.card ul {
  max-width: none;
  text-align: left;
  font-size: 0.9375rem;
  line-height: 1.56;
  margin: 0 0 0.7rem;
}
.card p:last-child, .card ul:last-child { margin-bottom: 0; }

/* term — description lines, no bullet */
.card ul.kv li { padding-left: 0; margin-bottom: 0.35rem; }
.card ul.kv li::before { content: none; }
.card ul.kv li:last-child { margin-bottom: 0; }

/* the closing note sits on the floor of the tile */
/* only where the content column has reached its full 48rem: below that the
   tiles are narrower, and a fixed height would make them portrait */
@media (min-width: 51rem) {
  .card { min-height: 21.95rem; }
}

.card-note {
  margin-top: auto;
  background: var(--panel);
  background: color-mix(in srgb, var(--card-tint) 55%, #fff);
  border-left: 3px solid var(--card-hue);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  padding: 0.65rem 0.85rem;
  font-size: 0.875rem;
  color: var(--ink-soft);
}

/* ------------------------------------------------------------------ stats
   Headline numbers for the dataset, so the section leads with something
   other than a wall of prose. */

.stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.8rem;
  max-width: var(--measure);
  margin: 1.75rem 0 2rem;
}

.stat {
  background: #fff;
  border: 1px solid var(--rule-soft);
  border-top: 3px solid var(--accent);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-sm);
  padding: 1.1rem 0.6rem 1rem;
  text-align: center;
  transition: box-shadow 0.18s ease, transform 0.18s ease;
}
.stat:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.stat:nth-child(2) { border-top-color: var(--hue-green); }
.stat:nth-child(3) { border-top-color: var(--hue-amber); }
.stat:nth-child(4) { border-top-color: var(--accent-dim); }

.stat-num {
  display: block;
  font-family: var(--serif);
  font-size: 2.1rem;
  font-weight: 600;
  line-height: 1.1;
  color: var(--ink);
  font-variant-numeric: lining-nums;
}
.stat-label {
  display: block;
  margin-top: 0.35rem;
  font-family: var(--sans);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ------------------------------------------------------------------- tabs
   Switches between panels of one section (used in Results). Without JS the
   first panel stays open and the rest keep their `hidden` attribute. */

.tabs {
  display: flex;
  gap: 1.9rem;
  max-width: var(--measure);
  margin: 0 0 1.6rem;
  border-bottom: 1px solid var(--rule);
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }

.tab {
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  padding: 0.55rem 0.1rem 0.7rem;
  font-family: var(--sans);
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--muted);
  white-space: nowrap;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.tab:hover { color: var(--ink); }
.tab.is-active { color: var(--accent); border-bottom-color: var(--accent); border-bottom-width: 3px; }
.tab:focus-visible { outline: 2px solid var(--accent-dim); outline-offset: 3px; }

.tab-panel[hidden] { display: none; }

h3 {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 1.25rem;
  line-height: 1.4;
  letter-spacing: -0.005em;
  margin: 2.5rem 0 0.75rem;
}
h3:first-child { margin-top: 0; }

/* Running prose is justified so both edges of the column are flush, as in a
   typeset paper. Hyphenation is required with it: without word breaks the
   browser stretches word spacing and opens rivers of white down the column.
   The limits stop short words breaking and cap consecutive hyphenated lines. */
p, ul li, figcaption {
  text-align: justify;
  -webkit-hyphens: auto;
          hyphens: auto;
  hyphenate-limit-chars: 7 4 3;
  hyphenate-limit-lines: 2;
}

/* Metadata and single-line notes stay ragged right — justifying a two- or
   three-line block just spaces it oddly. */
.venue, .byline, .affil, .colophon p, .tcap {
  text-align: left;
  -webkit-hyphens: manual;
          hyphens: manual;
}

p { margin: 0 0 1.15rem; max-width: var(--measure); }
p:last-child { margin-bottom: 0; }

/* Body copy sets flush on both edges, the way the paper itself is typeset.
   Headings, bylines and table cells are left out on purpose. */
.abstract p,
.section p,
.section ul li,
figcaption,
.tcap,
.colophon p {
  text-align: justify;
  text-justify: inter-word;
}

/* …and the pieces that opt out of it. These must come after the rule above:
   a card or tile is too narrow to justify without opening word gaps. */
.card p,
.card ul,
.highlight p,
p.pullquote,
p.card-note { text-align: left; }
p.lead { text-align: center; }

.abstract p {
  font-size: 1.125rem;
  line-height: 1.82;
}
.abstract p::first-line { font-variant-caps: normal; }

ul {
  max-width: var(--measure);
  margin: 0 0 1.15rem;
  padding-left: 0;
  list-style: none;
}
ul li {
  position: relative;
  padding-left: 1.35rem;
  margin-bottom: 0.6rem;
}
ul li::before {
  content: "";
  position: absolute;
  left: 0.15rem;
  top: 0.78em;
  width: 5px;
  height: 1px;
  background: var(--accent-dim);
}

b, strong { font-weight: 600; }

/* ----------------------------------------------------------------- figures
   Small inline math-ish italics keep the serif face. */
i, em { font-style: italic; }
sub, sup { line-height: 0; }

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

/* legend chip in a table caption: a green swatch, then the words */
.key-ours {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--hue-green);
  font-weight: 500;
}
.key-ours::before {
  content: "";
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 3px;
  background: rgba(47, 111, 95, 0.18);
  border: 1px solid rgba(47, 111, 95, 0.45);
  box-shadow: inset 2px 0 0 var(--hue-green);
}

.tcap {
  font-family: var(--sans);
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--muted);
  max-width: var(--measure);
  margin: 2.25rem 0 0.75rem;
}

/* Ruled grid rather than open booktabs: with this many numeric columns the
   vertical rules are what let a reader track a value back to its heading. */
.table-scroll {
  overflow-x: auto;
  max-width: var(--measure);
  margin-bottom: 1.5rem;
  background: #fff;
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
}

table {
  border-collapse: collapse;
  width: 100%;
  font-family: var(--sans);
  font-size: 0.875rem;
  font-variant-numeric: tabular-nums lining-nums;
  white-space: nowrap;
}

/* headings carry the metric name in full, so they wrap onto two lines and
   sit on the baseline of the tallest one */
thead th {
  text-align: center;
  vertical-align: bottom;
  white-space: normal;
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  -webkit-hyphens: auto;
  hyphens: auto;
  color: var(--ink-soft);
  background: linear-gradient(180deg, #faf8f4, #f1eee8);
  padding: 0.75rem 0.5rem 0.6rem;
  border-right: 1px solid var(--rule-soft);
  border-bottom: 2px solid var(--accent);
}
thead th:first-child { text-align: left; color: var(--ink); }
thead th:last-child { border-right: 0; }

tbody td {
  text-align: center;
  padding: 0.5rem 0.5rem;
  border-right: 1px solid var(--rule-soft);
  border-bottom: 1px solid var(--rule-soft);
  color: var(--ink-soft);
}
tbody td:last-child { border-right: 0; }
tbody tr:last-child td { border-bottom: 0; }

/* the widest headings (PERSUASIVE EFFECTIVENESS, STRATEGY APPROPRIATENESS)
   set the column widths in Table 3, so the model column takes what is left
   rather than claiming a fixed slice and pushing the table into a scroll */
tbody td:first-child {
  text-align: left;
  color: var(--ink);
  white-space: normal;
  min-width: 9.5rem;
}

tbody td b { color: var(--ink); }

/* banding: at this row count the eye needs help staying on one line */
tbody tr:nth-child(even) td { background: rgba(22, 24, 28, 0.022); }

/* our own systems: green across the row, so they are findable at a glance */
tbody tr.is-ours td {
  background: rgba(47, 111, 95, 0.11);
  border-top: 1px solid rgba(47, 111, 95, 0.28);
  border-bottom: 1px solid rgba(47, 111, 95, 0.28);
  color: var(--ink);
  font-weight: 500;
}
tbody tr.is-ours td:first-child { box-shadow: inset 4px 0 0 var(--hue-green); }
tbody tr.is-ours td b { color: var(--hue-green); }

/* group heading row: <td colspan> */
tbody td[colspan] {
  text-align: left;
  background: rgba(31, 58, 95, 0.045);
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-size: 0.75rem;
  color: var(--accent);
  padding: 0.55rem 0.8rem;
}

tbody tr:hover td { background: rgba(31, 58, 95, 0.04); }
tbody tr.is-ours:hover td { background: rgba(47, 111, 95, 0.17); }
tbody tr:hover td[colspan] { background: rgba(31, 58, 95, 0.045); }

/* ----------------------------------------------------------------- bibtex */

.bibtex-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  max-width: var(--measure);
}

.copy-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: var(--r-pill);
  box-shadow: var(--shadow-sm);
  padding: 0.42rem 0.95rem;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease,
              box-shadow 0.15s ease;
}
.copy-btn:hover { background: var(--ink); border-color: var(--ink); color: #fff; }
.copy-btn.copied { background: var(--accent); border-color: var(--accent); color: #fff; }
.copy-btn svg { width: 13px; height: 13px; }

pre {
  max-width: var(--measure);
  overflow-x: auto;
  margin: 0;
  padding: 1.25rem 1.4rem;
  background: var(--panel);
  border: 1px solid var(--rule-soft);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
}
code {
  font-family: var(--mono);
  font-size: 0.8125rem;
  line-height: 1.7;
  color: var(--ink-soft);
}

/* ----------------------------------------------------------------- footer */

.colophon {
  border-top: 1px solid var(--rule);
  padding: 2.5rem 0 3.5rem;
  font-family: var(--sans);
  font-size: 0.8125rem;
  line-height: 1.75;
  color: var(--muted);
}
.colophon a { color: var(--ink-soft); border-bottom-color: var(--rule); }
.colophon a:hover { color: var(--accent); background: none; }
.colophon p { max-width: var(--measure); }

/* --------------------------------------------------------------- to-top */

.to-top {
  position: fixed;
  right: 1.5rem;
  bottom: 1.5rem;
  width: 2.6rem;
  height: 2.6rem;
  display: grid;
  place-items: center;
  background: var(--paper);
  color: var(--ink-soft);
  border: 1px solid var(--rule);
  border-radius: var(--r-pill);
  box-shadow: var(--shadow-md);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
  z-index: 40;
}
.to-top.visible { opacity: 1; visibility: visible; transform: none; }
.to-top:hover { border-color: var(--ink); color: var(--ink); }
.to-top svg { width: 14px; height: 14px; }

/* --------------------------------------------------------------- responsive */

@media (max-width: 720px) {
  body { font-size: 1rem; line-height: 1.68; }
  .titleblock { padding: 2.75rem 0 2rem; }
  .section { padding: 2.5rem 0; }
  .abstract p { font-size: 1.0625rem; }
  .stat-num { font-size: 1.75rem; }
  .hl-num { font-size: 2rem; }
  .lead { font-size: 1.0625rem; }
  .tab { font-size: 0.9375rem; }
  figcaption { padding-left: 0.75rem; }
  .cards { grid-template-columns: 1fr; gap: 0.9rem; }
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .highlights { grid-template-columns: 1fr; }
  .tldr { font-size: 1.0625rem; }

  /* the column gets too narrow for gap-free justification */
  .abstract p,
  .section p,
  .section ul li,
  figcaption,
  .tcap,
  .colophon p {
    -webkit-hyphens: auto;
    hyphens: auto;
  }

  /* too little room for the full title beside the section links */
  .mark-full { display: none; }
  .masthead.is-scrolled .mark-short { opacity: 1; transform: none; }
  .masthead-mark { flex: 0 1 auto; }
}

@media print {
  .masthead, .to-top, .resources, .side-toc { display: none; }
  body { background: #fff; font-size: 10.5pt; }
  .section, .section.tinted { background: #fff; padding: 1.2rem 0; break-inside: avoid; }
  a { color: inherit; border: 0; }
  figure img, .table-scroll, pre { box-shadow: none; }
}
