/* ============================================================
   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--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; }
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 (max-width: 980px) { .launch--4 { grid-template-columns: repeat(2, 1fr); } }
@media (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; }

/* 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 (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 (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 (max-width: 620px) { .gtable th { white-space: normal; font-size: .85rem; } }
.gtable ul { margin: 0; padding-left: 1.15em; }
.gtable li { margin: 4px 0; }

/* 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 (max-width: 720px) { .cols2grid { grid-template-columns: 1fr; } .cols2grid .col:first-child .block:last-child { margin-bottom: 32px; } }

/* two-column bullet list */
.cols2list { columns: 2; column-gap: 40px; }
.cols2list > li { break-inside: avoid; margin-bottom: 10px; }
@media (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 (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 (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 (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); }

/* 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)); }

/* ---- 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); }

/* ---- 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 (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 (max-width: 760px) { .stats { grid-template-columns: repeat(3, 1fr); } .hero h1 { font-size: 1.9rem; } .toc ol { columns: 1; } }
@media (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 (max-width: 560px) { .packlist label { padding: 9px 2px; } }
