/* ==========================================================================
   Shared design system.
   Each section overrides --accent on <body class="s-painting"> etc.
   ========================================================================== */

:root{
  --ground:#242220;
  --ground-2:#302D29;
  --ground-3:#3C3833;
  --bone:#F4F0E6;
  --bone-dim:#BFB8A8;
  --rust:#E58466;
  --line:rgba(244,240,230,.14);

  /* Three accent steps, not two. Darkening an accent on a dark ground removes
     contrast instead of softening it — the old two-step scale put both steps
     below the WCAG floor (1.58:1 and 2.75:1). Roles are now separate:
       --accent        text and links. Must clear 4.5:1 on --ground.
       --accent-solid  fills, focus rings, the card corner fold. Pairs with
                       --ink-on-accent for text sitting on top of it.
       --accent-lo     borders and rules only. Never text. */
  --accent:#B99FE0;
  --accent-solid:#9478D6;
  --accent-lo:#453458;
  --ink-on-accent:#1A1815;

  --display:"Bricolage Grotesque",system-ui,sans-serif;
  --body:"IBM Plex Sans",system-ui,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,monospace;

  /* Type scale — every font-size on the site is one of these six steps
     (plus fluid clamp() for display headings, and .mark's 12px brand
     exception). Collapsing what used to be ~15 near-arbitrary sizes. */
  --fs-micro:9px;   /* decorative tags: "not written yet", pending marks */
  --fs-2xs:10px;    /* small mono labels: table headers, stat-line meta */
  --fs-xs:11px;     /* ui mono: eyebrow, nav, jump, crumb, footer */
  --fs-sm:13.5px;   /* support/secondary body text */
  --fs-md:15px;     /* component labels: card titles, list item names */
  --fs-base:16px;   /* primary reading text */

  /* Heights of the two sticky bars. Both are measured at runtime by
     sticky-offsets.js because the sitebar wraps to a variable height on
     narrow screens and the jump nav wraps to a variable number of rows.
     These defaults are the desktop values, so everything still lands in
     roughly the right place with JS disabled. */
  --bar-h:56px;
  --jump-h:0px;

  /* Hazard stripe. Deliberately not the accent: it is a caution-tape device,
     and on the neutral index an accent-coloured stripe stops reading as
     hazard tape at all. Fixed across sections for that reason. */
  --hazard:#B8933F;
}

body.s-painting{--accent:#B99FE0;--accent-solid:#9478D6;--accent-lo:#453458;}
body.s-rules{--accent:#D8B564;--accent-solid:#B8933F;--accent-lo:#57441F;}

/* The accent says which half of the site you are in — bench or table. The
   landing page is in neither; it is the index to both. Wearing either section
   colour there makes the other half feel like the odd one out, so the index
   goes neutral and both halves are an equal step away from it. Emphasis that
   the section pages carry with hue, the index carries with luminance. */
body.s-index{--accent:#F4F0E6;--accent-solid:#E6DFCE;--accent-lo:#4A463F;}

/* ---------- modern reset (Josh Comeau) ---------- */

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

html{
  -webkit-text-size-adjust:100%;text-size-adjust:100%;scroll-behavior:smooth;
  /* Anchor targets have to clear both sticky bars, or a jump link drops the
     heading behind them. */
  scroll-padding-top:calc(var(--bar-h) + var(--jump-h) + 16px);
}

body{-webkit-font-smoothing:antialiased;}

img, picture, video, canvas, svg{display:block;max-width:100%;} /* max-width-ok: never overflow */

input, button, textarea, select{font:inherit;}

p, h1, h2, h3, h4, h5, h6{overflow-wrap:break-word;}

h1, h2, h3{text-wrap:balance;}

ul[class], ol[class]{list-style:none;margin:0;padding:0;}

/* ---------- base ---------- */

body{
  background:var(--ground);
  background-image:
    radial-gradient(rgba(244,240,230,.035) 1px, transparent 1px),
    radial-gradient(rgba(0,0,0,.4) 1px, transparent 1px);
  background-size:7px 7px, 11px 11px;
  background-position:0 0, 3px 4px;
  color:var(--bone);
  font-family:var(--body);
  font-size:var(--fs-base);
  line-height:1.5;
}

.wrap{max-width:min(1600px, 94vw);margin:0 auto;padding:0 20px;} /* max-width-ok: the one content column */

/* ---------- text spans the column ----------
   .wrap is the only thing that decides how wide text gets. Headings and body
   copy always run its full width — no ch-based measure caps. This has been
   reintroduced and removed several times; `npm run check` fails the build on
   any new max-width in a stylesheet that isn't marked `max-width-ok`. */

.hero h1, .hero h2, .hero p,
.section > h2, .sub, .hero-lede{max-width:none;}

a{color:var(--accent);}

:focus-visible{outline:2px solid var(--accent);outline-offset:3px;}

.eyebrow{
  font-family:var(--mono);
  font-size:var(--fs-xs);
  letter-spacing:.22em;
  text-transform:uppercase;
  color:var(--bone-dim);
  margin:0 0 18px;
}

/* ---------- site header ---------- */

.sitebar{
  border-bottom:1px solid var(--line);
  position:sticky;
  top:0;
  z-index:20;
  background:rgba(36,34,32,.94);
  backdrop-filter:blur(8px);
}

.sitebar .wrap{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:20px;
  height:56px;
}

.mark{
  font-family:var(--mono);
  font-size:12px; /* deliberate one-off: sits a step above --fs-xs as the brand mark */
  letter-spacing:.2em;
  text-transform:uppercase;
  color:var(--bone);
  text-decoration:none;
  white-space:nowrap;
}

.mark b{color:var(--accent);font-weight:500;}

.sitenav-wrap{
  position:relative;
  min-width:0;
}

.sitenav-wrap::after{
  content:"";
  position:absolute;
  top:0;
  right:0;
  bottom:0;
  width:28px;
  background:linear-gradient(to right, transparent, rgba(36,34,32,.94));
  pointer-events:none;
}

.sitenav{
  display:flex;
  gap:22px;
  font-family:var(--mono);
  font-size:var(--fs-xs);
  letter-spacing:.14em;
  text-transform:uppercase;
  overflow-x:auto;
  padding-right:20px;
}

.sitenav a{
  display:inline-flex;
  align-items:center;
  color:var(--bone-dim);
  text-decoration:none;
  padding:9px 0;
  border-bottom:1px solid transparent;
  white-space:nowrap;
}

.sitenav a:hover{color:var(--bone);}
.sitenav a[aria-current="page"]{color:var(--bone);border-bottom-color:var(--accent);}

/* ---------- nav dropdowns (Factions, Painting) ---------- */

.nav-drops{
  display:flex;
  gap:22px;
  font-family:var(--mono);
  font-size:var(--fs-xs);
  letter-spacing:.14em;
  text-transform:uppercase;
  flex-shrink:0;
}

.nav-drop{position:relative;}

.nav-drop summary{
  display:inline-flex;
  align-items:center;
  gap:5px;
  color:var(--bone-dim);
  cursor:pointer;
  list-style:none;
  padding:9px 0;
  border-bottom:1px solid transparent;
  white-space:nowrap;
}

.nav-drop summary::-webkit-details-marker{display:none;}
.nav-drop summary::after{content:"▾";font-size:9px;}
.nav-drop summary:hover{color:var(--bone);}
.nav-drop summary.here{color:var(--bone);border-bottom-color:var(--accent);}
.nav-drop[open] summary{color:var(--bone);}
.nav-drop[open] summary::after{content:"▴";}

.nav-panel{
  position:absolute;
  top:100%;
  left:0;
  margin-top:8px;
  z-index:19;
  min-width:230px;
  background:var(--ground-2);
  border:1px solid var(--line);
  box-shadow:0 8px 20px rgba(0,0,0,.35);
  display:flex;
  flex-direction:column;
  padding:6px;
}

/* Where submenus stack inline rather than flying out (see below), a panel
   lists every page's sections and can run past the bottom of the screen —
   so cap it and let it scroll. This must NOT apply in the flyout case: an
   overflow value other than visible clips the flyout, which by design hangs
   outside the panel's own box. Keep this list the exact complement of the
   flyout query below. */
@media (max-width:759px), (hover:none), (pointer:coarse){
  .nav-panel{
    max-height:calc(100vh - var(--bar-h) - 24px);
    overflow-y:auto;
    overscroll-behavior:contain;
  }
}

.nav-panel a{
  display:flex;
  align-items:center;
  min-height:44px;
  padding:0 10px;
  font-family:var(--body);
  font-size:var(--fs-sm);
  font-weight:500;
  letter-spacing:normal;
  text-transform:none;
  color:var(--bone);
  text-decoration:none;
}

.nav-panel a:hover{background:var(--ground-3);}

.nav-item-group{position:relative;}

.nav-subpanel{
  display:flex;
  flex-direction:column;
  margin:0 0 2px;
  padding-left:8px;
  border-left:1px solid var(--line);
}

.nav-subpanel a{
  min-height:34px;
  font-family:var(--mono);
  font-size:var(--fs-xs);
  letter-spacing:.06em;
  text-transform:uppercase;
  font-weight:400;
  color:var(--bone-dim);
}

.nav-subpanel a:hover{color:var(--bone);background:var(--ground-3);}

/* Flyout submenus need room to the right of the panel they hang off. In a
   narrow desktop window there isn't any, and the submenu lands off-screen —
   so below this width every pointer type gets the stacked, inline submenu
   that touch devices already use. */
@media (hover:hover) and (pointer:fine) and (min-width:760px){
  .nav-subpanel{
    display:none;
    position:absolute;
    top:0;
    left:100%;
    margin:0 0 0 8px;
    min-width:200px;
    background:var(--ground-2);
    border:1px solid var(--line);
    box-shadow:0 8px 20px rgba(0,0,0,.35);
    padding:6px;
  }
  .nav-item-group:focus-within .nav-subpanel,
  .nav-item-group.sub-open .nav-subpanel{display:flex;}
}

.nav-panel-more{
  margin-top:2px;
  padding-top:10px !important;
  border-top:1px solid var(--line);
  font-family:var(--mono);
  font-size:var(--fs-2xs) !important;
  letter-spacing:.06em;
  text-transform:uppercase;
  color:var(--bone-dim) !important;
  font-weight:400 !important;
}

/* ---------- in-page jump nav ---------- */

.jump{
  display:flex;flex-wrap:wrap;gap:2px;margin-top:28px;
  position:sticky;
  top:var(--bar-h);
  z-index:15; /* under .sitebar (20), over page content */
  padding-block:8px;
  background:var(--ground);
  /* The bar lives inside .wrap, so its own box stops short of the viewport
     edge and content would scroll through the gutters. A 100vw shadow spread
     paints the background out past both edges without affecting layout (so no
     horizontal overflow); clip-path keeps that spread from bleeding upward
     while letting the soft drop shadow show below. */
  box-shadow:0 6px 12px -8px rgba(0,0,0,.55), 0 0 0 100vw var(--ground);
  clip-path:inset(0 -100vw -14px -100vw);
}

.jump a{
  font-family:var(--mono);font-size:var(--fs-xs);letter-spacing:.12em;
  text-transform:uppercase;text-decoration:none;color:var(--bone-dim);
  background:var(--ground-2);padding:9px 14px;
  transition:color .16s ease,background .16s ease;
}

.jump a:hover{color:var(--bone);background:var(--ground-3);}

/* ---------- crumb: a link to another page, styled distinctly from .jump ---------- */

.crumb{
  display:inline-flex;align-items:center;gap:6px;
  font-family:var(--mono);font-size:var(--fs-xs);letter-spacing:.12em;
  text-transform:uppercase;text-decoration:none;color:var(--bone-dim);
  background:var(--ground-2);border:1px solid var(--line);
  padding:8px 14px;margin-bottom:22px;
  transition:color .16s ease,background .16s ease,border-color .16s ease;
}

.crumb:hover{color:var(--bone);background:var(--ground-3);border-color:var(--accent-lo);}

/* ---------- rule reference: jumps into the official PDF ----------
   A real tap target, not an inline link — this gets used at a table with one
   hand, and the whole point of a rules page is being able to check the
   source. Shared by every page that cites the Core Rules. */

.rule-ref{
  display:flex;
  align-items:center;
  flex-wrap:wrap;
  gap:4px 10px;
  min-height:38px;
  margin-top:12px;
  padding:8px 12px;
  background:var(--ground-2);
  border:1px solid var(--line);
  text-decoration:none;
  transition:background .16s ease,border-color .16s ease;
}

.rule-ref:hover{background:var(--ground-3);border-color:var(--accent-lo);}

.rule-num{
  font-family:var(--mono);
  font-size:var(--fs-2xs);
  font-variant-numeric:tabular-nums;
  letter-spacing:.1em;
  color:var(--accent);
  flex:none;
}

.rule-title{
  font-size:var(--fs-sm);
  color:var(--bone);
  flex:1;
  min-width:0;
}

.rule-go{
  font-family:var(--mono);
  font-size:var(--fs-2xs);
  font-variant-numeric:tabular-nums;
  letter-spacing:.08em;
  text-transform:uppercase;
  color:var(--bone-dim);
  flex:none;
}

/* consecutive refs read as one stack rather than separate buttons */
.rule-ref + .rule-ref{margin-top:-1px;}

/* claims that are an inference from two or more rules rather than a
   sentence you can point at. Say so — the links below it are the premises,
   not a quotation. */
.rule-derived{
  margin-top:10px !important;
  padding-left:12px;
  border-left:2px solid var(--accent-lo);
  font-size:var(--fs-sm) !important;
  color:var(--bone-dim);
}

/* claims we could not trace to the core rules — deliberately not a link */
.rule-none{
  margin-top:12px !important;
  padding:8px 12px;
  border:1px dashed var(--line);
  font-family:var(--mono);
  font-size:var(--fs-2xs) !important;
  letter-spacing:.06em;
  text-transform:uppercase;
  color:var(--bone-dim);
}

/* ---------- sub-heading inside a section ----------
   A labelled break within a section, below .section > h2. Mono, so it reads
   as a label rather than competing with the display heading above it. */

.sub-head{
  font-family:var(--mono);
  font-size:var(--fs-2xs);
  font-weight:500;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--bone-dim);
  margin:34px 0 10px;
}

/* ---------- generic section ---------- */

.section{padding-top:56px;}

.section > h2{
  font-family:var(--display);
  font-weight:700;
  font-size:clamp(24px,3.4vw,34px);
  letter-spacing:-.02em;
  margin:0 0 6px;
}

/* heading-anchors.js wraps each anchored heading's own text in this link,
   so the whole heading is the tap target. The "#" marker stays visible at
   rest in accent colour — same convention as .tip below, where accent
   colour alone (no underline) signals "this has more behaviour," so it
   reads on touch without needing a hover state to discover it. */
.heading-anchor{
  color:inherit;
  text-decoration:none;
}

.heading-anchor:hover,
.heading-anchor:focus-visible{
  color:var(--accent);
  text-decoration:underline;
  text-underline-offset:.15em;
}

.heading-anchor::after{
  content:"#";
  display:inline-block;
  margin-left:12px;
  font-family:var(--mono);
  font-size:22px;
  font-weight:400;
  color:var(--accent);
  vertical-align:middle;
}

.sub{
  margin:0 0 24px;
  color:var(--bone-dim);
  font-size:var(--fs-sm);
}

.split{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:46px;
}

/* ---------- cards ---------- */

.cards{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
  gap:1px;
  background:var(--line);
  border:1px solid var(--line);
}

.card{
  display:block;
  background:var(--ground-2);
  padding:18px 16px 20px;
  transition:background .18s ease;
  color:inherit;
  text-decoration:none;
}

.card:hover{background:var(--ground-3);}

.card h3{
  font-family:var(--body);
  font-weight:600;
  font-size:var(--fs-md);
  margin:0 0 12px;
}

/* interactive cards get a folded corner, like a tagged requisition card,
   instead of a generic accent rail — a distinguishing mark that reads
   without a hover state, since this is a touch-first site */
a.card{
  position:relative;
}

a.card::before{
  content:"";
  position:absolute;
  top:0;
  right:0;
  width:0;
  height:0;
  border-style:solid;
  border-width:0 16px 16px 0;
  /* --accent-solid, not --accent-lo: this fold is the site's main "this is a
     link" affordance on a touch-first layout, so it has to read without hover. */
  border-color:transparent var(--accent-solid) transparent transparent;
  transition:border-color .16s ease;
}

a.card:hover::before{border-color:transparent var(--accent) transparent transparent;}

.card p{
  margin:12px 0 0;
  font-size:var(--fs-sm);
  color:var(--bone-dim);
  line-height:1.45;
}

.card p b{color:var(--bone);font-weight:500;}

.card.pending{
  background:transparent;
  border:1px dashed var(--line);
  cursor:default;
}

.card.pending:hover{background:transparent;}
.card.pending h3{color:var(--bone-dim);}
.card.pending h3::after{
  content:"not written yet";
  display:block;
  font-family:var(--mono);
  font-size:var(--fs-micro);
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--bone-dim);
  margin-top:6px;
}

/* ---------- numbered sequence ---------- */

.steps{list-style:none;margin:0;padding:0;counter-reset:step;}

.steps > li{
  counter-increment:step;
  display:grid;
  grid-template-columns:34px minmax(0,1fr);
  gap:14px;
  padding:11px 0;
  border-top:1px solid var(--line);
}

.steps > li:last-child{border-bottom:1px solid var(--line);}

.steps > li::before{
  content:counter(step,decimal-leading-zero);
  font-family:var(--mono);
  font-size:var(--fs-xs);
  font-variant-numeric:tabular-nums;
  color:var(--accent); /* text step, not --accent-lo: these ordinals have to be readable */
  padding-top:2px;
}

/* Scoped to the item's own name/body, not every descendant — a step can
   contain bold text or a nested list of its own without picking these up. */
.steps > li > div > b{display:block;font-weight:600;font-size:var(--fs-md);margin-bottom:2px;}
.steps > li > div > span{display:block;font-size:var(--fs-sm);color:var(--bone-dim);line-height:1.45;}
.steps > li > div > span + span{margin-top:8px;}

/* ---------- dash list ---------- */

.rules-list{list-style:none;margin:0;padding:0;}

.rules-list li{
  display:grid;
  grid-template-columns:18px minmax(0,1fr);
  gap:12px;
  padding:10px 0;
  font-size:var(--fs-sm);
  border-top:1px solid var(--line);
}

.rules-list li:last-child{border-bottom:1px solid var(--line);}

.rules-list li::before{
  content:"—";
  font-family:var(--mono);
  color:var(--rust);
  font-size:var(--fs-sm);
  line-height:1.55;
}

/* ---------- table ---------- */

.diag{width:100%;border-collapse:collapse;font-size:var(--fs-sm);}

.diag th{
  text-align:left;
  font-family:var(--mono);
  font-size:var(--fs-2xs);
  font-weight:500;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--bone-dim);
  padding:0 16px 10px 0;
  border-bottom:1px solid var(--line);
}

.diag td{
  padding:14px 16px 14px 0;
  border-bottom:1px solid var(--line);
  vertical-align:top;
  line-height:1.45;
}

.diag td:first-child{font-weight:500;width:27%;}
.diag td:nth-child(2){color:var(--bone-dim);width:31%;}
.diag td:last-child{color:var(--bone-dim);}
.diag tr:hover td{background:rgba(244,240,230,.03);}

/* ---------- fold: the shared disclosure ----------
   One collapsible entry: a summary that stays visible and is the tap target,
   a body behind the toggle. Use `.folds` on a wrapper to close the top of a
   run of them.

   Grid rather than flex for the summary: a summary long enough to wrap is an
   anonymous flex item and wraps as a whole block, stranding the +/- marker on
   the line above. Fixed columns keep the marker beside the first line however
   many lines the summary runs to. (troubleshooting.css hit this and solved it
   the same way; this is that solution, promoted.)

   Printing: a collapsed <details> prints as a list of headings with no
   content, which makes a printed reference page useless. Everything opens
   under @media print below — page-level disclosures should not re-solve it. */

.folds{border-top:1px solid var(--line);}

.fold{border-bottom:1px solid var(--line);}

.fold > summary{
  display:grid;
  grid-template-columns:16px 1fr;
  align-items:baseline;
  gap:8px 14px;
  min-height:34px; /* touch target floor */
  padding:14px 0;
  cursor:pointer;
  list-style:none;
  font-size:var(--fs-md);
  font-weight:600;
}

.fold > summary::-webkit-details-marker{display:none;}

.fold > summary::before{
  content:"+";
  font-family:var(--mono);
  font-size:var(--fs-base);
  color:var(--accent);
}

.fold[open] > summary::before{content:"–";}

.fold > summary:hover{color:var(--bone);}

/* a summary that is a one-line description rather than a name reads as body
   copy, not as a heading */
.fold > summary.as-lede{font-size:var(--fs-sm);font-weight:400;color:var(--bone-dim);}
.fold > summary.as-lede:hover{color:var(--bone);}

.fold-body{padding:0 0 20px 30px;}
.fold-body > :first-child{margin-top:0;}
.fold-body p{margin:0;color:var(--bone-dim);font-size:var(--fs-sm);line-height:1.55;}
.fold-body p + p{margin-top:11px;}
.fold-body b{color:var(--bone);}

/* ---------- fold-section: a whole page section collapsed to a row ----------
   Closed, a section is one list row and the page is an index you tap into.
   Open, the heading returns to display size and the section reads exactly as
   it did before it was ever folded. The section's own top padding goes, or
   every row would sit 56px apart and the compactness is lost. */

.fold-section{padding-top:0;}
.fold-section:first-of-type{padding-top:32px;}
.fold-section > .fold,
.fold-section > div > .fold{border-top:1px solid var(--line);margin-top:-1px;}

.fold-section .fold > summary > h2{
  display:inline;
  font-family:var(--body);
  font-size:var(--fs-md);
  font-weight:600;
  line-height:1.35;
  letter-spacing:normal;
}

.fold-section .fold[open] > summary{padding-bottom:8px;}

.fold-section .fold[open] > summary > h2{
  display:block;
  font-family:var(--display);
  font-weight:800;
  font-size:clamp(26px,4.4vw,44px);
  line-height:1.04;
  letter-spacing:-.025em;
  padding-top:10px;
}

/* A split section is two columns of prose, which is a fine way to read but a
   bad index: closed, its two folds land side by side on desktop and separated
   by the grid gap on a phone, so the run of rows loses its rhythm. Rows are
   full width, one per line, like every other section. */
.split.fold-section{display:block;}

/* The heading is a link (heading-anchors.js), and its "#" marker is meant to
   sit beside a display heading, not on every row of an index — it doubles the
   things that look tappable in a row that is already entirely a tap target.
   Show it once the section is open and the heading is a heading again. */
.fold-section .fold > summary a{color:inherit;text-decoration:none;}
.fold-section .fold:not([open]) > summary .heading-anchor{display:none;}
/* sits beside the heading rather than wrapping it, so it needs its own box */
.heading-anchor-beside{display:inline-block;vertical-align:middle;}
.heading-anchor-beside::after{margin-left:10px;}

@media (max-width:560px){
  .fold > summary{padding:13px 0;gap:8px 10px;}
  .fold-body{padding:0 0 18px 26px;}
  .fold-section .fold[open] > summary > h2{padding-top:6px;}
}

@media print{
  /* Forcing the children visible is not enough on its own: a closed <details>
     hides its content through ::details-content, not through the children's
     own display. Browsers that don't support that pseudo-element are covered
     by folds.js, which opens every details on beforeprint. */
  details.fold::details-content{content-visibility:visible !important;block-size:auto !important;}
  .fold > *{display:block !important;}
  .fold > summary::before{content:"";}
}

/* ---------- disclosure list: stratagems, expandable entries ---------- */

.strat-group{margin-bottom:36px;}

.strat-group:last-child{margin-bottom:0;}

.strat-group h2{
  font-family:var(--mono);
  font-size:var(--fs-xs);
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--accent);
  margin:0 0 10px;
}

.strat-list{list-style:none;margin:0;padding:0;border-top:1px solid var(--line);}

.strat-list > li > details{border-bottom:1px solid var(--line);}

.strat-list > li > details > summary{
  display:flex;
  flex-wrap:wrap;
  align-items:baseline;
  justify-content:space-between;
  gap:4px 12px;
  padding:14px 2px;
  cursor:pointer;
  list-style:none;
  min-height:34px;
}

.strat-list > li > details > summary::-webkit-details-marker{display:none;}

.strat-list > li > details > summary::before{
  content:"+";
  font-family:var(--mono);
  color:var(--accent);
  margin-right:10px;
  flex-shrink:0;
}

.strat-list > li > details[open] > summary::before{content:"–";}

.strat-list .strat-name{font-weight:600;font-size:var(--fs-md);flex:1;min-width:120px;}

.strat-list .strat-meta{
  font-family:var(--mono);
  font-size:var(--fs-xs);
  font-variant-numeric:tabular-nums;
  letter-spacing:.02em;
  color:var(--bone-dim);
}

/* stat-line groups (M12" T5 Sv4+ ...): dim label, bright value, real
   spacing between groups — letters and numbers in one flat run of text
   at a single weight/color are hard to parse at a glance, and this needs
   to hold up small on a phone screen, not just in a zoomed-in check */
.strat-meta .stat{
  display:inline-block;
  margin-right:14px;
  padding:2px 0;
  color:var(--bone);
  font-weight:700;
}
.strat-meta .stat:last-child{margin-right:0;}
.strat-meta .stat .k{
  color:var(--bone-dim);
  font-weight:500;
  text-transform:uppercase;
  margin-right:1px;
}

.strat-list .strat-body{
  padding:0 2px 16px 22px;
  font-size:var(--fs-sm);
  color:var(--bone-dim);
  line-height:1.5;
}

.strat-list .strat-body a{color:var(--accent);}
.strat-list .strat-body > p{margin:0 0 12px;}

/* ---------- datasheet reference table ---------- */

.datasheet-table{width:100%;border-collapse:collapse;font-size:var(--fs-sm);}

.datasheet-table th{
  text-align:left;
  font-family:var(--mono);
  font-size:var(--fs-2xs);
  font-weight:500;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--bone-dim);
  padding:0 12px 10px 0;
  border-bottom:1px solid var(--line);
}

.datasheet-table td{
  padding:12px 12px 12px 0;
  border-bottom:1px solid var(--line);
  vertical-align:top;
  font-variant-numeric:tabular-nums;
}

.datasheet-table td:first-child{font-weight:500;}
.datasheet-table td:not(:first-child){color:var(--bone-dim);}
.datasheet-table tr:hover td{background:rgba(244,240,230,.03);}

@media (max-width:560px){
  .datasheet-table thead{display:none;}
  .datasheet-table, .datasheet-table tbody, .datasheet-table tr, .datasheet-table td{
    display:block;width:100%;
  }
  .datasheet-table tr{padding:12px 0;border-bottom:1px solid var(--line);}
  .datasheet-table td{border:0;padding:2px 0;}
  .datasheet-table td:first-child{font-size:var(--fs-md);margin-bottom:2px;}
}

/* ---------- painting log ---------- */

.paint-log{list-style:none;margin:0;padding:0;border-top:1px solid var(--line);}

.paint-log li{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1.4fr);
  gap:14px;
  padding:12px 0;
  border-bottom:1px solid var(--line);
  font-size:var(--fs-sm);
}

.paint-log b{display:block;font-weight:600;font-size:var(--fs-md);}
.paint-log .status{
  font-family:var(--mono);
  font-size:var(--fs-2xs);
  letter-spacing:.1em;
  text-transform:uppercase;
  color:var(--accent);
}
.paint-log .paints{color:var(--bone-dim);font-size:var(--fs-sm);}

@media (max-width:560px){
  .paint-log li{grid-template-columns:1fr;gap:4px;}
}

.note-block{
  border:1px dashed var(--line);
  padding:16px 18px;
  margin-top:20px;
  font-size:var(--fs-sm);
  color:var(--bone-dim);
}

.note-block b{color:var(--bone);}

/* ---------- note box: the standing "the official rules win" footer ----------
   Lived in four page stylesheets as four copies that had already drifted —
   two of them hardcoded 13.5px instead of --fs-sm and were missing the
   paragraph spacing, so their multi-paragraph boxes ran together. One copy. */

.note-box{
  margin-top:56px;
  padding:20px 22px;
  border:1px dashed var(--line);
}

.note-box p{margin:0;color:var(--bone-dim);font-size:var(--fs-sm);line-height:1.55;}
.note-box p + p{margin-top:12px;}
.note-box b{color:var(--bone);}

/* ---------- reference search/filter ---------- */

.ref-search{
  display:block;
  width:100%;
  background:var(--ground-2);
  border:1px solid var(--line);
  color:var(--bone);
  font-family:var(--body);
  font-size:var(--fs-md);
  padding:12px 14px;
  min-height:44px;
  margin:24px 0 4px;
}

.ref-search::placeholder{color:var(--bone-dim);}
.ref-search:focus{outline:none;border-color:var(--accent);}

.ref-empty{padding:20px 2px;color:var(--bone-dim);font-size:var(--fs-sm);}

/* ---------- stat/weapon abbreviation glossary ---------- */

.legend{
  display:flex;
  flex-wrap:wrap;
  gap:6px 16px;
  margin:20px 0 28px;
  padding:0;
  list-style:none;
}

.legend li{
  font-family:var(--mono);
  font-size:var(--fs-2xs);
  color:var(--bone-dim);
}

.legend b{color:var(--bone);font-weight:700;letter-spacing:.02em;}

/* ---------- unit keyword tags ---------- */

.kw-list{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 16px;list-style:none;padding:0;}

.kw-list li{
  font-family:var(--mono);
  font-size:var(--fs-2xs);
  letter-spacing:.06em;
  text-transform:uppercase;
  color:var(--bone-dim);
  background:var(--ground-3);
  padding:4px 8px;
}

/* ---------- inline tooltips: ability/weapon keywords ----------
   Tap to open on any device (native <details>, zero JS) — on devices
   with a real mouse, also open on hover so you don't need to tap at
   all. Never hover-only: this site is touch-first. */

.tip{display:inline-block;position:relative;}

.tip summary{
  display:inline;
  cursor:help;
  list-style:none;
}

.tip summary::-webkit-details-marker{display:none;}

/* accent color alone marks a term as having a tooltip — no underline,
   which reads as clutter once several tags sit close together (kw-list
   chips already have a pill background; wpn-tags already uses accent
   for all its text). */
.kw-list .tip summary{color:var(--accent);}

.tip-panel{
  position:absolute;
  bottom:100%;
  left:0;
  margin-bottom:8px;
  z-index:25;
  width:max-content;
  max-width:240px; /* max-width-ok: tooltip panel, not body copy */
  background:var(--ground-3);
  border:1px solid var(--line);
  box-shadow:0 8px 20px rgba(0,0,0,.35);
  padding:10px 12px;
  font-family:var(--body);
  font-size:var(--fs-sm);
  font-weight:400;
  text-transform:none;
  letter-spacing:normal;
  color:var(--bone);
  line-height:1.4;
}

@media (hover:hover) and (pointer:fine){
  .tip:hover .tip-panel{display:block;}
}

/* ---------- weapon profile table ---------- */

.wpn-table{width:100%;border-collapse:collapse;font-size:var(--fs-sm);margin:0 0 16px;}

.wpn-table th{
  text-align:right;
  font-family:var(--mono);
  font-size:var(--fs-2xs);
  font-weight:500;
  letter-spacing:.08em;
  text-transform:uppercase;
  color:var(--bone-dim);
  padding:0 0 8px 10px;
  border-bottom:1px solid var(--line);
}

.wpn-table th:first-child{text-align:left;padding-left:0;}

.wpn-table td{
  padding:9px 0 9px 10px;
  border-bottom:1px solid var(--line);
  vertical-align:top;
  text-align:right;
  font-variant-numeric:tabular-nums;
}

.wpn-table td:first-child{
  text-align:left;
  padding-left:0;
  font-weight:500;
  color:var(--bone);
}

.wpn-table .wpn-tags{
  display:block;
  font-family:var(--mono);
  font-size:var(--fs-micro);
  letter-spacing:.04em;
  text-transform:uppercase;
  color:var(--accent);
  font-weight:400;
  margin-top:2px;
  white-space:normal;
}

@media (max-width:560px){
  .wpn-table thead{display:none;}
  .wpn-table, .wpn-table tbody{display:block;width:100%;}
  .wpn-table tr{
    display:grid;
    grid-template-columns:repeat(3, 1fr);
    gap:6px;
    padding:10px 0;
    border-bottom:1px solid var(--line);
  }
  .wpn-table td{border:0;padding:0;text-align:left;font-variant-numeric:tabular-nums;}
  .wpn-table td:first-child{grid-column:1 / -1;margin-bottom:2px;}
  .wpn-table td:not(:first-child){
    display:flex;
    flex-direction:column;
    gap:2px;
    background:var(--ground-3);
    padding:5px 7px;
    font-family:var(--mono);
    font-size:var(--fs-sm);
    font-weight:600;
    color:var(--bone);
  }
  .wpn-table td:not(:first-child)::before{
    font-weight:400;
    font-size:var(--fs-micro);
    letter-spacing:.06em;
    text-transform:uppercase;
    color:var(--bone-dim);
  }
  .wpn-table td:nth-child(2)::before{content:"Rng";}
  .wpn-table td:nth-child(3)::before{content:"A";}
  .wpn-table td:nth-child(4)::before{content:"Skill";}
  .wpn-table td:nth-child(5)::before{content:"S";}
  .wpn-table td:nth-child(6)::before{content:"AP";}
  .wpn-table td:nth-child(7)::before{content:"D";}
}

/* ---------- named ability list ---------- */

.ability-list{margin:0;padding:0;}

.ability-list div{padding:10px 0;border-top:1px solid var(--line);}

.ability-list dt{font-weight:600;font-size:var(--fs-sm);margin-bottom:3px;}

.ability-list dd{margin:0;font-size:var(--fs-sm);color:var(--bone-dim);line-height:1.5;}

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

.sitefoot{
  margin-top:64px;
  padding:20px 0 60px;
  border-top:1px solid var(--line);
  font-family:var(--mono);
  font-size:var(--fs-xs);
  letter-spacing:.1em;
  text-transform:uppercase;
  color:var(--bone-dim);
}

.sitefoot .wrap{display:flex;flex-wrap:wrap;column-gap:10px;row-gap:4px;}

.sitefoot p{margin:0;}

.sitefoot p:not(:last-child)::after{content:"·";margin-left:10px;}

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

@media (max-width:820px){
  .split{grid-template-columns:1fr;gap:38px;}
  .diag td:first-child,
  .diag td:nth-child(2){width:auto;}
}

@media (max-width:560px){
  .wrap{padding:0 16px;}
  /* Wrapped, the jump nav is two or three rows tall — stuck under an
     already-tall mobile sitebar that eats a third of the viewport. One
     scrolling row instead; a part-cut chip at the edge shows there's more. */
  .jump{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;}
  .jump::-webkit-scrollbar{display:none;}
  .jump a{white-space:nowrap;}
  .sitebar .wrap{height:auto;padding-top:10px;padding-bottom:10px;
    flex-direction:column;align-items:flex-start;gap:8px;}
  .sitenav-wrap{width:100%;}
  .sitenav{width:100%;gap:16px;}
  .diag,.diag tbody,.diag tr,.diag td{display:block;width:100%;}
  .diag thead{display:none;}
  .diag tr{padding:14px 0;border-bottom:1px solid var(--line);}
  .diag td{border:0;padding:0 0 5px;}
  .diag td:first-child{font-size:var(--fs-md);}

  /* on a phone the rule number and page sit on one line and the title gets
     the full width below them — sharing a row squeezes the title into a
     four-word-per-line column */
  .rule-ref{padding:10px 12px;}
  .rule-go{margin-left:auto;}
  .rule-title{flex:1 0 100%;order:3;}
}

@media (prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important;scroll-behavior:auto!important;}
}

@media print{
  body{background:#fff;color:#111;}
  .sitebar,.sitefoot{display:none;}
  .jump{position:static;box-shadow:none;clip-path:none;background:none;}
  .card,.ladder{background:#fff;}
  .section{break-inside:avoid;}
  /* a filter box and its result count are controls, not content — on paper
     every entry is already there and there is nothing to type into */
  .ref-search,.ref-count,.ref-empty{display:none;}
}
