/* ============================================================
   NB every width breakpoint below is `@media screen and (max-width: ...)`.
   Without `screen`, headless Chrome evaluates them against the window rather
   than the page box when printing, so every printed page came out in the
   mobile layout: one-column card grids on a landscape sheet, half of it empty.
   Scoped 27 August 2026. Do not add an unscoped width query.
   ============================================================ */
/* ============================================================
   iOi house stylesheet — the single source of truth.
   Neutral base (black/white core) + official iOi palette accents.
   Light and dark themes via [data-theme] on <html>.
   Change this file and every page that links it updates.
   ============================================================ */

:root {
  /* neutral tokens — LIGHT */
  --bg: #ffffff;
  --surface: #ffffff;
  --surface-2: #fafafa;
  --fill: #f0f0f0;
  --ink: #1a1a1a;
  --ink-soft: #3d3d3d;
  --muted: #767676;
  --line: #dcdcdc;
  --line-soft: #ececec;
  --link: #1a5fb4;
  --code-bg: #1e1e1e;
  --code-ink: #f2f2f2;

  /* official iOi palette (same in both themes) */
  --yellow: #FFCB05;
  --blue:   #00B3DF;
  --red:    #EF4124;
  --green:  #00AB8A;
  --purple: #6462AB;
  --orange: #F79225;
  --pink:   #F9BEC9;
  --sand:   #CFC9BC;
  --charcoal:#877C78;

  --radius: 8px;
  --maxw: 940px;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

[data-theme="dark"] {
  --bg: #15171a;
  --surface: #1c1f24;
  --surface-2: #22262c;
  --fill: #2a2f36;
  --ink: #eaeaea;
  --ink-soft: #c7ccd2;
  --muted: #9aa1a9;
  --line: #343a42;
  --line-soft: #2a2f36;
  --link: #6db3f2;
  --code-bg: #0e0f11;
  --code-ink: #eaeaea;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 72px; }
body {
  margin: 0; font-family: var(--font); font-size: 17px; color: var(--ink);
  background: var(--bg); line-height: 1.65; -webkit-font-smoothing: antialiased;
  transition: background .2s ease, color .2s ease;
}
h1, h2, h3, h4 { color: var(--ink); line-height: 1.25; }
p { color: var(--ink-soft); }
ul { color: var(--ink-soft); padding-left: 1.3em; }
ul li { margin: 6px 0; }
a { color: var(--link); }

/* theme toggle (injected by theme.js) */
.theme-toggle {
  position: fixed; top: 12px; right: 14px; z-index: 200;
  font: 600 .8rem/1 var(--font); color: var(--ink-soft);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 999px; padding: 7px 13px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
}
.theme-toggle:hover { border-color: var(--muted); }

/* top bar */
.topbar { position: sticky; top: 0; z-index: 50; background: var(--bg); border-bottom: 1px solid var(--line); }
.topbar__inner { max-width: var(--maxw); margin: 0 auto; padding: 13px 24px; display: flex; align-items: baseline; gap: 12px; }
.topbar__brand, .topbar__title { font-weight: 700; font-size: .98rem; color: var(--ink); }
.topbar__sub { font-size: .82rem; color: var(--muted); }
.topbar__icon { width: 22px; height: 22px; object-fit: contain; display: block; flex: none; align-self: center; }

/* hero */
.hero { max-width: var(--maxw); margin: 0 auto; padding: 52px 24px 8px; }
.hero h1 { font-size: 2.3rem; margin: 0 0 8px; font-weight: 700; letter-spacing: -.01em; }
.hero h1 .rule { display: block; width: 56px; height: 5px; border-radius: 3px; background: var(--red); margin: 16px 0 0; }
.hero p.lede { font-size: 1.14rem; color: var(--ink-soft); margin: 20px 0 0; max-width: 64ch; }
.eyebrow { display: block; font-size: .76rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin-bottom: 14px; }

/* stat band */
.stats { max-width: var(--maxw); margin: 40px auto 8px; padding: 0 24px; display: grid; gap: 14px; grid-template-columns: repeat(6, 1fr); }
/* eight figures sit as two rows of four rather than six and a ragged two.
   The small-screen rules below still override it. */
.stats--3up { grid-template-columns: repeat(3, 1fr); }
.stats--4up { grid-template-columns: repeat(4, 1fr); }
.stats--5up { grid-template-columns: repeat(5, 1fr); }
.stat { border: 1px solid var(--line); border-radius: var(--radius); padding: 16px 14px; }
.stat__num { font-size: 1.9rem; font-weight: 700; line-height: 1; letter-spacing: -.02em; }
.stat__label { font-size: .8rem; color: var(--muted); margin-top: 7px; }
.stat__num.sm { font-size: 1.2rem; line-height: 1.58; letter-spacing: 0; white-space: nowrap; }

/* sections */
.section { max-width: var(--maxw); margin: 44px auto 0; padding: 0 24px; }
.section__title, section > h2 { font-size: 1.5rem; margin: 0 0 10px; font-weight: 700; padding-bottom: 8px; border-bottom: 1px solid var(--line-soft); }
.section__title.eyebrowed { font-size: .82rem; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); font-weight: 700; }
section { margin: 0 0 48px; scroll-margin-top: 72px; }
section > h2 .num { color: var(--muted); font-weight: 700; margin-right: 6px; }
section h3 { font-size: 1.12rem; margin: 26px 0 6px; font-weight: 600; }
/* A subsection heading sitting directly in a section is structure: Examples,
   Techniques, Sequence. Liber, 26 August 2026, wanting to see them at a
   glance. Capitals, so they read as the skeleton rather than as another
   heading. An h3 inside a .block or a card is a label, not structure, and is
   left alone. */
.section > h3,
.section > details > h3 { text-transform: uppercase; letter-spacing: .09em; font-size: .92rem;
  font-weight: 700; color: var(--muted); margin: 34px 0 12px; }
.section > h3:first-of-type,
.section > details > h3:first-of-type { margin-top: 22px; }
section strong { color: var(--ink); font-weight: 600; }

/* cards */
.cards { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); margin: 18px 0; }
.card { background: var(--surface); border: 1px solid var(--line); border-top: 4px solid var(--ac, var(--muted)); border-radius: var(--radius); padding: 18px 18px 16px; display: flex; flex-direction: column; }
.card h3, .card h4 { margin: 0 0 6px; font-size: 1.06rem; font-weight: 700; }
.card p { margin: 0 0 12px; font-size: .93rem; color: var(--ink-soft); }
.card .metric { margin-top: auto; font-size: .8rem; font-weight: 600; color: var(--muted); border-top: 1px solid var(--line-soft); padding-top: 10px; }
/* Something that may not happen: dashed top edge. Hollow dot is with the dot rules. */
.card--maybe { border-top-style: dashed; }

/* launchpad — clickable project tiles (dashboard) */
.launch { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); margin: 18px 0; }
/* Three or four tiles that belong together, held on one row until the screen is too narrow. */
.launch--3 { grid-template-columns: repeat(3, 1fr); }
.launch--4 { grid-template-columns: repeat(4, 1fr); }
@media screen and (max-width: 980px) { .launch--4 { grid-template-columns: repeat(2, 1fr); } }
@media screen and (max-width: 720px) { .launch--3, .launch--4 { grid-template-columns: 1fr; } }
.launch .tile {
  text-decoration: none; color: inherit; background: var(--surface);
  border: 1px solid var(--line); border-top: 4px solid var(--ac, var(--muted));
  border-radius: var(--radius); padding: 18px; display: flex; flex-direction: column; gap: 6px;
  transition: border-color .15s ease, transform .1s ease;
}
.launch a.tile:hover { border-color: var(--muted); transform: translateY(-2px); }
.launch .tile h3 { margin: 0; font-size: 1.05rem; font-weight: 700; }
.launch .tile p { margin: 0; font-size: .9rem; color: var(--ink-soft); }
.launch .tile .open { margin-top: 8px; font-size: .78rem; font-weight: 600; color: var(--link); }
.launch .tile .sub { margin-top: 6px; font-size: .74rem; color: var(--muted); }

/* callout */
.callout { border: 1px solid var(--line); border-left: 4px solid var(--ac, var(--muted)); background: var(--surface-2); border-radius: var(--radius); padding: 14px 18px; margin: 18px 0; color: var(--ink-soft); font-size: .97rem; }
.callout strong { color: var(--ink); }

/* accents — add one of these classes to any component that reads --ac
   (.card, .callout, .launch .tile, .qbanner, .obox) instead of an inline style */
.accent-yellow   { --ac: var(--yellow); }
.accent-blue     { --ac: var(--blue); }
.accent-red      { --ac: var(--red); }
.accent-green    { --ac: var(--green); }
.accent-purple   { --ac: var(--purple); }
.accent-orange   { --ac: var(--orange); }
.accent-pink     { --ac: var(--pink); }
.accent-sand     { --ac: var(--sand); }
.accent-charcoal { --ac: var(--charcoal); }

/* toc */
.toc { background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px 24px; margin: 32px 0 44px; }
.toc h2 { font-size: .78rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); margin: 0 0 12px; font-weight: 700; }
.toc ol { margin: 0; padding-left: 1.3em; columns: 2; column-gap: 32px; }
.toc li { margin: 6px 0; }
.toc a { color: var(--link); text-decoration: none; }
.toc a:hover { text-decoration: underline; }

/* steps */
.steps { counter-reset: step; list-style: none; padding: 0; margin: 18px 0; }
.steps li { position: relative; padding: 2px 0 16px 40px; margin: 0 0 0 12px; border-left: 1px solid var(--line); }
.steps li:last-child { border-left-color: transparent; }
.steps li::before { counter-increment: step; content: counter(step); position: absolute; left: -14px; top: 0; width: 26px; height: 26px; border-radius: 50%; background: var(--surface); border: 1px solid var(--line); color: var(--ink-soft); font-weight: 600; font-size: .85rem; display: grid; place-items: center; }
.steps li strong { color: var(--ink); }

/* figure / screenshot */
figure.shot { margin: 22px 0; }
figure.shot .frame { position: relative; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--surface); }
figure.shot img { display: block; width: 100%; height: auto; }
figure.shot.is-missing .frame::before { content: "Screenshot: " attr(data-label); display: flex; align-items: center; justify-content: center; min-height: 200px; padding: 28px; color: var(--muted); font-size: .92rem; font-weight: 600; text-align: center; background: var(--fill); }
figure.shot.is-missing .frame::after { content: "awaiting " attr(data-file); position: absolute; bottom: 10px; left: 0; right: 0; text-align: center; font-size: .74rem; color: var(--muted); font-family: ui-monospace, Menlo, monospace; }
figure.shot.is-missing img { display: none; }
figcaption { margin-top: 8px; font-size: .85rem; color: var(--muted); text-align: center; }
/* ---- examples row ----------------------------------------------------
   Examples is one row, whatever is in it (Liber, 27 August 2026). Photographs
   of example boards and cards describing the rest are equal citizens: however
   many there are, they share the width. This replaced a .shot--narrow rule added
   the same morning to cap a portrait photograph at 560px; the row sets the width
   now, so that rule went rather than sitting unused. */
.examples { display: grid; gap: 18px; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); align-items: start; margin: 18px 0; }
.examples > figure.shot { margin: 0; }
.examples > .card { margin: 0; }
/* one example on its own must not stretch to the full column: a portrait board at
   full width runs a page and a half tall. */
.examples > :only-child { max-width: 560px; }
.examples figcaption { text-align: left; }
@media screen and (max-width: 900px) { .examples { grid-auto-flow: row; grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media screen and (max-width: 560px) { .examples { grid-template-columns: minmax(0, 1fr); } }

/* board mockup */
.board { border: 1px solid var(--bc, var(--line)); border-radius: var(--radius); overflow: hidden; background: var(--surface); margin: 20px 0; font-size: .92rem; }
.board__group { font-weight: 600; padding: 10px 16px; background: var(--bc, var(--fill)); color: var(--ink); border-bottom: 1px solid var(--bc, var(--line)); }
.board table { width: 100%; border-collapse: collapse; table-layout: fixed; }
.board td p { margin: 0 0 8px; }
.board td p:last-child { margin-bottom: 0; }
.board th { text-align: left; font-size: .74rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); font-weight: 600; padding: 8px 16px; border-bottom: 1px solid var(--line); background: var(--surface-2); }
.board td { padding: 10px 16px; border-bottom: 1px solid var(--line-soft); color: var(--ink-soft); }
.board tr:last-child td { border-bottom: none; }
.pill { display: inline-block; font-weight: 600; font-size: .78rem; padding: 2px 10px; border-radius: var(--radius); border: 1px solid var(--line); color: var(--ink-soft); background: var(--fill); }
.board td.when { color: var(--ink); font-variant-numeric: tabular-nums; }
.board td.act { font-weight: 600; color: var(--ink); }
.board td.act .reg { font-weight: 400; }
.board tr.hl td { background: var(--surface-2); color: var(--ink); }
.board td small { display: block; color: var(--muted); font-weight: 400; margin-top: 3px; }
/* column widths for fixed-layout tables — put on the th */
th.c15 { width: 15%; } th.c20 { width: 20%; } th.c25 { width: 25%; } th.c33 { width: 33%; }
th.c30 { width: 30%; } th.c35 { width: 35%; } th.c40 { width: 40%; } th.c50 { width: 50%; }
.board td .flag { display: block; margin-top: 8px; font-weight: 700; color: var(--ink); background: var(--fill); border-left: 3px solid var(--green); border-radius: 4px; padding: 6px 10px; line-height: 1.35; }

/* rounded wrapper for bordered tables */
.tround { border-radius: var(--radius); overflow: hidden; margin: 16px 0; }
.tround > table { margin: 0; }

/* story strip */
.story { max-width: var(--maxw); margin: 40px auto 0; padding: 18px 24px; }
.story__inner { border: 1px solid var(--line); border-left: 4px solid var(--green); border-radius: var(--radius); padding: 16px 20px; color: var(--ink-soft); font-size: .98rem; background: var(--surface-2); }
.story__inner strong { color: var(--ink); }

/* code */
pre.code { background: var(--code-bg); color: var(--code-ink); border-radius: var(--radius); padding: 16px 18px; overflow-x: auto; font-size: .85rem; line-height: 1.5; font-family: ui-monospace, Menlo, monospace; margin: 16px 0; }
code.inline { font-family: ui-monospace, Menlo, monospace; font-size: .88em; background: var(--fill); padding: 1px 6px; border-radius: 4px; color: var(--ink); }
.note-strip { border: 1px dashed var(--muted); border-radius: var(--radius); padding: 12px 16px; margin: 0 0 8px; font-size: .9rem; color: var(--muted); }

/* big banner title */
.banner { background: var(--yellow); color: #1a1a1a; border-radius: 14px; padding: 18px 28px;
          text-align: center; font-weight: 800; font-size: 1.9rem; line-height: 1.15;
          letter-spacing: -.01em; margin: 8px 0 22px; }
@media screen and (max-width: 560px) { .banner { font-size: 1.4rem; padding: 14px 18px; } }

/* planning matrix — 9-column grid (reusable) */
.matrix-wrap { overflow-x: auto; margin: 20px 0; -webkit-overflow-scrolling: touch; }
.matrix { display: grid; grid-template-columns: repeat(9, 1fr); gap: 7px; min-width: 880px; }
.matrix + .matrix { margin-top: 10px; }
.matrix > div { border-radius: 7px; padding: 9px 7px; text-align: center; font-size: .8rem; line-height: 1.3; }
.matrix .m-head { font-weight: 700; font-size: 1rem; color: var(--ink); padding-bottom: 2px; }
.matrix .m-class { color: var(--ink-soft); font-size: .73rem; font-weight: 600; }
.matrix .m-brief { border: 2px solid var(--muted); font-weight: 600; color: var(--ink); display: flex; align-items: center; justify-content: center; min-height: 48px; background: var(--surface); }
.matrix .m-theme { font-weight: 700; color: #fff; padding: 15px 7px; }
.matrix .m-band { font-weight: 700; color: #fff; padding: 16px 7px; }
.matrix .m-tech { border: 2px solid var(--muted); font-weight: 600; color: var(--ink); display: flex; align-items: center; justify-content: center; min-height: 46px; background: var(--surface); }

/* progression bar chart (pure CSS, reusable) */
.chart { border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); padding: 22px 20px 16px; margin: 20px 0; }
.chart__plot { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 10px; align-items: end; height: 170px; border-bottom: 1px solid var(--line); }
.chart__bar { display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; }
.chart__bar .stem { width: 3px; min-height: 4px; border-radius: 3px; background: var(--muted); position: relative; }
.chart__bar .stem .pt { position: absolute; top: -5px; left: 50%; transform: translateX(-50%); width: 11px; height: 11px; border-radius: 50%; background: var(--muted); border: 2px solid var(--surface); }
.chart__bar .tag { font-size: .66rem; color: var(--muted); margin-bottom: 5px; font-weight: 600; }
.chart__axis { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 10px; margin-top: 8px; }
.chart__axis span { font-size: .72rem; text-align: center; color: var(--ink-soft); font-weight: 600; }
.chart__cap { font-size: .82rem; color: var(--muted); margin: 12px 0 0; }

/* photo gallery */
.gallery { display: grid; gap: 14px; grid-template-columns: repeat(3, 1fr); margin: 18px 0; }
.gallery figure { margin: 0; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--surface); }
.gallery img { display: block; width: 100%; height: 165px; object-fit: cover; }
.gallery figcaption { font-size: .8rem; color: var(--muted); padding: 8px 10px; text-align: center; }
.gallery img, figure.shot img { cursor: zoom-in; }

/* lightbox (click a photo to enlarge) */
.lightbox { position: fixed; inset: 0; z-index: 300; display: none; align-items: center; justify-content: center; background: rgba(0,0,0,.86); padding: 24px; cursor: zoom-out; }
.lightbox.open { display: flex; }
.lightbox figure { margin: 0; display: flex; flex-direction: column; align-items: center; max-width: 94vw; max-height: 94vh; }
.lightbox img { max-width: 94vw; max-height: 84vh; object-fit: contain; border-radius: 8px; box-shadow: 0 12px 44px rgba(0,0,0,.55); }
.lightbox figcaption { color: #fff; margin-top: 14px; font-size: .92rem; text-align: center; }
@media screen and (max-width: 560px) { .gallery { grid-template-columns: repeat(2, 1fr); } .gallery img { height: 130px; } }

/* green two-column table (Time to Explore) */
.gtable { width: 100%; border-collapse: collapse; table-layout: fixed; margin: 20px 0; }
.gtable th { background: var(--gc, var(--green)); color: #fff; text-align: left; font-weight: 700; font-size: .92rem; padding: 13px 14px; vertical-align: top; border: 2px solid var(--gc, var(--green)); white-space: nowrap; }
.gtable td { padding: 14px 16px; vertical-align: top; color: var(--ink-soft); border: 2px solid var(--gc, var(--green)); }
.gtable td.k { font-weight: 600; color: var(--ink); }
@media screen and (max-width: 620px) { .gtable th { white-space: normal; font-size: .85rem; } }
.gtable ul { margin: 0; padding-left: 1.15em; }
.gtable li { margin: 4px 0; }
/* Red is the safeguarding colour (25 Aug 2026), and the Safety section wears
   it as ONE solid line and nothing else. Liber, 26 August: a red table frame
   and red headers were "just too red", and a section that shouts stops being
   read. The rule under the title carries it; the table stays neutral. Works
   folded or not, so the selector takes the h2 and the summary. */
.gtable--red { --gc: var(--red); }
.section.section--safety > .section__title,
.section.section--safety > details > summary { border-bottom: 3px solid var(--red); }

/* materials tables (colour set per table via --mc) */
.mtable { width: 100%; border-collapse: collapse; table-layout: fixed; margin: 14px 0; }
.mtable td { border: 2px solid var(--mc, var(--blue)); padding: 11px 16px; text-align: center; color: var(--ink-soft); }
.mtable td.qty { font-weight: 600; color: var(--ink); }

/* two-column section layout */
.cols2grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 40px; align-items: start; }
.cols2grid .col { min-width: 0; }
.cols2grid .block { margin: 0 0 32px; }
.cols2grid .block:last-child { margin-bottom: 0; }
@media screen and (max-width: 720px) { .cols2grid { grid-template-columns: 1fr; } .cols2grid .col:first-child .block:last-child { margin-bottom: 32px; } }
.cols3grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 34px; align-items: start; }
.cols3grid .col { min-width: 0; }
.cols3grid .block { margin: 0 0 32px; }
.cols3grid .block:last-child { margin-bottom: 0; }
/* a heading inside a .block is one level down now that Setup nests Materials */
.cols2grid .block h4, .cols3grid .block h4 { font-size: 1.06rem; font-weight: 600; margin: 22px 0 6px; }
.cols2grid .block h4:first-child, .cols3grid .block h4:first-child { margin-top: 0; }
@media screen and (max-width: 860px) { .cols3grid { grid-template-columns: 1fr 1fr; } }
@media screen and (max-width: 560px) { .cols3grid { grid-template-columns: 1fr; }
  .cols3grid .block { margin-bottom: 28px; } }
.cols4grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0 28px; align-items: start; }
.cols4grid .col { min-width: 0; }
.cols4grid .block { margin: 0 0 30px; }
.cols4grid .block:last-child { margin-bottom: 0; }
@media screen and (max-width: 980px) { .cols4grid { grid-template-columns: 1fr 1fr; } }
@media screen and (max-width: 560px) { .cols4grid { grid-template-columns: 1fr; }
  .cols4grid .block { margin-bottom: 26px; } }

/* two-column bullet list */
.cols2list { columns: 2; column-gap: 40px; }
.cols2list > li { break-inside: avoid; margin-bottom: 10px; }
@media screen and (max-width: 720px) { .cols2list { columns: 1; } }

/* question banners + chips */
.qbanners { display: flex; flex-direction: column; gap: 8px; margin-top: 4px; }
.qbanner { background: var(--surface-2); border: 1px solid var(--line); border-left: 3px solid var(--ac, var(--blue)); border-radius: 0; padding: 9px 12px; font-size: .9rem; color: var(--ink); }
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }

/* record metadata — a small, secondary key/value block that sits under a hero
   without competing with the body. Markup: dl.meta > dt + dd pairs.
   .meta dd.unset marks a field that exists but has no value yet. */
.meta {
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  padding: 14px 0; margin: 26px 0 0;
  display: grid; grid-template-columns: 132px minmax(0, 1fr); gap: 7px 20px;
  font-size: .84rem; line-height: 1.5;
}
.meta dt { color: var(--muted); font-weight: 600; }
.meta dd { margin: 0; color: var(--ink-soft); }
.meta dd.unset { color: var(--muted); font-style: italic; }
.meta .chips { margin-top: 0; gap: 5px; }
.meta .pill { font-size: .74rem; font-weight: 500; padding: 1px 8px; }
/* .meta--open drops the top rule for a block that already sits under a
   section heading, so the heading rule and the block rule do not read as a
   double line. */
.meta--open { border-top: none; margin-top: 10px; padding-top: 0; }
@media screen and (max-width: 560px) {
  .meta { grid-template-columns: 1fr; gap: 0; }
  .meta dt { margin-top: 10px; }
  .meta dt:first-child { margin-top: 0; }
}

/* ---- empty slots ------------------------------------------------------
   A field that exists but has no value yet. It renders as a short muted
   rule holding the space the value would occupy, so the layout stays
   composed and the gap reads as deliberate rather than broken.
   Add .is-empty to an element left with no text content. */
.is-empty { color: var(--muted); }
.is-empty::after {
  content: ""; display: block; width: 42px; height: 2px; border-radius: 2px;
  background: var(--muted); opacity: .45;
}
.stat__num.is-empty { height: 1.9rem; display: flex; align-items: flex-end; }
.meta dd.is-empty, .card .metric .is-empty, .tl__when.is-empty { min-height: 1.35em; display: flex; align-items: center; }
.tl__when.is-empty::after, .meta dd.is-empty::after { width: 34px; }
.board td .is-empty { display: inline-flex; align-items: center; min-height: 1.35em; }

/* a small caption under a stat number — defines the figure, e.g. what it
   is the sum of. Never used to explain an absent value. */
.stat__sub { font-size: .72rem; color: var(--muted); margin-top: 3px; }

/* ---- timeline ---------------------------------------------------------
   The shape of a day at a glance: a time, a rail with a marker, a label.
   Markup: ol.timeline > li > .tl__when + .tl__rail + .tl__what.
   li.tl--venue marks a requirement that comes from the venue. */
.timeline { list-style: none; margin: 20px 0 0; padding: 0; border-top: 1px solid var(--line); }
.timeline > li {
  display: grid; grid-template-columns: 120px 20px minmax(0, 1fr); gap: 0 16px;
  align-items: start; padding: 13px 12px; border-bottom: 1px solid var(--line-soft);
}
.tl__when { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--ink); font-size: .95rem; padding-top: 1px; }
.tl__rail { position: relative; align-self: stretch; }
.tl__rail::before { content: ""; position: absolute; left: 50%; top: -14px; bottom: -14px; width: 1px; background: var(--line); transform: translateX(-50%); }
.timeline > li:first-child .tl__rail::before { top: 6px; }
.timeline > li:last-child .tl__rail::before { bottom: auto; height: 12px; }
.tl__rail::after {
  content: ""; position: absolute; left: 50%; top: 5px; width: 11px; height: 11px;
  border-radius: 50%; background: var(--surface); border: 2px solid var(--ac, var(--muted));
  transform: translateX(-50%);
}
.tl__what { font-size: .96rem; color: var(--ink); font-weight: 600; }
.tl__what small { display: block; font-weight: 400; color: var(--muted); font-size: .85rem; margin-top: 3px; }
.timeline > li.tl--run .tl__rail::after { background: var(--ac, var(--muted)); }
.timeline > li.tl--venue { background: var(--surface-2); }
@media screen and (max-width: 560px) {
  .timeline > li { grid-template-columns: 92px 18px minmax(0, 1fr); gap: 0 10px; }
}

/* ---- one-third / two-thirds split ------------------------------------
   An image at a third of the width, detail alongside it. */
.thirds { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); gap: 28px; align-items: start; margin: 20px 0 0; }
.thirds__img { display: block; width: 100%; height: auto; border: 1px solid var(--line); border-radius: var(--radius); }
.thirds .meta { margin-top: 0; }
@media screen and (max-width: 700px) { .thirds { grid-template-columns: 1fr; gap: 20px; } }

/* outlined box (distinct from filled cards) */
.obox { border: 2px solid var(--ac, var(--purple)); border-radius: 0; padding: 18px; background: transparent; display: flex; flex-direction: column; gap: 6px; }
.obox h3 { margin: 0 0 4px; font-size: 1.06rem; font-weight: 700; }
.obox p { margin: 0; font-size: .93rem; color: var(--ink-soft); }

/* --- prompt: the words said to a child ---------------------------------
   Every other block on an activity page addresses an adult. A prompt is the
   one addressed to a child, so it is framed and labelled rather than set as
   another paragraph a facilitator has to spot. The label breaks the top
   border, which is what makes it read as something held out to be said
   rather than as a callout. Set the words with data-say, default "Ask". */
.prompt { position: relative; border: 2px solid var(--ac, var(--pink));
  border-radius: 0; background: var(--fill);
  padding: 30px 26px 26px; margin: 26px 0; }
/* the label is a filled chip, not coloured text: pink is a pale palette
   colour and pink type on either ground fails to carry. Dark text on the
   accent is the same answer .board__group already uses for the pales. */
.prompt::before { content: attr(data-say); position: absolute; top: -.72em; left: 18px;
  font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .08em;
  color: #1a1a1a; background: var(--ac, var(--pink)); padding: 2px 9px; }
.prompt p { margin: 0 0 14px; font-size: 1.1rem; line-height: 1.5;
  color: var(--ink); font-weight: 500; }
.prompt p:last-child { margin-bottom: 0; }
.prompt p + p { font-size: 1rem; color: var(--ink-soft); font-weight: 400; }
/* a prompt whose possibilities are a list rather than a second sentence */
.prompt ul { margin: 14px 0 0; padding-left: 1.2em; columns: 2; column-gap: 34px; }
.prompt li { margin: 5px 0; font-size: 1rem; color: var(--ink-soft); break-inside: avoid; }
.prompt + .prompt { margin-top: 20px; }
/* two prompts side by side: a question and its possibilities, or a prompt
   for the start and one for the end */
.prompts { display: grid; grid-template-columns: 1fr 1fr; gap: 26px 30px;
  align-items: start; margin: 26px 0; }
.prompts > .prompt { margin: 0; }
@media screen and (max-width: 720px) { .prompts { grid-template-columns: 1fr; } }
/* No dashed variant. A dashed frame means "this comes off before the link
   goes out" (Liber, 26 Aug), so dashing a prompt that must survive verbatim
   would say the opposite of what it means. Attribution goes in data-say. */
@media screen and (max-width: 560px) { .prompt ul { columns: 1; } }

/* --- blist: a plain bullet list ----------------------------------------
   Liber, 26 August 2026, on chips used for materials and for what a child
   looks at: "They can be tags, doesn't mean they need to look like ones."
   A set of things to read is a list. Pills are for a status or a label. */
.blist { margin: 6px 0 0; padding-left: 1.15em; color: var(--ink-soft); }
.blist li { margin: 5px 0; }
.blist--2 { columns: 2; column-gap: 34px; }
.blist--2 li { break-inside: avoid; }
@media screen and (max-width: 560px) { .blist--2 { columns: 1; } }

/* colour legend */
.legend { display: flex; flex-wrap: wrap; gap: 8px 16px; margin: 14px 0 0; padding: 0; list-style: none; }
.legend li { display: flex; align-items: center; gap: 7px; font-size: .8rem; color: var(--ink-soft); }
.legend .dot, .kind .dot { width: 12px; height: 12px; border-radius: 3px; background: var(--ac, var(--muted)); flex: none; }
.legend .dot--maybe, .kind .dot--maybe { background: transparent; box-shadow: inset 0 0 0 2px var(--ac, var(--muted)); }

/* ---- type marker ------------------------------------------------------
   Names the category a card belongs to, next to the colour that codes it.
   The colour comes from an .accent-* class on the card, so the card's top
   border and the dot always agree; the label carries the meaning in words
   as well, so the coding does not rest on colour alone. A card with no
   .accent-* class stays uncoloured. Use a div, not a p, so .card p does
   not override the size. Markup:
     <article class="card accent-green">
       <h3>Name</h3><div class="kind"><span class="dot"></span>type</div> */
.kind { display: flex; align-items: center; gap: 7px; margin: 0 0 10px;
        font-size: .74rem; font-weight: 600; color: var(--muted); }

/* element list inside cards */
.card ul.mini { margin: 4px 0 12px; padding-left: 1.15em; font-size: .9rem; color: var(--ink-soft); columns: 2; column-gap: 20px; }
.card ul.mini li { margin: 3px 0; break-inside: avoid; }
.card .classes { font-size: .74rem; color: var(--muted); margin: 0 0 10px; }
.card .chips { margin: 0 0 14px; }
.card > .is-empty { margin: 0 0 14px; }
.card .metric.row { display: flex; justify-content: space-between; align-items: center; gap: 14px; }
.card .metric.row .val { color: var(--ink); font-size: .95rem; font-weight: 700; }
/* a second metric row continues the first block rather than starting its own */
.card .metric + .metric { margin-top: 0; border-top: 0; padding-top: 5px; }
/* a card heading that links to the thing it describes; the rule takes the card's accent */
.card h3 a { color: inherit; text-decoration: underline; text-decoration-thickness: 1px;
             text-underline-offset: 4px; text-decoration-color: var(--ac, var(--muted)); }
.card h3 a:hover { color: var(--link); text-decoration-color: var(--link); }

/* ---- schematic diagram ------------------------------------------------
   A small line drawing of a physical operation. The canvas is set by the
   container it sits in, not by the drawing: inside a .card author on
   0 0 120 72, inside a .fig or a .seq__step author on 0 0 120 120.
   Five stroke roles, all drawn from theme variables so the drawing reads in
   light and dark. Ink is the material, the accent is something you do to it:
     .d-paper   the material itself, in the state that panel shows
     .d-mark    a FOLD line, marked but not yet made (takes the accent)
     .d-cut     a CUT path and how far it goes (accent, always drawn
                with its arrowhead, which is what tells it from .d-paper)
     .d-ghost   a tool, a work surface, an arrow: not the material
     .d-hidden  material that really is there but is concealed by something
                in front of it, e.g. a dowel running inside a straw
   Never give a diagram a fill or a colour of its own. */
.diagram { display: block; width: 100%; height: auto; margin: 0 0 12px; }
.d-paper, .d-mark, .d-cut, .d-ghost, .d-hidden {
  fill: none; stroke-linecap: round; stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.d-paper  { stroke: var(--ink); stroke-width: 1.8; }
.d-mark   { stroke: var(--ac, var(--blue)); stroke-width: 1.5; stroke-dasharray: 3 3; }
.d-cut    { stroke: var(--ac, var(--blue)); stroke-width: 1.5; }
.d-ghost  { stroke: var(--muted); stroke-width: 1.1; }
.d-hidden { stroke: var(--muted); stroke-width: 1.3; stroke-dasharray: 0.6 2.8; }
.cards--tight { grid-template-columns: repeat(auto-fill, minmax(196px, 1fr)); }
.cards--one { grid-template-columns: minmax(0, 560px); }
/* Both of these need the doubled class: the plain .figs and .fig rules are
   later in this file, so at equal specificity they win. Fourth time today. */
.figs.figs--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.figs.figs--2 .diagram { max-width: 100%; }
/* A .fig caption is normally one sentence under a technique drawing, so .fig p
   is .9rem. A figs--2 figure carries body copy explaining how an area works,
   and at .9rem it read as smaller than every other paragraph on the page
   (Liber, 26 Aug). Body size here, caption size everywhere else. */
.figs.figs--2 .fig p { font-size: inherit; line-height: inherit; }  /* inherit, not 1rem: body is 1.0625rem here */
.figs.figs--2 .fig h4 { font-size: 1.06rem; margin: 0 0 12px; }
/* --- icn: an area icon sitting before its title ------------------------
   Line icons on Material's 24x24 grid, drawn to match its proportions and
   weight rather than copied from it. Stroked, so they take the surrounding
   colour and work in both themes with nothing to load. */
.icn { width: 1.2em; height: 1.2em; vertical-align: -.24em; margin-right: .5em;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round; flex: none; }

/* the title names the area before you look at it, so it sits above the drawing */
.figs.figs--2 .fig .diagram { margin: 0 0 16px; }
@media screen and (max-width: 720px) { .figs.figs--2 { grid-template-columns: 1fr; } }

/* ---- step sequence -----------------------------------------------------
   A make read left to right: one drawing per step, each a separate square
   diagram, numbered by the stylesheet so no author picks the wording. Four
   panels is the house pattern, inherited from the printed step strips on
   the example boards. Put the accent class on the .seq itself; .d-mark and
   .d-cut read --ac from their nearest ancestor. Every .seq__step carries a
   <figcaption>, empty if there are no words: the number comes from it. */
.seq { counter-reset: seqstep; display: grid; gap: 22px 20px;
       grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); margin: 20px 0 0; }
.seq__step { margin: 0; }
.seq__step .diagram { aspect-ratio: 1 / 1; max-width: 210px; margin: 0 0 10px; }
.seq__step figcaption { margin: 0; font-size: .9rem; color: var(--ink-soft); }
.seq__step figcaption::before {
  counter-increment: seqstep; content: "Step " counter(seqstep);
  display: block; margin: 0 0 3px; color: var(--ink);
  font-size: .78rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
}

/* ---- figure column -----------------------------------------------------
   A diagram with its words under it and nothing drawn around it. A .card
   boxes a thing you might act on; a .fig only shows an operation, so a
   border round it adds a line that means nothing. The drawing is square
   here (author on 0 0 120 120) because a row of squares reads as one set
   more readily than a row of letterbox panels. Put the accent class on the
   .fig itself: .d-mark reads --ac from its nearest ancestor, and outside a
   card there is nothing else to set it. */
.figs { display: grid; gap: 28px 30px; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); margin: 22px 0 0; }
.fig { margin: 0; }
.fig .diagram { aspect-ratio: 1 / 1; max-width: 230px; margin: 0 0 14px; }
.fig h4 { margin: 0 0 5px; font-size: 1rem; }
.fig p { margin: 0; font-size: .9rem; color: var(--ink-soft); }
.fig p + p { margin-top: 10px; }

/* ---- table card -------------------------------------------------------
   A sheet taped flat to a table so a child and the adult with them can start
   without anyone explaining it. Printed on plain paper, not laminated
   (Liber, 25 August 2026), so it is cheap enough to reprint when it gets
   glue on it, and the design assumes that rather than defending against it:
   few words, large type, and nothing that stops working when a corner is
   smudged.

   A4 landscape, because the house step notation is a strip read left to
   right and a card lying on a table is read foreshortened from standing.
   One card per page on print; on screen they stack so a set can be checked
   in one scroll. Screen keeps the frame; print drops it, because a border is
   ink spent on nothing. */
.tcard { border: 1px solid var(--line); background: var(--surface);
         padding: 22px 24px 20px; margin: 0 0 22px; }
.tcard h2 { margin: 0 0 4px; font-size: 1.6rem; font-weight: 700; letter-spacing: -.01em; }
.tcard__lede { margin: 0 0 18px; font-size: 1.02rem; font-weight: 600; color: var(--ink-soft); }
.tcard__steps { display: grid; gap: 16px; margin: 0 0 16px;
                grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
.tcard__step { margin: 0; }
.tcard__step .diagram { margin: 0 0 8px; }
.tcard__step p { margin: 0; font-size: .95rem; line-height: 1.4; }
.tcard__step b { display: block; font-size: .72rem; letter-spacing: .08em;
                 text-transform: uppercase; color: var(--muted); margin: 0 0 3px; }
.tcard__ask { margin: 0; font-size: 1.02rem; font-style: italic; color: var(--ink-soft); }
.tcard__fix { margin: 8px 0 0; font-size: .9rem; color: var(--muted); }
.tcard__rules { margin: 0; padding: 0; list-style: none; }
.tcard__rules li { padding: 9px 0; border-top: 1px solid var(--line-soft); font-size: 1.02rem; }
.tcard__rules li:first-child { border-top: 0; }
.tcard__rules b { font-weight: 700; }
.tcard--rule { border-top: 5px solid var(--ac, var(--muted)); }
.tcard--rule .tcard__lede { color: var(--ink); }

@media print {
  /* Landscape is the table card and the risk assessment sheet, both of which are
     wide by design. Everything else is a document and prints portrait, via a named
     page: @page cannot be scoped by selector any other way. */
  @page { size: A4 portrait; margin: 12mm 14mm; }
  @page wide { size: A4 landscape; margin: 11mm; }
  .tcards, .ra { page: wide; }

  /* Force the LIGHT palette on paper whatever the screen was showing. A card
     printed from a dark-themed browser otherwise comes out pale grey on white
     and is unreadable across a table, which is a fault you only see after
     printing. These are the :root light values, not new colours. */
  :root, :root[data-theme="dark"] {
    --bg: #ffffff; --surface: #ffffff; --surface-2: #ffffff; --fill: #f0f0f0;
    --ink: #1a1a1a; --ink-soft: #3d3d3d; --muted: #5c5c5c;
    --line: #bdbdbd; --line-soft: #dcdcdc;
  }

  /* Chrome and the theme toggle come off every printed page. */
  .topbar, .theme-toggle, .qform, .toc { display: none; }
  /* Hiding .qform alone left its section heading stranded on the last page of
     every printed report. The whole section goes, since the questions are
     answered on screen and mean nothing on paper. */
  .section:has(> .qform) { display: none; }

  /* Keep a heading with what it introduces. Without this a section title
     lands alone at the foot of a page and its table starts on the next one,
     which you only see once the PDF exists. */
  .section__title, .card h3, .board__group { page-break-after: avoid; break-after: avoid; }
  p { orphans: 2; widows: 2; }

  /* The rest of this block is the TABLE CARD page and nothing else. It used to
     apply everywhere, which meant any other page printed without its headings or
     its hero: a fault you only find by printing. Scoped 27 August 2026 so the
     activity pages could be printed as station packs. */
  .tcards .foot, .tcards .hero, .tcards .tcards__intro, .tcards .section__title { display: none; }
  .tcards .section { padding: 0; margin: 0; max-width: none; }
  .tcard { border: 0; background: none; padding: 0; margin: 0;
           page-break-after: always; break-after: page; }
  .tcard:last-child { page-break-after: auto; break-after: auto; }
  /* Sized to fill the sheet. A card is read standing, from about half a
     metre above it and foreshortened, so type that looks generous on screen
     is the minimum on the table. */
  .tcard h2 { font-size: 38pt; margin-bottom: 6pt; }
  .tcard__lede { font-size: 19pt; margin-bottom: 26pt; }
  .tcard__steps { gap: 20pt; margin-bottom: 26pt; }
  .tcard__step p { font-size: 14pt; line-height: 1.35; }
  .tcard__step b { font-size: 10pt; }
  .tcard__step .diagram { margin-bottom: 12pt; }
  .tcard__ask { font-size: 18pt; }
  .tcard__fix { font-size: 12pt; margin-top: 14pt; }
  .tcard__rules li { font-size: 15pt; padding: 11pt 0; }

  /* vector-effect pins a stroke to a fixed screen width, so a drawing scaled
     up for print goes hairline. Turn it off and restate the widths in user
     units. See skill-notes/building-print-packs.md. */
  .tcard .d-paper, .tcard .d-mark, .tcard .d-cut,
  .tcard .d-ghost, .tcard .d-hidden { vector-effect: none; }
  .tcard .d-paper  { stroke-width: 1.6; }
  .tcard .d-mark   { stroke-width: 1.3; }
  .tcard .d-cut    { stroke-width: 1.3; }
  .tcard .d-ghost  { stroke-width: 1.0; }
  .tcard .d-hidden { stroke-width: 1.1; }
}

/* ---- disclosure inside a card ------------------------------------------
   Three levels of detail, and each has a job (Liber, 25 August 2026):
     the card          what a facilitator needs at a glance
     the open card     the list, a line per item
     the activity page the full method, "for when you don't have a clue of
                       what you're doing and need deep instructions"
   So a card may hide a list behind a summary. What it may NOT hide is what
   the card is: name, type, facilitator, volunteers and counts stay visible.

   Safety lines MAY collapse here, which is a deliberate reversal: this board
   is read by facilitators, and volunteers have their own entry point in
   volunteer-guide.html, which never collapses anything. Collapsing is safe
   exactly when the audience is known and the other audience has a flat
   document of its own.

   Native <details>, not the .reveal checkbox below: it is announced as
   expandable by screen readers, works from the keyboard, and Chrome opens it
   for an in-page find. Print forces it open, see @media print. */
.card details { margin: 0 0 12px; border-top: 1px solid var(--line-soft); }
.card summary { cursor: pointer; list-style: none; padding: 9px 0 0;
                font-size: .82rem; font-weight: 600; color: var(--ink-soft);
                display: flex; align-items: center; gap: 8px; }
.card summary::-webkit-details-marker { display: none; }
.card summary::before {
  content: "+"; flex: none; width: 16px; height: 16px; border-radius: 4px;
  border: 1px solid var(--line); display: grid; place-items: center;
  font-size: .8rem; line-height: 1; color: var(--muted);
}
.card details[open] summary::before { content: "\2212"; }
.card summary:focus-visible { outline: 2px solid var(--link); outline-offset: 3px; border-radius: 4px; }
.card details > ul { margin: 10px 0 2px; padding: 0; list-style: none;
                     font-size: .87rem; color: var(--ink-soft); }
.card details > ul > li { padding: 6px 0; border-top: 1px solid var(--line-soft); }
.card details > ul > li:first-child { border-top: 0; }
.card details b { font-weight: 600; color: var(--ink); }
@media print { .card details > *:not(summary) { display: block !important; }
               .card summary::before { content: ""; border: 0; } }

/* ---- station frame ----------------------------------------------------
   A station is a place with a table; an activity is a thing a child does.
   One station may hold several activities, and the two were being told apart
   only by a run-in heading, which made a station look like a section rather
   than a thing in its own right.

   So a station is a SQUARE-CORNERED frame around the cards of the activities
   it holds. Square corners are the whole distinction: the rounded card is the
   thing you act on, the square frame is the place it sits in. The frame
   carries the station name and nothing else. Facilitators live on the
   activity cards, because a facilitator runs an activity.

   Width follows content: a frame spans one grid column per activity it holds,
   so a three-activity station is visibly bigger than a one-activity station
   and the inner .cards grid puts one card in each column with no per-station
   tuning. Below 900px everything collapses to one column and the frames
   stack. */
.stations { counter-reset: station; display: grid; gap: 18px; align-items: start;
            grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); margin: 18px 0; }
.station { border: 1px solid var(--line); border-radius: 0; padding: 12px 12px 14px;
           background: var(--surface-2); grid-column: span 1; }
.station--2 { grid-column: span 2; }
.station--3 { grid-column: span 3; }
/* Numbered by a counter, not by hand, so inserting a station renumbers the
   rest. Sentence case rather than the small caps a frame label would take:
   Liber wants a title here, and dropping the uppercase and the tracking is
   what buys the width to keep the longest name on ONE LINE at this size.
   The longest is "7 . Sounds of the Universe" in a single-column frame, which
   is the case to measure against before making this any larger. */
.station__name { margin: 0 0 11px; font-size: 1.15rem; font-weight: 700;
                 letter-spacing: -.005em; color: var(--ink);
                 white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.station__name::before { counter-increment: station; content: counter(station) " · ";
                         color: var(--muted); font-weight: 400; }
.station__name .reg { text-transform: none; letter-spacing: 0; font-weight: 400; }
.station .cards { margin: 0; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
@media screen and (max-width: 900px) {
  .stations { grid-template-columns: 1fr; }
  .station--2, .station--3 { grid-column: span 1; }
}

/* ---- floor plan --------------------------------------------------------
   A plan of a room, drawn with the same five roles and the same variables as
   a technique diagram, but it is a different genre and two rules bend.

   1. A plan CARRIES ITS LABELS. A technique diagram never contains text,
      because its figcaption says what the step is. A plan has fifteen things
      in fifteen places, and a numbered key would mean cross-referencing a
      drawing someone is holding in one hand in a room they have not been in
      before. So .d-label and .d-label-soft exist, and only here.
   2. The roles read ONE STEP ACROSS, because on a plan "the material" is the
      part of the room that is ours:
        .d-paper       the walls, and OUR tables
        .d-ghost       everybody else's tables and fittings: context, not ours
        .d-mark        the boundary of our area, marked out but not built
      .d-cut and .d-hidden are not used on a plan.

   The label classes set a fill, which no other diagram class may do; text is
   the one thing that has to be filled rather than stroked. */
.plan { margin: 0; }
.plan .diagram { width: 100%; max-width: 860px; margin: 0 auto 12px; }
.plan figcaption { font-size: .85rem; color: var(--muted); max-width: 860px;
                   margin: 0 auto; line-height: 1.5; }
.d-label, .d-label-soft {
  stroke: none; text-anchor: middle; dominant-baseline: middle;
  font-family: inherit; letter-spacing: .01em;
}
.d-label      { fill: var(--ink);   font-size: 3.4px; font-weight: 600; }
.d-label-soft { fill: var(--muted); font-size: 2.7px; font-weight: 400; }
.d-zone       { fill: var(--ac, var(--blue)); opacity: .08; stroke: none; }

/* ---- legend ------------------------------------------------------------
   Names what the accent colours on the cards below it mean, so the colour
   is carrying information rather than decorating. Put the accent class on
   each entry; the swatch reads it from --ac. */
.legend { display: flex; flex-wrap: wrap; gap: 9px 22px; margin: 14px 0 0; font-size: .86rem; color: var(--ink-soft); }
.legend > * { display: inline-flex; align-items: center; gap: 7px; }
.legend i { width: 12px; height: 12px; border-radius: 3px; background: var(--ac, var(--line)); flex: none; font-style: normal; }

/* ---- weather -----------------------------------------------------------
   The forecast as a figure in the stats row, on a page where wind, rain and
   heat change what gets carried and where a structure can stand. Icons are
   inline SVG on a 24 x 24 viewBox so they take the theme and the accent. */
.wx { display: flex; align-items: center; gap: 7px; }
.wx svg { width: 23px; height: 23px; flex: none; fill: none; stroke: var(--ac, var(--blue)); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.wx--sub { gap: 4px 12px; flex-wrap: wrap; }
.wx--sub svg { width: 14px; height: 14px; stroke-width: 1.8; }
/* an icon and its figure are one unit, so a wrap never leaves the icon
   stranded at the end of a line with its number on the next one. */
.wx__b { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }

/* ---- reveal ------------------------------------------------------------
   A checkbox that opens a block below it. No script: the hidden input is a
   sibling of the label and the body, and :checked drives both.
   Markup: input.reveal__switch#id + label.reveal__label[for=id] + .reveal__body */
.reveal__switch { position: absolute; width: 1px; height: 1px; opacity: 0; margin: 0; }
.reveal__label { display: inline-flex; align-items: center; gap: 9px; cursor: pointer; color: var(--ink-soft); }
.reveal__label::before {
  content: ""; width: 15px; height: 15px; flex: none; border: 1px solid var(--muted);
  border-radius: 3px; background: var(--surface); color: var(--bg);
  display: grid; place-items: center; font-size: .68rem; line-height: 1; font-weight: 700;
}
.reveal__switch:checked + .reveal__label::before { content: "\2713"; background: var(--ink); border-color: var(--ink); }
.reveal__switch:focus-visible + .reveal__label::before { outline: 2px solid var(--link); outline-offset: 2px; }
.reveal__body { display: none; }
.reveal__switch:checked ~ .reveal__body { display: block; }

/* ---- picker ------------------------------------------------------------
   A list of things that could be chosen. Nothing is chosen by default. */
.picker { list-style: none; margin: 12px 0 2px; padding: 0; display: grid; gap: 6px; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }
.picker label { display: flex; align-items: center; gap: 9px; padding: 8px 11px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-2); color: var(--ink-soft); cursor: pointer; }
.picker label:hover { border-color: var(--muted); }
.picker input { flex: none; margin: 0; accent-color: var(--ink); }
[data-theme="dark"] .picker input { color-scheme: dark; }
.picker label:has(input:checked) { border-color: var(--ink); color: var(--ink); font-weight: 600; }

/* question form — answer a report's open questions at the point of reading.
   Markup: form.qform > .q (with .q__ask, optional .q__why, .q__opt labels,
   optional textarea.q__note) + .qform__actions. Driven by assets/answers.js. */
.qform { border: 1px solid var(--line); border-top: 4px solid var(--ac, var(--red)); border-radius: var(--radius); background: var(--surface); padding: 8px 24px 24px; margin: 22px 0; }
.qform__intro { font-size: .95rem; color: var(--ink-soft); margin: 18px 0 4px; }
.q { border-top: 1px solid var(--line-soft); padding: 20px 0 4px; }
.q:first-of-type { border-top: none; }
.q__ask { font-weight: 700; color: var(--ink); font-size: 1.02rem; margin: 0 0 4px; }
.q__why { font-size: .89rem; color: var(--muted); margin: 0 0 12px; }
.q__opt { display: flex; align-items: flex-start; gap: 10px; padding: 9px 12px; margin: 0 0 7px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-2); cursor: pointer; font-size: .94rem; color: var(--ink-soft); transition: border-color .12s ease; }
.q__opt:hover { border-color: var(--muted); }
.q__opt input { margin: 4px 0 0; flex: none; accent-color: var(--red); }
.q__opt input:checked ~ span { color: var(--ink); font-weight: 600; }
.q__opt:has(input:checked) { border-color: var(--ac, var(--red)); background: var(--fill); }
.q__opt span small { display: block; font-weight: 400; color: var(--muted); font-size: .84rem; margin-top: 2px; }
.q__note, .q__free { display: block; width: 100%; margin-top: 8px; font: inherit; font-size: .93rem; color: var(--ink); background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 12px; resize: vertical; min-height: 52px; }
/* the name field: one line, same skin as the textareas, and 16px on a phone
   because anything smaller makes iOS Safari zoom the page on focus. */
.q__who { display: block; width: 100%; max-width: 22rem; margin-top: 4px; font: inherit; font-size: 16px; color: var(--ink); background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 12px; }
.q__note:focus, .q__free:focus, .q__who:focus { outline: none; border-color: var(--ac, var(--red)); }
.q__note::placeholder, .q__free::placeholder, .q__who::placeholder { color: var(--muted); }
.qform__how { font-size: .89rem; color: var(--muted); margin: 10px 0 0; }
.qform__how strong { color: var(--ink-soft); }
.qform__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 26px; padding-top: 20px; border-top: 1px solid var(--line-soft); }
.btn { font: 600 .9rem/1 var(--font); color: var(--bg); background: var(--ink); border: 1px solid var(--ink); border-radius: 999px; padding: 11px 20px; cursor: pointer; transition: opacity .12s ease; }
.btn:hover { opacity: .85; }
.btn--soft { color: var(--ink-soft); background: var(--surface); border-color: var(--line); }
.btn--soft:hover { border-color: var(--muted); opacity: 1; }
.qform__status { font-size: .86rem; color: var(--muted); }
@media screen and (max-width: 560px) {
  .qform { padding: 4px 16px 20px; }
  .q__note, .q__free { font-size: 16px; }
  .qform__actions .btn { flex: 1 1 100%; text-align: center; }
}

/* wrap + footer */
.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 24px 80px; }
.foot { max-width: var(--maxw); margin: 44px auto 0; padding: 24px; border-top: 1px solid var(--line); color: var(--muted); font-size: .84rem; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px; }

@media screen and (max-width: 760px) { .stats { grid-template-columns: repeat(3, 1fr); } .hero h1 { font-size: 1.9rem; } .toc ol { columns: 1; } }
@media screen and (max-width: 440px) { .stats { grid-template-columns: repeat(2, 1fr); } }

/* Pale board headers: force dark text in dark theme (light bg) */
[data-theme="dark"] .board[style*="--pink"] .board__group,
[data-theme="dark"] .board[style*="--sand"] .board__group,
[data-theme="dark"] .board[style*="--yellow"] .board__group { color: #1a1a1a; }

/* ---- packlist ----------------------------------------------------------
   A list you tick while packing, on a phone held in the other hand. Three
   columns on a desktop, one on a phone. No box around an item: the checkbox
   is the affordance and a border round every line only adds noise. Checked
   items strike through and fade, so what is left is what you can still see.
   State persists via packlist.js. */
.packlist { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 0 28px; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
.packlist li { margin: 0; }
.packlist label { display: flex; align-items: baseline; gap: 10px; padding: 7px 2px; color: var(--ink-soft); cursor: pointer; font-size: .94rem; line-height: 1.35; transition: opacity .12s ease; }
.packlist label:hover .pk__name { color: var(--ink); }
.packlist input { flex: none; margin: 0; width: 17px; height: 17px; accent-color: var(--ac, var(--green)); transform: translateY(2px); }
[data-theme="dark"] .packlist input { color-scheme: dark; }
.packlist .pk__n { flex: none; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; }
.packlist .pk__note { display: block; font-size: .82rem; color: var(--muted); margin-top: 1px; }
.packlist label:has(input:checked) { opacity: .42; }
.packlist label:has(input:checked) .pk__name,
.packlist label:has(input:checked) .pk__n { text-decoration: line-through; }
.packlist__done { font-size: .86rem; color: var(--muted); margin-left: auto; font-variant-numeric: tabular-nums; }
.packgroup { display: flex; align-items: baseline; gap: 10px; margin: 26px 0 0; padding-bottom: 5px; border-bottom: 1px solid var(--line); }
.packgroup h3 { margin: 0; color: var(--ac, var(--ink)); }
@media screen and (max-width: 560px) { .packlist label { padding: 9px 2px; } }

/* ---- Folding section -------------------------------------------------------
   A .section whose body collapses behind its own title. The summary carries the
   .section__title look plus a +/- marker. For a page with a stable set of long
   sections where the titles are the map. Native <details>, so it is announced
   as expandable and it prints open. */
.section--fold > details > summary {
  font-size: 1.5rem; margin: 0 0 10px; font-weight: 700; padding-bottom: 8px;
  border-bottom: 1px solid var(--line-soft); cursor: pointer; list-style: none;
  display: flex; align-items: center; gap: 10px; }
.section--fold > details > summary::-webkit-details-marker { display: none; }
.section--fold > details > summary::after {
  content: "\002B"; margin-left: auto; font-weight: 400; font-size: 1.15rem; color: var(--muted); }
.section--fold > details[open] > summary::after { content: "\2212"; }
.section--fold > details > summary:focus-visible {
  outline: 2px solid var(--link); outline-offset: 3px; border-radius: 4px; }
@media print { .section--fold > details > *:not(summary) { display: block !important; }
               .section--fold > details > summary::after { content: ""; } }

/* ---- Cut line --------------------------------------------------------------
   Everything below it comes off before the document is sent out. One per page,
   and its only job is to be unmissable while scrolling. */
.cutline { max-width: var(--maxw); margin: 54px auto 0; padding: 0 24px; }
.cutline__bar { height: 6px; border-radius: 3px; background: var(--red); margin: 0 0 10px; }
.cutline__label { margin: 0; font-size: .82rem; text-transform: uppercase; letter-spacing: .07em;
  font-weight: 700; color: var(--red); }
.cutline__label .reg { text-transform: none; letter-spacing: 0; font-weight: 400; color: var(--muted); }
@media print { .cutline { display: none; } }

@media print {
  /* A document page: an activity, a guide, a board. Compact, because these get
     printed two to a sheet and read at a table. Sized against the A4 portrait
     text column, not against the screen. */
  html { font-size: 13px; }
  .section, .hero { max-width: none; }
  .hero { padding: 0 0 6pt; }
  .hero h1 { font-size: 17pt; margin: 0; }
  .hero h1 .rule { display: none; }
  .hero p.lede { font-size: 9.5pt; margin: 4pt 0 0; max-width: none; }
  .section { margin: 0 0 9pt; padding: 0; }
  .section__title { font-size: 11.5pt; margin: 0 0 5pt; padding-bottom: 3pt;
                    page-break-after: avoid; break-after: avoid; }
  .section > h3 { page-break-after: avoid; break-after: avoid; }
  /* NOT .gtable: a long table must break, or every one jumps to a fresh page.
     Its rows carry their own avoid. */
  .card, .tile, .station, figure, .steps li { page-break-inside: avoid; break-inside: avoid; }
  .cards { gap: 7pt; margin: 7pt 0; }
  .card { padding: 8pt 9pt; }
  .card h3, .card h4 { font-size: 10pt; }
  .card p { font-size: 8.4pt; margin-bottom: 6pt; }
  .board, .gtable { font-size: 8.4pt; }
  .board td, .board th, .gtable td, .gtable th { padding: 4pt 6pt; }
  /* No bare `p, li` rule here: at (0,0,1) it beats `.ra .gtable` on inherited size
     and quietly retyped the risk assessment sheets. The base size does this job. */
  /* A photograph at screen width takes a whole sheet. On paper these are
     reference, not posters, and they keep their aspect ratio. */
  img, svg { max-height: 46mm; width: auto !important; height: auto !important;
             max-width: 100%; object-fit: contain; }
  .tcards img, .tcards svg { max-height: none; }
  /* A capped photograph in a full-width figure leaves a bordered empty box beside
     it. On paper the frame shrinks to the picture. */
  figure { margin: 0 0 6pt; width: max-content; max-width: 100%;
           page-break-inside: avoid; break-inside: avoid; }
  figure img { display: block; }
  /* The border lives on .frame inside the figure, so capping the image alone left
     a full-width bordered box with the picture in one corner. */
  figure.shot .frame { width: max-content; max-width: 100%; }
  .examples > figure.shot { justify-self: start; }
  /* Anything with a rule or a border round it reads as broken when it splits. */
  .prompt, .callout, .note-strip, .board, .frame, .block { page-break-inside: avoid; break-inside: avoid; }
  /* The prompt's label sits at top:-.72em, outside its own box, so a prompt pushed
     to the next page leaves its tab printed alone at the foot of the one before.
     On paper it goes inline, inside the box it belongs to. */
  .prompt::before { position: static; display: inline-block; margin: 0 0 5pt; }
  .prompt { padding-top: 8pt; }
  .foot { max-width: none; margin: 7pt 0 0; padding: 4pt 0 0; font-size: 6.5pt; }
  details { display: block; }
  details > *:not(summary) { display: block !important; }
  summary::before, summary::after { content: "" !important; }
}

/* ---- risk assessment sheet -------------------------------------------
   A risk assessment is a document that gets printed and carried to a table,
   not a page you scan, so it is the one place on this site where the print
   layout leads and the screen follows. Everything here is scoped to .ra on
   the body: no other page changes.

   The table is the five columns iOi has used since 2018 (hazard, who, how,
   controls, score) and the component underneath it is .gtable, which already
   takes a <ul> inside a <td>. Only the score column and the grouping rows are
   new. Generated by event-activity-planner/build-risk-assessments.py. */

.gtable--charcoal { --gc: var(--charcoal); }

/* A five column table at the 940px house width squeezes the first three columns
   to about twelve characters. This is a document, and the table is the whole of
   it, so the sheet gets a wider measure. Print overrides max-width to none. */
.ra { --maxw: 1180px; }

/* The header block is a label-over-value grid, not a stack of table rows. Sixteen
   rows filled a whole sheet on their own and pushed the hazards, which are the
   document, onto page two. */
.ra-head { display: grid; grid-template-columns: repeat(6, 1fr); gap: 1px;
           background: var(--line); border: 1px solid var(--line); margin: 20px 0 0; }
.ra-head__cell { background: var(--surface); padding: 9px 12px; min-width: 0; }
.ra-head__cell.span2 { grid-column: span 2; }
.ra-head__cell.span3 { grid-column: span 3; }
/* screen only, and deliberately so: headless Chrome evaluates width media queries
   against the window, not the page box, so an unscoped max-width rule collapses the
   printed grid to two columns and costs a whole page. */
@media screen and (max-width: 900px) { .ra-head { grid-template-columns: repeat(2, 1fr); }
  .ra-head__cell.span2, .ra-head__cell.span3 { grid-column: span 2; } }
.ra-head dt { font-size: .7rem; text-transform: uppercase; letter-spacing: .05em;
              color: var(--muted); font-weight: 700; margin: 0 0 3px; }
.ra-head dd { margin: 0; font-size: .88rem; color: var(--ink); }

.ra-scope { font-size: .92rem; color: var(--ink-soft); margin: 14px 0 0; max-width: 74ch; }

/* The three closing blocks sit side by side rather than one under the other.
   Stacked, they took a sheet of their own; in a band they ride along under the
   hazards and a station sheet comes out at one or two sides. */
.ra-tail { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
           align-items: start; }
/* The all-stations check block on the one-document version: same panels, but there
   are seven or eight of them rather than three, so they wrap instead of fitting a row. */
.ra-tail--checks { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.ra-panel { border: 1px solid var(--line); border-top: 3px solid var(--ac, var(--charcoal));
            border-radius: var(--radius); padding: 14px 16px; background: var(--surface); }
.ra-panel h3 { margin: 0 0 8px; font-size: .95rem; font-weight: 700; }
.ra-panel p { margin: 0 0 10px; font-size: .82rem; color: var(--ink-soft); }
.ra-bands { width: 100%; border-collapse: collapse; font-size: .82rem; }
.ra-bands td { padding: 3px 0; color: var(--ink-soft); }
.ra-bands td:first-child { width: 46px; }
.ra-who { margin: 0; font-size: .82rem; }
.ra-who dt { font-size: .68rem; text-transform: uppercase; letter-spacing: .05em;
             color: var(--muted); font-weight: 700; margin: 8px 0 2px; }
.ra-who dt:first-child { margin-top: 0; }
.ra-who dd { margin: 0; color: var(--ink-soft); }
.ra-fine { font-size: .74rem; color: var(--muted); margin: 10px 0 0; }

.ra-table { table-layout: fixed; }
/* .gtable th is nowrap, which suits a two or three column table and collides at
   five. These headings are sentences. */
.ra-table th { white-space: normal; }
.ra-table th:nth-child(1), .ra-table td:nth-child(1) { width: 18%; }
.ra-table th:nth-child(2), .ra-table td:nth-child(2) { width: 15%; }
.ra-table th:nth-child(3), .ra-table td:nth-child(3) { width: 17%; }
.ra-table th:nth-child(4), .ra-table td:nth-child(4) { width: 36%; }
.ra-table th:nth-child(5), .ra-table td:nth-child(5) { width: 14%; }

/* An activity heading inside the station's table. A station may hold three
   activities and the rows have to stay attributable to one of them. */
.ra-table tr.ra-group td {
  background: var(--fill); color: var(--ink); font-weight: 700;
  font-size: .78rem; text-transform: uppercase; letter-spacing: .07em;
  padding: 8px 16px;
}

.ra-sc { font-variant-numeric: tabular-nums; }
.ra-score {
  display: inline-block; font-weight: 700; font-size: .84rem; color: var(--ink);
  border-left: 4px solid var(--sc, var(--charcoal)); background: var(--fill);
  border-radius: 4px; padding: 4px 9px; line-height: 1.25;
}
.ra-score.b1, .ra-score.b2 { --sc: var(--green); }
.ra-score.b3 { --sc: var(--orange); }
.ra-score.b4, .ra-score.b5 { --sc: var(--red); }
.ra-sc small { display: block; color: var(--muted); margin-top: 5px; font-size: .76rem; line-height: 1.35; }

/* proposed / open on a row. A reader months later has to be able to tell a
   reasoned line from an observed one without archaeology. */
.ra-flag {
  display: inline-block; margin-left: 7px; vertical-align: 2px;
  font-size: .66rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  border: 1px solid var(--fc, var(--muted)); color: var(--fc, var(--muted));
  border-radius: 3px; padding: 1px 5px;
}
.ra-flag--proposed { --fc: var(--charcoal); }
.ra-flag--open { --fc: var(--red); }

.ra-gaps { font-size: .93rem; color: var(--ink-soft); margin: 16px 0 0; padding-left: 1.15em; }

/* A list you tick on paper. Named generally because it is not only a risk
   assessment thing: any list that gets printed and worked through wants it.
   NB `.ticks` is used on four pages in this workspace and is defined nowhere;
   use this instead and do not copy that one. */
.checklist { list-style: none; margin: 0; padding: 0; font-size: .82rem; color: var(--ink-soft); }
.checklist li { position: relative; padding: 5px 0 5px 24px; border-top: 1px solid var(--line-soft); }
.checklist li:first-child { border-top: 0; }
.checklist li::before {
  content: ""; position: absolute; left: 0; top: 7px; width: 13px; height: 13px;
  border: 1.5px solid var(--ink-soft); border-radius: 3px;
}

@media print {
  /* The global print block above is written for .tcard table cards: it hides
     the hero and the section titles and gives every card its own sheet. A risk
     assessment needs the opposite, so put it all back, scoped to .ra.

     The whole of this block is sized to one target: a station sheet on one
     double-sided A4, which is what Liber prints. Everything here is a page-count
     decision, so change a size only if you re-measure the page count after. */
  .ra .hero { display: block; max-width: none; padding: 0 0 5pt; }
  .ra .hero h1 { font-size: 15pt; margin: 0; }
  .ra .hero h1 .rule { display: none; }
  .ra .hero .eyebrow { font-size: 6.6pt; margin-bottom: 3pt; }
  .ra .hero p.lede { font-size: 8pt; margin: 4pt 0 0; max-width: none; }
  .ra .section { display: block; max-width: none; padding: 0; margin: 0 0 7pt; }
  .ra .section__title { display: block; font-size: 10pt; margin: 0 0 4pt; padding-bottom: 2pt;
                        page-break-after: avoid; break-after: avoid; }
  .ra .stats, .ra .launch, .ra .cards, .ra .toc { display: none; }

  .ra .gtable { font-size: 7.1pt; margin: 4pt 0 0; }
  .ra .gtable th { font-size: 7.1pt; padding: 2.5pt 4pt; border-width: .8pt; }
  .ra .gtable td { padding: 2.5pt 4pt; border-width: .8pt; line-height: 1.25; }
  .ra .gtable ul { padding-left: .95em; }
  .ra .gtable li { margin: .6pt 0; }
  .ra .gtable tr { page-break-inside: avoid; break-inside: avoid; }
  /* The <thead> repeats on every sheet, so page two is not five unlabelled columns. */
  .ra .gtable thead { display: table-header-group; }
  .ra .ra-group td { font-size: 6.6pt; padding: 3pt 5pt; }
  .ra .ra-score { font-size: 6.8pt; padding: 1.5pt 4pt; }
  .ra .ra-sc small { font-size: 6.2pt; margin-top: 3pt; }
  .ra .ra-flag { font-size: 5.4pt; padding: 0 3pt; }
  .ra .ra-scope, .ra .ra-gaps { font-size: 7pt; margin: 5pt 0 0; max-width: none; }

  .ra .ra-head { margin: 0 0 6pt; grid-template-columns: repeat(6, 1fr); }
  .ra .ra-head__cell.span2 { grid-column: span 2; }
  .ra .ra-head__cell.span3 { grid-column: span 3; }
  .ra .ra-head__cell { padding: 2.5pt 5pt; }
  .ra .ra-head dt { font-size: 5.4pt; margin-bottom: .5pt; }
  .ra .ra-head dd { font-size: 6.9pt; line-height: 1.25; }
  .ra .callout { padding: 4pt 7pt; margin: 0; font-size: 7pt; border-left-width: 3pt;
                 line-height: 1.3; }

  /* Three columns at the foot, laid out with FLOATS in print, though the screen
     uses grid. This is not a style preference and it is worth a paragraph, because
     it cost a page per sheet and looked like a height problem when it is not.

     Chrome will not place a grid, flex or table container into the space left on a
     page after a fragmented table. It pushes the whole container to a fresh page
     however small it is: a two-item version measured 147pt against 270pt of free
     space and still jumped. A bare <p>, a bordered <div>, a float and an
     inline-block in the same position all land correctly. Measured on
     tool-area.pdf, 27 August 2026; the ladder is in
     skill-notes/generating-risk-assessments.md. */
  .ra .ra-tail { display: block; margin-top: 3pt; overflow: hidden; }
  .ra .ra-tail > .ra-panel { float: left; width: 32%; margin-right: 2%;
                             page-break-inside: avoid; break-inside: avoid; }
  .ra .ra-tail > .ra-panel:last-child { margin-right: 0; }
  /* Seven or eight check panels, so they run three to a row and wrap. */
  .ra .ra-tail--checks > .ra-panel:nth-child(3n) { margin-right: 0; }
  .ra .ra-tail--checks > .ra-panel { margin-bottom: 7pt; }
  .ra .ra-panel { padding: 4pt 6pt; border-width: .8pt; border-top-width: 2pt; }
  .ra .ra-panel h3 { font-size: 7.6pt; margin-bottom: 2pt; }
  .ra .ra-panel p { font-size: 6.1pt; margin-bottom: 3pt; line-height: 1.25; }
  .ra .ra-bands, .ra .ra-who, .ra .checklist { font-size: 6.4pt; line-height: 1.3; }
  .ra .ra-bands td { padding: 1.5pt 0; }
  .ra .ra-who dt { font-size: 5.4pt; margin-top: 3pt; }
  .ra .checklist li { padding: 1.5pt 0 1.5pt 10pt; }
  .ra .checklist li::before { width: 6.5pt; height: 6.5pt; top: 3pt; border-width: .7pt; }
  .ra #foot .section__title { display: none; }
  /* The one-document version puts every assessment on its own page, so a station
     is never read across a fold with the one before it (Liber, 27 August 2026).
     The station sheets do not use this: they are two sides each by design. */
  .ra .ra-page { page-break-before: always; break-before: page; }
  /* The base .foot carries 44px of margin and 24px of padding, which at the end of
     a full page is enough to spill a whole sheet holding nothing but the footer.
     Reset all of it, not just the top. */
  .ra .foot { font-size: 6.2pt; max-width: none; margin: 4pt 0 0; padding: 3pt 0 0;
              gap: 4pt; page-break-before: avoid; break-before: avoid; }
}
  .ra .gtable li { margin: 1.5pt 0; }
  /* A row that splits across a page break loses which control belongs to which
     hazard, which is the whole readable unit. Rows here are short enough that
     avoid does not strand a heading; the tables themselves break freely. */
  .ra .gtable tr { page-break-inside: avoid; break-inside: avoid; }
  /* The hazard table's <thead> repeats on every sheet, so page two is not five
     unlabelled columns. Keeping a heading with what it introduces is the other
     half: a heading alone at the foot of a page is the classic print fault here. */
  .ra .gtable thead { display: table-header-group; }
  .ra .section__title { page-break-after: avoid; break-after: avoid; }
  .ra .ra-score { font-size: 7.5pt; padding: 2pt 5pt; }
  .ra .ra-sc small { font-size: 6.8pt; }
  .ra .ra-flag { font-size: 6pt; }
  .ra .ra-scope { font-size: 8pt; margin: 6pt 0 0; max-width: none; }

  /* Each of the four blocks starts a fresh sheet, so the station's own hazards
     are never read on the same page as the room's. */
  .ra #event, .ra #scoring, .ra #before { page-break-before: always; break-before: page; }
}
