/* ===================================================================
   MANON'S BATTLE ATLAS — PROTOTYPE
   One stylesheet for every page. This is the file that becomes the
   real one, so the rules live here rather than in the markup:

   TYPE     page H1 = Booton 800 · item/list headers = 600
            short names + numerals = 800 · reading = Bureau Serif 300
            one pull quote per article = Booton 200
            every label = Bureau Semi Mono, uppercase, tracked
            Walkout is never set — it only arrives on rollover
   COLOUR   ground is paper, bone or a pillar tint. Blue is a fact
            plate. Lilac is a sheet you opened, and the Register's
            ground. Pink is contested. Orange is the ask. Neon marks
            today, behind a few words, never as a field.
   RADIUS   4px on tiles, cards and picture blocks · pills on every
            control · 26px on a raised sheet
   =================================================================== */

@font-face{font-family:"Booton";src:url("/total-battle/fonts/web/BootonUprightsVF.woff2") format("woff2-variations");font-weight:100 900;font-style:normal;font-display:swap}
@font-face{font-family:"Booton";src:url("/total-battle/fonts/web/BootonItalicsVF.woff2") format("woff2-variations");font-weight:100 900;font-style:italic;font-display:swap}
@font-face{font-family:"BureauSerif";src:url("/total-battle/fonts/web/STKBureauSerifVariableComplete.woff2") format("woff2-variations");font-weight:150 700;font-style:normal;font-display:swap}
@font-face{font-family:"BureauMono";src:url("/total-battle/fonts/web/BureauSemiMono-Medium.woff2") format("woff2");font-weight:500;font-display:swap}
@font-face{font-family:"BureauMono";src:url("/total-battle/fonts/web/BureauSemiMono-Book.woff2") format("woff2");font-weight:400;font-display:swap}
@font-face{font-family:"Walkout";src:url("/total-battle/fonts/web/TAYWalkout.woff2") format("woff2");font-weight:400;font-display:swap}

:root{
  --ink:#111110; --ink-2:#2e2e2a; --grey:#6b6b62; --grey-2:#9d9d93;
  --paper:#fff; --bone:#f4f1e9; --sand:#e6e0d3; --rule:#dedacf;
  --charcoal:#1c1c1a;
  --blue:#1b23ff; --acid:#e6ff2e; --lilac:#cec5ff; --pink:#ffbcec; --flare:#ff4a17; --neon:#47ffb6;
  /* Target met. Sits with lilac and pink as a soft tone rather than competing
     with acid, which is the loud one. Far enough round the wheel from acid's
     yellow-green (hue 67 against 129) that the two never read as the same
     signal, even though both are green-ish. */
  --jade:#82f894;
  --r:4px; --r-pill:999px; --r-sheet:26px;
  --ph-line:rgba(17,17,16,.28);
  --sans:"Booton",-apple-system,Helvetica,Arial,sans-serif;
  --mono:"BureauMono",ui-monospace,Menlo,monospace;
  --serif:"BureauSerif",Georgia,serif;
  --script:"Walkout","Booton",sans-serif;
  --nav-h:66px;
  /* The footer rides the bottom of the window, so the window is not
     the space a sticky pane actually has. Everything that sizes
     itself to the viewport subtracts this too, or its last rows sit
     under the footer for the whole of the scroll. Measured at 49px
     (16px padding, 10px mono line, 1.4px rule) and re-measured in
     proto.js, since the copy wraps to two lines on a narrow window. */
  --foot-h:49px;
  /* The kingdom band, where there is one. Zero everywhere else, so
     the offsets below are the same arithmetic on every page. Measured
     in proto.js, because the band wraps to two lines on a phone. */
  --kband-h:0px;
  /* The bottom edge of whatever is pinned to the top of the window.
     Everything that sticks hangs off this rather than off --nav-h, or
     it slides under the band on the kingdom pages. */
  --top-h:calc(var(--nav-h) + var(--kband-h));
  /* The measure a long read is set to. Past this the column stops
     growing and the extra width goes to the sources rail instead. */
  --read-max:960px;
  --view-h:calc(100dvh - var(--top-h) - var(--foot-h));
  /* motion — one soft curve, one with a little overshoot, and two speeds */
  --ease:cubic-bezier(.22,.8,.24,1);
  --ease-spring:cubic-bezier(.22,1.15,.36,1);
  --dur:.42s; --dur-slow:.62s; --dur-fast:.22s;
}

*{box-sizing:border-box}
html{-webkit-font-smoothing:antialiased;scroll-behavior:smooth;
  /* an anchor jump lands clear of both bars, not tucked under them */
  scroll-padding-top:var(--top-h);scroll-padding-bottom:var(--foot-h)}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--sans);font-weight:300;font-size:16px;line-height:1.5}
a{color:inherit;text-decoration:none}

/* ---------- type ---------- */
.h1{font-size:clamp(38px,4.6vw,58px);font-weight:800;letter-spacing:-.036em;line-height:1.02;margin:0}
.h2{font-size:clamp(24px,2.4vw,32px);font-weight:600;letter-spacing:-.024em;line-height:1.12;margin:0}
.h3{font-size:21px;font-weight:600;letter-spacing:-.02em;line-height:1.18;margin:0}
.lede{font-family:var(--serif);font-weight:300;font-size:clamp(17px,1.5vw,21px);line-height:1.45;margin:0}
.body{font-family:var(--serif);font-weight:300;font-size:17px;line-height:1.55;margin:0}
.quote{font-size:clamp(30px,3.4vw,42px);font-weight:200;letter-spacing:-.024em;line-height:1.16;margin:0}
.mono{font-family:var(--mono);font-size:10px;font-weight:500;letter-spacing:.15em;text-transform:uppercase}
/* The Atlas never sets the serif in capitals. .mono carries both the face and
   the capitals, but at one class it loses the face to any container that
   styles its own paragraphs — ".entry-body p" is two classes and was winning,
   which left "Written up in" as uppercase serif. The guard is a real selector
   rather than !important: :root costs a class, so this lands at two and holds
   the face wherever a label is dropped into body copy. */
:root p.mono,:root li.mono,:root span.mono,:root div.mono
  {font-family:var(--mono);font-size:10px;letter-spacing:.15em}
:root p.mono-s,:root span.mono-s,:root div.mono-s
  {font-family:var(--mono);font-size:9px;letter-spacing:.13em}
.mono-s{font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.13em;text-transform:uppercase}
.num{font-weight:800;letter-spacing:-.04em;font-variant-numeric:tabular-nums;line-height:1}
.grey{color:var(--grey)}
.mk{background:var(--acid);box-decoration-break:clone;padding:0 3px}

/* ---------- chrome ---------- */
.nav{position:sticky;top:0;z-index:50;background:var(--charcoal);color:var(--bone);display:flex;align-items:center;gap:26px;padding:0 clamp(16px,3vw,40px);height:var(--nav-h)}
/* The wordmark is a block, not a line of text: full bar height, and
   it runs out to the left edge of the window. That block is the zone
   the drawing answers to, so it wants a real area rather than the
   exact outline of the letters. */
.nav .mark{font-family:var(--script);font-size:30px;letter-spacing:.02em;
  white-space:nowrap;line-height:1;
  display:inline-flex;align-items:center;height:100%;
  margin-left:calc(-1 * clamp(16px,3vw,40px));
  padding-left:clamp(16px,3vw,40px);padding-right:24px}
.nav-links{position:relative;display:flex;gap:6px;font-family:var(--mono);font-size:11px;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;color:rgba(244,241,233,.6);margin-left:auto}
.nav-links a{position:relative;z-index:1;display:inline-flex;align-items:center;line-height:1;
  padding:8px 11px 8px;border-radius:var(--r-pill)}
.nav-links a:hover{color:var(--ink)}
/* whatever the pill is sitting under takes ink, always — the pill and the
   colour are set together so the label can never be light-on-acid */
.nav-links a.lit{color:var(--ink)}
.nav-pill{position:absolute;top:50%;left:0;height:26px;margin-top:-13px;border-radius:var(--r-pill);
  background:var(--acid);z-index:0;opacity:0;
  transition:transform .42s cubic-bezier(.34,1.42,.5,1),width .42s cubic-bezier(.34,1.42,.5,1),opacity .2s var(--ease)}
.nav-pill.ready{opacity:1}
@media (prefers-reduced-motion:reduce){.nav-pill{transition:opacity .2s linear}}
.nav-search{display:inline-flex;align-items:center;gap:9px;font-family:var(--mono);font-size:11px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;border:1px solid rgba(244,241,233,.45);border-radius:var(--r-pill);padding:9px 16px;color:var(--bone);white-space:nowrap;cursor:pointer;transition:border-color var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}
.nav-search:hover{border-color:var(--acid);color:var(--acid)}
/* The glyph carried the whole control at 11px and read as punctuation.
   A drawn magnifier at 15px reads as a button. */
.nav-search svg{width:15px;height:15px;flex:none;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round}
/* Sign in sits at the end of the bar, quieter than the search beside
   it — it is the thing you need once, not constantly. */
/* The bar is a fixed set of things in a shrinking space, and between the
   desktop layout and the 900px burger it simply ran out — at 1280px it wanted
   1536px, so the search control was clipped mid-word and Sign in was pushed
   off the edge entirely.

   The widths below are measured, not guessed. Whole bar: 1510px. Without
   "the Atlas": 1433px. Icon only, with the gaps and link padding tightened:
   about 1250px. Each rule starts just above the width its own layout needs.

   The search gives way first, because it is the one control whose meaning
   survives being shortened — a magnifier says what it does on its own. The
   links are the last thing to go, at 900px, to the burger. */
@media(max-width:1520px){
  .nav-search .ns-more{display:none}
}
@media(max-width:1440px){
  .nav{gap:18px}
  .nav-search .ns-word{display:none}
  .nav-search{padding:9px 11px;gap:0}
  .nav-links{gap:2px}
  .nav-links a{padding-left:8px;padding-right:8px}
}
@media(max-width:1120px){
  .nav{gap:14px}
  .nav .mark{font-size:24px}
  .nav-links{font-size:9.5px;letter-spacing:.07em}
  .nav-links a{padding-left:5px;padding-right:5px}
}
/* The last stretch before the burger. Nine links at 9.5px will not compress
   further and stay tappable, so the wordmark gives way instead — which is
   what the 900px rule below already says the mark is for. */
@media(max-width:1010px){
  .nav{gap:10px}
  .nav .mark{font-size:20px}
}
.nav-who{flex:none;font-family:var(--mono);font-size:10px;font-weight:500;letter-spacing:.13em;text-transform:uppercase;color:rgba(244,241,233,.62);white-space:nowrap;transition:color var(--dur-fast) var(--ease)}
.nav-who:hover{color:var(--acid)}
.nav-burger{display:none;margin-left:auto;width:34px;height:34px;border:1px solid rgba(244,241,233,.45);border-radius:50%;place-items:center}

.strip{display:flex;justify-content:space-between;align-items:baseline;gap:20px;padding:12px clamp(16px,3vw,40px);border-bottom:1px solid var(--rule);flex-wrap:wrap}
.foot{border-top:1px solid var(--rule);padding:16px clamp(16px,3vw,40px);display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;font-family:var(--mono);font-size:10px;font-weight:500;letter-spacing:.13em;text-transform:uppercase;color:var(--grey-2)}

/* page shells */
.page{min-height:100dvh;display:flex;flex-direction:column}

/* The desk is a fixed frame rather than a scrolling document: the masthead
   column and the rail each own their scroll, so a wheel over the rail moves
   the rail and nothing else. Every other page scrolls normally. */
.page--frame{height:100dvh;overflow:hidden}
.page--frame .cols{flex:1;min-height:0}
.page--frame .cols > *{min-height:0}
.page--frame .deskmain{overflow-y:auto;display:flex;flex-direction:column}
.page--frame .rail-scroll{position:static;height:100%;max-height:none}
/* the divider is painted on the grid, not the rail, so it runs the full
   height of the window even when the rail is short or sticky */
.cols{flex:1;display:grid;grid-template-columns:300px minmax(0,1fr) 340px;
  min-height:calc(100dvh - var(--nav-h));
  background-image:linear-gradient(var(--rule),var(--rule));
  background-size:1px 100%;background-position:300px 0;background-repeat:no-repeat}
.cols--2{grid-template-columns:300px minmax(0,1fr);background-position:300px 0}
/* the rail-right layouts draw their own edge on the aside, so the grid
   divider is switched off for them */
.cols--rail{grid-template-columns:minmax(0,1fr) 420px;background-image:none}
/* What you have and what you are hitting are both questions you answer, so
   they sit together; the stack is the answer and gets the room. Input on one
   side, output on the other, rather than the answer wedged between them. */
/* Both figures are the same measurement, so it is stated once — they drifted
   apart the last time one of them changed and the divider stopped landing on
   the column edge. */
:root{--sb-inputs-w:620px}
.cols--inputs{grid-template-columns:minmax(0,var(--sb-inputs-w)) minmax(0,1fr);
  background-image:linear-gradient(var(--rule),var(--rule));
  background-size:1px 100%;background-position:var(--sb-inputs-w) 0;background-repeat:no-repeat}
.sb-inputs{display:grid;grid-template-columns:1fr 1fr;
  background-image:linear-gradient(var(--rule),var(--rule));
  background-size:1px 100%;background-position:50% 0;background-repeat:no-repeat}
/* Each rail scrolls on its own. The left one runs to twenty-six troop lines
   plus monsters, mercenaries, the dragon and the command, which is far longer
   than the stack beside it — tying them together meant scrolling past the
   whole army to reach the answer.

   This was tried before and reverted, because a scroller clips an absolutely
   positioned dropdown the moment it opens. The menus are pinned to the
   viewport now instead of to their wrapper, so there is nothing left to
   clip. */
.sb-rail,.sb-side{padding:24px 24px;min-width:0;display:flex;flex-direction:column;gap:10px;
  position:sticky;top:var(--top-h);max-height:var(--view-h);overflow-y:auto;
  overscroll-behavior:contain;scrollbar-width:thin}
@media(max-width:1080px){
  .sb-rail,.sb-side{position:static;max-height:none;overflow:visible}
}
@media(max-width:1080px){
  .cols--inputs{grid-template-columns:1fr;background-image:none}
  .sb-inputs{border-bottom:1px solid var(--rule)}
}
@media(max-width:680px){
  .sb-inputs{grid-template-columns:1fr;background-image:none}
  .sb-rail{border-bottom:1px solid var(--rule)}
}
/* The rail opens on the same line as the column beside it. .main sets 30px
   and the rail set 26, which read as the outline sagging under the page. */
.rail-l{padding:30px 24px 26px;display:flex;flex-direction:column;gap:11px;font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--grey)}
.rail-l b{color:var(--ink);font-weight:500}
/* Nothing bold in a left rail goes past 500. Heavier reads as a
   second headline competing with the page's own. Said once here,
   covering every element that could carry bold, rather than left to
   each page to remember. Lighter text is not touched. */
.rail-l b,.rail-l strong,.rail-l h1,.rail-l h2,.rail-l h3,.rail-l h4,
.rail-l .idx-view,.rail-l a.on,.rail-l a.here,.rail-l .sub.here{font-weight:500}
.rail-l a{display:flex;justify-content:space-between;gap:10px}
.rail-l a:hover{color:var(--ink)}
.rail-l a.on{color:var(--ink);border-left:3px solid var(--ink);padding-left:10px}
.main{min-width:0;padding:30px clamp(16px,3vw,44px) 44px}
.side{border-left:1px solid var(--rule);padding:26px 24px}

/* ---------- controls ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;
  color:var(--paper);border-radius:var(--r-pill);padding:13px 20px;
  font-family:var(--mono);font-size:10px;font-weight:500;letter-spacing:.13em;text-transform:uppercase;cursor:pointer;
  /* the wipe is a background layer, so it can never paint over the label */
  background-color:var(--ink);
  background-image:linear-gradient(var(--blue),var(--blue));
  background-repeat:no-repeat;background-position:left center;background-size:0% 100%;
  transition:background-size .46s cubic-bezier(.34,1.4,.5,1),color .18s var(--ease),border-color .18s var(--ease)}
.btn:hover{background-size:100% 100%;color:#fff}
.btn--ghost{background-color:transparent;color:var(--ink);border:1px solid currentColor}
.btn--ghost:hover{color:#fff;border-color:var(--blue)}
@media (prefers-reduced-motion:reduce){.btn{transition:color .18s linear}.btn:hover{background-size:100% 100%}}
.pill{display:inline-flex;align-items:center;gap:6px;font-family:var(--mono);font-size:9.5px;font-weight:500;letter-spacing:.11em;text-transform:uppercase;padding:7px 12px;border-radius:var(--r-pill);border:1px solid var(--rule);color:var(--grey);white-space:nowrap}
.pill--on{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.pill--pink{background:var(--pink);border-color:var(--pink);color:var(--ink)}
.glyph{width:32px;height:32px;border-radius:50%;border:1.1px solid currentColor;display:grid;place-items:center;font-size:13px;flex:none}

/* ---------- plates, sheets, tiles ---------- */
.plate-blue{background:var(--blue);color:#fff;padding:20px 22px 22px;border-radius:var(--r)}
.plate-blue .num{font-size:clamp(44px,5vw,62px);margin:8px 0 0}
.ask{background:var(--flare);color:#fff;padding:16px 18px;border-radius:var(--r)}
.tile{position:relative;border-radius:var(--r);padding:20px 22px 22px;background:var(--tile,var(--paper));display:flex;flex-direction:column;overflow:hidden;transition:transform .4s cubic-bezier(.2,.75,.2,1),box-shadow .4s cubic-bezier(.2,.75,.2,1);will-change:transform}
.tile:hover{box-shadow:0 16px 30px -22px rgba(0,0,0,.5)}
.tile .eyebrow{font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.15em;text-transform:uppercase;color:rgba(17,17,16,.6);margin:0}
.tile h3{margin:12px 0 0;font-size:24px;font-weight:800;letter-spacing:-.03em;line-height:1.06}
.tile p{margin:11px 0 0;font-size:14px;line-height:1.5;color:rgba(17,17,16,.78)}
/* a tile filled with the same colour as the surface under it needs an edge,
   or it reads as a hole rather than an object */
.tile--outline{border:1px solid var(--rule)}
.tile .cta{align-self:flex-start;margin-top:16px;border-radius:var(--r-pill);padding:9px 14px;font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;background:var(--tile-cta,var(--paper))}
.ev{display:grid;grid-template-columns:repeat(3,1fr);gap:0;background:transparent;margin-top:22px}
.ev > div{background:transparent;padding:0 14px 0 0}
.ev > div + div{border-left:1px solid rgba(17,17,16,.2);padding-left:16px}
.ev b{display:block;font-size:26px;font-weight:800;letter-spacing:-.03em;line-height:1}
.ev span{display:block;font-family:var(--mono);font-size:8.5px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;opacity:.62;margin-top:7px}

/* ---------- placeholders ---------- */
.ph{position:relative;background:var(--paper);overflow:hidden;border-radius:var(--r)}
.ph::before{content:"";position:absolute;inset:0;background-image:repeating-linear-gradient(45deg,var(--ph-line) 0 1.5px,transparent 1.5px 10px)}
.ph--dot::before{background-image:radial-gradient(var(--ph-line) 1.3px,transparent 1.4px);background-size:11px 11px}
.ph--coarse::before{background-image:repeating-linear-gradient(45deg,var(--ph-line) 0 3px,transparent 3px 22px)}

/* ---------- list rows ---------- */
.rows{border-top:1.4px solid var(--ink)}
.row{display:grid;grid-template-columns:1fr 66px;gap:18px;align-items:center;padding:16px clamp(16px,2vw,26px);border-bottom:1px solid var(--rule)}
.row:hover{background:rgba(17,17,16,.035)}
.row h3{margin:0;font-size:clamp(20px,2vw,24px);font-weight:600;letter-spacing:-.024em;line-height:1.1}
.row .meta{display:flex;justify-content:space-between;gap:12px;margin-top:8px;font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--grey)}
.row .ph{width:66px;height:66px}
.row--on{background:rgba(255,255,255,.5)}

/* status + category marks */
.dot{width:9px;height:9px;border-radius:50%;display:inline-block;flex:none;background:var(--ink)}
.st{font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.11em;text-transform:uppercase;color:var(--grey-2);white-space:nowrap}
.st--cont{color:var(--ink);background:var(--pink);padding:3px 8px;border-radius:var(--r-pill)}
/* the category key — brighter, and still distinct at 9px on white */
.cat-mechanic{background:#111110}      /* ink stays the anchor */
.cat-gem{background:#7b5cff}           /* violet */
.cat-captain{background:#ff4fa3}       /* hot pink */
.cat-troop{background:#ff8a00}         /* amber-orange, clear of the flare */
.cat-building{background:#00c07a}      /* green */
.cat-event{background:var(--acid)}     /* the neon we already use */
.cat-resource{background:var(--blue)}  /* the blue we already use */
.cat-hero{background:#f2b705}         /* gold — one hero, one gold */
.cat-monster{background:#b0431f}      /* rust, clear of the conflict red */
.cat-equipment{background:#0f8a8a}    /* teal */
.cat-material{background:#8a6a3d}     /* bronze — the raw stuff */
.cat-enchantment{background:#b45cff}  /* violet's lighter sibling: gems enchant */
.cat-other{background:#b6b6ab}

/* Each category has a ground as well as a mark. The ground is the dot's hue
   pulled back to the lilac's weight, so a panel never shouts; the dot stays
   saturated and does the identifying. */
:root{
  --tint-mechanic:#e8e6e0;
  --tint-gem:#d0c5ff;
  --tint-captain:#ffc5e1;
  --tint-troop:#ffe4c5;
  --tint-building:#c5ffea;
  --tint-event:#f8ffc5;
  --tint-resource:#c5e0ff;
  --tint-hero:#fef0c6;
  --tint-monster:#f6d8ce;
  --tint-equipment:#cbf9f9;
  --tint-material:#ede4d7;
  --tint-enchantment:#e4c5ff;
  --tint-other:#efeee9;
}
.tint-mechanic{background:var(--tint-mechanic)}
.tint-gem{background:var(--tint-gem)}
.tint-captain{background:var(--tint-captain)}
.tint-troop{background:var(--tint-troop)}
.tint-building{background:var(--tint-building)}
.tint-event{background:var(--tint-event)}
.tint-resource{background:var(--tint-resource)}
.tint-hero{background:var(--tint-hero)}
.tint-monster{background:var(--tint-monster)}
.tint-equipment{background:var(--tint-equipment)}
.tint-material{background:var(--tint-material)}
.tint-enchantment{background:var(--tint-enchantment)}
.tint-other{background:var(--tint-other)}

/* ---------- the Walkout rollover ---------- */
.morph{position:relative;display:inline-block;white-space:nowrap}
.morph > span{display:block}
/* The wipe runs first word to last on the way in and unwinds last to
   first on the way out, so a headline reads as one movement across
   the line rather than eight separate flips. The article headlines
   were already set this way; this is the same timing for the rest. */
.morph .m-sans{transition:clip-path .34s cubic-bezier(.66,0,.2,1)
  calc((var(--n,1) - 1 - var(--i,0)) * .16s)}
.morph .m-walk{position:absolute;left:0;top:0;width:max-content;font-family:var(--script);text-transform:uppercase;font-weight:400;letter-spacing:.005em;transform-origin:left center;clip-path:inset(0 100% 0 0);transition:clip-path .34s cubic-bezier(.66,0,.2,1)
  calc((var(--n,1) - 1 - var(--i,0)) * .16s)}
.morph::after{content:"";position:absolute;top:-.06em;bottom:-.06em;left:0;width:2px;background:var(--blue);transform:scaleY(0);transform-origin:bottom;transition:transform .2s ease,left .55s cubic-bezier(.66,0,.2,1)}
.morph-group:hover .m-sans,.morph-group:hover .m-walk,
.morph.is-on .m-sans,.morph.is-on .m-walk{
  transition-delay:calc(var(--i,0) * .16s)}
.morph-group:hover .m-sans,.morph.is-on .m-sans{clip-path:inset(0 0 0 100%)}
.morph-group:hover .m-walk,.morph.is-on .m-walk{clip-path:inset(0 0 0 0)}
.morph-group:hover .morph::after,.morph.is-on::after{transform:scaleY(1);left:100%}
/* one edge for the whole headline, at the end of the sweep */
.morph-group--multi .morph::after{display:none}
.morph-group--multi .morph--last::after{display:block}
@media (prefers-reduced-motion:reduce){.morph .m-sans,.morph .m-walk,.morph::after{transition:none}}

/* The phone's menu: nine destinations, a way to search, and a way in.
   Rows are 52px so a thumb hits one on purpose. */
.mega-list{display:flex;flex-direction:column;padding:8px 0 20px}
.mega-row{display:flex;align-items:stretch;border-bottom:1px solid var(--rule)}
/* ".mega a" is declared later and matches at the same weight, so the menu's
   own rows have to be said through .mega to keep their type — otherwise they
   inherit the panel's 16px/600 and read as headlines rather than a list. */
.mega .mega-list a,.mega .mega-list-search{
  display:flex;align-items:center;gap:12px;min-height:52px;padding:0 20px;
  font-family:var(--mono);font-size:13px;font-weight:500;letter-spacing:.1em;
  text-transform:none;line-height:1.2;color:var(--ink);
  background:none;border:0;width:100%;text-align:left;cursor:pointer}
.mega .mega-list a{flex:1;min-width:0}
.mega .mega-list-search{border-bottom:1px solid var(--rule);color:var(--grey);font-size:12px}
.mega .mega-list a.on{color:var(--blue)}
.mega-list-search svg{width:16px;height:16px;flex:none;fill:none;stroke:currentColor;
  stroke-width:1.8;stroke-linecap:round}
.mega .mega-list a.mega-list-who{color:var(--grey);font-size:11px}
.mega-list .mega-list-who{border-top:1px solid var(--rule);margin-top:6px}

/* The arrow is its own target beside the name: the name goes to the section,
   the arrow opens what is inside it. */
.mega-more{flex:0 0 56px;display:grid;place-items:center;background:none;border:0;
  border-left:1px solid var(--rule);color:var(--grey);cursor:pointer;padding:0}
.mega-more svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round;
  transition:transform var(--dur-fast) var(--ease)}
.mega-more.open{color:var(--ink)}
.mega-more.open svg{transform:rotate(90deg)}
.mega-sub{padding:10px 20px 16px;background:var(--bone);
  border-bottom:1px solid var(--rule)}
.mega .mega-sub a{display:block;min-height:0;padding:9px 0;font-family:var(--sans);
  font-size:14px;font-weight:500;letter-spacing:-.01em;text-transform:none;
  color:var(--ink-2);width:auto}
.mega .mega-sub a:hover{color:var(--blue)}
.mega-sub span{display:block;font-family:var(--mono);font-size:8.5px;font-weight:500;
  letter-spacing:.12em;text-transform:uppercase;color:var(--grey);margin-top:2px}

/* ---------- phone ---------- */
.tabbar{display:none}
@media (max-width:900px){
  .cols,.cols--2{background-image:none;min-height:0}
  /* The bar has to hold the mark, Sign in and the burger inside 375px.
     At 30px the script mark alone took most of it and pushed the
     burger off the right edge — which is why it could not be tapped
     at all. The mark gives way, the burger never shrinks. */
  .nav{gap:12px}
  .nav .mark{font-size:22px;min-width:0;overflow:hidden;text-overflow:clip}
  .nav-links,.nav-search{display:none}
  /* Sign in lives in the burger sheet on a phone (.mega-list-who, appended
     when the menu is built), so the bar does not need to carry it twice —
     and the wordmark needs the room more than a duplicate link does. It is
     taken out below, after the rule that would otherwise put it back. */
  .nav-burger{display:grid;flex:0 0 34px;font-size:17px;line-height:1}
  .cols,.cols--2,.cols--rail{display:block}
  /* A rail is a column on a desktop and a swipeable strip on a phone.
     Wrapping it instead turned an outline into a paragraph of run-on
     labels — and because each row is justify-between, the title and
     its count ended up at opposite edges of the screen. One row that
     scrolls sideways, each entry a chip that keeps its pair together. */
  /* It sticks under the bar, so it needs a ground and a layer. It had
     neither — the page scrolled through it and two lines of type sat on top
     of each other. Paper, and above the column it is holding. */
  .rail-l,.side.rail-sticky{background:var(--paper);z-index:30}
  .rail-l{border-bottom:1px solid var(--rule);flex-direction:row;flex-wrap:nowrap;
    gap:8px;padding:12px 16px;overflow-x:auto;overscroll-behavior-x:contain;
    scrollbar-width:none}
  .rail-l::-webkit-scrollbar{display:none}
  .rail-l > *{flex:0 0 auto}
  .rail-l b{align-self:center;white-space:nowrap;padding-right:2px}
  .rail-l a{display:inline-flex;align-items:center;justify-content:flex-start;gap:8px;
    white-space:nowrap;min-height:44px;
    border:1px solid var(--rule);border-radius:var(--r-pill);padding:6px 14px}
  .rail-l a.sub{padding-left:12px}
  .rail-l a.on,.rail-l a.here,.rail-l .sub.here{border-left:1px solid var(--ink);
    padding-left:12px;background:var(--ink);color:var(--paper);border-color:var(--ink)}
  .rail-l a.on span,.rail-l a.here span,.rail-l .sub.here span{color:var(--paper)}
  .side{border-left:0;border-top:1px solid var(--rule)}
  .main{padding:22px 16px 34px}
  .tabbar{display:flex;position:fixed;left:0;right:0;bottom:0;z-index:60;background:var(--paper);border-top:1px solid var(--rule);justify-content:space-between;padding:10px 20px 22px}
  .tabbar a{display:flex;flex-direction:column;align-items:center;gap:5px;font-family:var(--mono);font-size:8px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--grey-2)}
  .tabbar i{width:15px;height:15px;border:1.3px solid currentColor;display:block}
  .tabbar a.on{color:var(--ink)}
  .tabbar a.on i{background:currentColor}
  .h1{font-size:clamp(32px,9vw,42px)}
  /* The rollover holds its two layers on one unbreakable line, which
     is what makes the wipe measurable — and what pushed a long title
     past the right edge of a phone. There is no hover on a phone
     anyway, so the headline goes back to being a headline: one layer,
     wrapping like text. */
  .morph{white-space:normal}
  .morph .m-walk,.morph::after{display:none}
  /* A wide stat table does not fit a phone and should not try. It scrolls
     inside its own box rather than panning the whole page sideways.

     The table stays a table. Making it display:block and handing thead and
     tbody `display:table` each turns them into two independent tables that
     size their columns separately — the gem table came out with a 441px
     header over a 323px body, so the headings sat over the wrong figures.
     One table, natural width, scrolling in the wrapper it already has. */
  .ar-tw{overflow-x:auto;overscroll-behavior-x:contain;
    -webkit-overflow-scrolling:touch;max-width:100%}
  .ar-tw > table{display:table;min-width:max-content;max-width:none;overflow:visible}
  .ar-tw > table thead{display:table-header-group}
  .ar-tw > table tbody{display:table-row-group}
  /* A table that somehow escaped the wrapper still must not pan the page. */
  table:not(.ar-tw > table){display:block;overflow-x:auto;max-width:100%}
  .deskgrid{display:block !important}
  .deskgrid .ph{min-height:210px;margin-top:20px}
  .pillars{grid-template-columns:1fr 1fr !important;gap:18px !important}
  .twoup,.factrow,.series,.stats{display:block !important}
  .cols--rail aside{border-left:0;border-top:1px solid var(--rule)}

  /* The Desk is a fixed frame on a desktop — a full-height board with its own
     inner scrollers. On a phone that meant a page locked to 100dvh with
     overflow hidden, so the Desk could not be scrolled at all: everything
     below the fold was simply unreachable. A phone scrolls the page. */
  .page--frame{height:auto;min-height:100dvh;overflow:visible}
  .page--frame .cols{flex:none;min-height:0}
  .page--frame .deskmain{overflow-y:visible;display:block}
  .page--frame .rail-scroll{position:static;height:auto;max-height:none;overflow:visible}

  /* Nothing is pinned to the bottom of a phone. The tab bar held 65px of the
     screen at all times and the footer reserved another 96 to clear it —
     161px spent before a word of the page. The bar goes back into the flow
     and the footer is a footer. */
  .tabbar{position:static;padding:14px 20px;border-top:1.4px solid var(--ink)}
  .tabbar a{min-height:44px;justify-content:center}
  /* The scrubber is a column down the edge, not a row — 26 letters at 44px
     each would be 1,144px of it. The thumb runs down the strip rather than
     hunting one letter, so the target grows sideways only. */
  .azscrub a{min-width:30px;display:flex;align-items:center;justify-content:center}

  /* A 14px link is a 14px target. The padding grows the touch area and the
     negative margin gives the space back to the layout, so a "See all →"
     still sits on the same line as the heading it belongs to — it is simply
     hittable now. */
  a.mono-s,a.mono,.nav-who,.foot a,
  .signin-swap a,.acad-account a,.glossbox a,.side--reads .rp a{
    display:inline-flex;align-items:center;min-height:44px;
    margin-top:-15px;margin-bottom:-15px}
  /* …except the one in the bar, which is not there at all on a phone. This
     has to out-specify the touch-target rule directly above it: both are a
     single class on .nav-who, and that one is written later. */
  .nav .nav-who{display:none}
  .foot a{min-height:32px;margin-top:-9px;margin-bottom:-9px}
  /* Wrapped tags in a rail keep their own line box, so they take the height
     as padding instead — a negative margin would pull the row above them. */
  .glossbox a,.side--reads .rp a{min-height:0;margin:0;padding:7px 0}
}

/* ===================================================================
   MEGA NAV · SEARCH · SCROLLING RAIL
   =================================================================== */

.nav-links a.has-menu{cursor:default}
.mega{
  position:fixed;left:0;right:0;top:var(--nav-h);z-index:49;background:var(--paper);
  border-bottom:1.4px solid var(--ink);box-shadow:0 24px 40px -34px rgba(0,0,0,.55);
  padding:26px clamp(16px,3vw,40px) 30px;display:none;
}
.mega.open{display:block}
.mega-in{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:26px 34px;max-width:1360px}
.mega h4{margin:0 0 12px;font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.15em;text-transform:uppercase;color:var(--grey)}
.mega a{display:block;padding:6px 0;font-size:16px;font-weight:600;letter-spacing:-.015em;line-height:1.25}
.mega a:hover{color:var(--blue)}
.mega a span{display:block;font-family:var(--mono);font-size:8.5px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--grey);margin-top:3px}

.scrim{position:fixed;inset:var(--nav-h) 0 0;background:rgba(17,17,16,.35);z-index:48;display:none}
.scrim.open{display:block}

/* search */
.search-wrap{position:fixed;inset:0;z-index:70;display:none;background:rgba(17,17,16,.45);padding:8vh 16px 16px}
.search-wrap.open{display:block}
.search-box{max-width:760px;margin:0 auto;background:var(--paper);border-radius:var(--r);overflow:hidden;box-shadow:0 40px 80px -40px #000}
.search-field{display:flex;align-items:center;gap:14px;padding:18px 22px;border-bottom:1.4px solid var(--ink)}
.search-field input{flex:1;border:0;outline:0;font-family:var(--sans);font-size:24px;font-weight:600;letter-spacing:-.02em;color:var(--ink);background:transparent}
.search-field input::placeholder{color:var(--grey-2);font-weight:300}
.search-hint{font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--grey-2);white-space:nowrap}
.search-results{max-height:56vh;overflow:auto}
.sr-group{font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.13em;text-transform:uppercase;color:var(--grey);background:var(--bone);padding:7px 22px}
.sr{display:grid;grid-template-columns:14px 1fr auto;gap:12px;align-items:baseline;padding:11px 22px;border-bottom:1px solid var(--rule);cursor:pointer}
.sr:hover,.sr.sel{background:rgba(27,35,255,.06)}
.sr h5{margin:0;font-size:17px;font-weight:600;letter-spacing:-.018em}
.sr p{margin:3px 0 0;font-size:13px;line-height:1.4;color:var(--grey)}
.sr .st{align-self:center}
.search-empty{padding:26px 22px;font-family:var(--serif);font-weight:300;font-size:17px;color:var(--grey)}

/* the desk rail scrolls on its own */
.rail-scroll{position:sticky;top:var(--top-h);max-height:var(--view-h);overflow-y:auto;overscroll-behavior:contain}
/* the rail scrolls, so its tiles keep their full height instead of being
   squeezed to fit the viewport */
.rail-scroll > *{flex:none}
.rail-scroll .ph{flex:none}
.rail-scroll{scrollbar-width:thin;scrollbar-color:rgba(17,17,16,.28) transparent;scrollbar-gutter:stable}
.rail-scroll::-webkit-scrollbar{width:9px}
.rail-scroll::-webkit-scrollbar-thumb{background:rgba(17,17,16,.22);border-radius:var(--r-pill);border:3px solid var(--bone)}
.rail-scroll::-webkit-scrollbar-thumb:hover{background:rgba(17,17,16,.4)}

@media (max-width:900px){
  .mega{top:var(--nav-h);max-height:calc(100dvh - var(--nav-h));overflow:auto}
  .mega-in{grid-template-columns:1fr;gap:20px}
  .rail-scroll{position:static;max-height:none}
  .search-wrap{padding:0}
  .search-box{border-radius:0;height:100dvh;display:flex;flex-direction:column}
  .search-results{max-height:none;flex:1}
}

/* the kingdom section carries its own tell wherever it is named */
.k318-link{display:inline-flex;align-items:center;gap:6px}
.k318-link::before{content:"";width:7px;height:7px;background:var(--acid);border-radius:50%;flex:none}
.k318-link.on::before{background:var(--ink)}

/* the kingdom masthead: a charcoal band under the nav, on every K318 page */
/* Lo: it stays with you on the kingdom pages, the way the nav does —
   it is how you know which part of the Atlas you are standing in. */
.kband{position:sticky;top:var(--nav-h);z-index:35;
  background:var(--lilac);color:var(--ink);padding:19px clamp(16px,3vw,40px) 17px;
  display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.kband .sigil{width:28px;height:28px;border-radius:50%;background:var(--acid);color:var(--ink);display:grid;place-items:center;
  font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.02em;flex:none;
  transition:transform var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease)}
.kband a.sigil:hover{transform:scale(1.12);box-shadow:0 0 0 4px rgba(17,17,16,.12)}
.kband .kname{font-family:var(--mono);font-size:11px;font-weight:500;letter-spacing:.15em;text-transform:uppercase}
.kband .knote{font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:rgba(17,17,16,.55);margin-left:auto}

/* provenance, this section only */
.prov{font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;padding:4px 9px;border-radius:var(--r-pill);border:1px solid var(--rule);color:var(--grey)}
.prov--palace{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.prov--council{background:var(--blue);color:#fff;border-color:var(--blue)}
.prov--observed{border-color:var(--ink);color:var(--ink)}
.prov--estimate{background:var(--sand);border-color:var(--sand);color:var(--ink)}
.prov--unverified{background:var(--flare);border-color:var(--flare);color:#fff}
.vis{font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;padding:4px 9px;border-radius:var(--r-pill)}
.vis--public{background:var(--bone);color:var(--grey)}
.vis--kingdom{background:var(--acid);color:var(--ink)}
/* Tighter than kingdom-only: one clan's own business, not K318's. Set in ink
   because the tiers read as a ladder — bone, acid, then solid — and because
   acid is spoken for and must keep meaning exactly one thing. */
.vis--clan{background:var(--ink);color:var(--paper)}
/* The kingdom's pages inside the phone menu. One column, tappable rows, with
   the rail's own count held to the right where it does not fight the label. */
.mega-k318{display:flex;flex-direction:column}
.mega-k318 a{display:flex;justify-content:space-between;align-items:baseline;gap:12px;
  padding:11px 0;border-top:1px solid var(--rule);font-family:var(--mono);font-size:11px;
  font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--ink)}
.mega-k318 a:first-child{border-top:0}
.mega-k318 em{font-style:normal;color:var(--grey);white-space:nowrap}
.directive{border:1.4px solid var(--ink);border-radius:var(--r);padding:20px 22px;background:var(--paper)}
.directive .attrib{display:flex;gap:10px;flex-wrap:wrap;align-items:center;padding-bottom:14px;margin-bottom:14px;border-bottom:1px solid var(--rule)}
.correction{background:var(--flare);color:#fff;border-radius:var(--r);padding:12px 16px;margin-bottom:18px}
.clock{font-weight:800;letter-spacing:-.05em;line-height:.9;font-variant-numeric:tabular-nums;font-size:clamp(72px,10vw,132px);margin:0}

/* ===================================================================
   MOTION
   Page to page, the mega nav, and everything that arrives on scroll.
   One curve does most of it; the spring is for things that open.
   =================================================================== */

/* --- page to page: a cross-fade with a small rise on the incoming view --- */
@view-transition{navigation:auto}
::view-transition-old(root){animation:vt-out .34s var(--ease) both}
::view-transition-new(root){animation:vt-in var(--dur-slow) var(--ease) both}
@keyframes vt-out{to{opacity:0;transform:translateY(-6px) scale(.995)}}
@keyframes vt-in{from{opacity:0;transform:translateY(14px) scale(.995)}}
/* the chrome stays put while the body moves under it */
.nav{view-transition-name:atlas-nav}
::view-transition-old(atlas-nav),::view-transition-new(atlas-nav){animation:none;mix-blend-mode:normal}

/* --- the mega nav opens rather than appears --- */
.mega{
  display:block;opacity:0;visibility:hidden;pointer-events:none;
  transform:translateY(-12px) scaleY(.97);transform-origin:top center;
  transition:opacity .26s var(--ease),transform var(--dur) var(--ease-spring),visibility 0s linear var(--dur);
}
.mega.open{opacity:1;visibility:visible;pointer-events:auto;transform:none;transition-delay:0s,0s,0s}
.mega-in > div{opacity:0;transform:translateY(10px);transition:opacity .38s var(--ease),transform .5s var(--ease-spring)}
.mega.open .mega-in > div{opacity:1;transform:none}
.mega.open .mega-in > div:nth-child(1){transition-delay:.04s}
.mega.open .mega-in > div:nth-child(2){transition-delay:.09s}
.mega.open .mega-in > div:nth-child(3){transition-delay:.14s}
.mega.open .mega-in > div:nth-child(4){transition-delay:.19s}

.scrim{display:block;opacity:0;visibility:hidden;transition:opacity .3s var(--ease),visibility 0s linear .3s}
.scrim.open{opacity:1;visibility:visible;transition-delay:0s,0s}
.mega a{transition:color var(--dur-fast) var(--ease),transform var(--dur-fast) var(--ease)}
.mega a:hover{transform:translateX(3px)}

/* --- search opens the same way --- */
.search-wrap{display:block;opacity:0;visibility:hidden;pointer-events:none;transition:opacity .28s var(--ease),visibility 0s linear .28s}
.search-wrap.open{opacity:1;visibility:visible;pointer-events:auto;transition-delay:0s,0s}
.search-box{transform:translateY(-14px) scale(.985);transition:transform .46s var(--ease-spring)}
.search-wrap.open .search-box{transform:none}
.sr{transition:background var(--dur-fast) var(--ease)}

/* --- lists arrive as you reach them --- */
.reveal{opacity:0;transform:translateY(16px)}
.reveal.in{opacity:1;transform:none;transition:opacity .55s var(--ease),transform var(--dur-slow) var(--ease-spring)}

/* --- everything that reacts to a pointer does it on the same curve --- */
.row,.glrow,.qrow,.k-card,.nav-links a,.pill,.btn,.tabbar a,.rail-l a{
  transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease),
             border-color var(--dur-fast) var(--ease),transform var(--dur-fast) var(--ease);
}
.row:hover,.glrow:hover,.qrow:hover{transform:translateX(2px)}
.btn:hover{transform:translateY(-1px)}
.pill:hover{border-color:var(--ink);color:var(--ink)}
/* an active pill is ink-on-ink at this point, so it keeps its own colour */
.pill--on:hover{color:var(--paper)}
.pill--pink:hover,.pill--lilac:hover{color:var(--ink)}
.tile{transition:transform var(--dur) var(--ease-spring),box-shadow var(--dur) var(--ease)}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .reveal{opacity:1;transform:none}
  .mega,.mega-in > div,.search-box{transition:none}
  ::view-transition-old(root),::view-transition-new(root){animation:none}
  .row:hover,.glrow:hover,.qrow:hover,.btn:hover,.mega a:hover{transform:none}
}

/* ===================================================================
   THE GLOSSARIUM'S FINDING AID
   295 entries is too many to scroll blind, so the alphabet is a
   control: a sticky bar on desktop, a scrubber down the edge on a
   phone, and a sticky letter header that tells you where you are.
   =================================================================== */

.azbar{display:none}
.azbar a{font-family:var(--mono);font-size:11px;font-weight:500;letter-spacing:.06em;color:var(--grey);
  width:24px;height:24px;display:grid;place-items:center;border-radius:var(--r-pill);
  transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease),transform var(--dur-fast) var(--ease)}
.azbar a:hover{background:var(--ink);color:var(--paper);transform:translateY(-1px)}
.azbar a.empty{color:var(--rule);pointer-events:none}
.azbar a.here{background:var(--acid);color:var(--ink)}
.azbar .azcount{margin-left:auto;font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.13em;text-transform:uppercase;color:var(--grey-2)}

.glwrap{display:grid;grid-template-columns:minmax(0,1fr) 34px}
.lettergroup{scroll-margin-top:var(--top-h)}
/* the letter bars carry the charcoal, so a scrolling reader always knows which
   run they are in without looking away at the scrubber */
.glhead{position:sticky;top:var(--top-h);z-index:20;background:var(--charcoal);
  padding:8px clamp(16px,2vw,26px);font-family:var(--mono);font-size:10px;font-weight:500;
  letter-spacing:.15em;text-transform:uppercase;color:var(--bone);
  border:0;display:flex;justify-content:space-between}
.glhead span:last-child{color:rgba(244,241,233,.62)}

.glrow{cursor:pointer}
.glrow.sel{background:rgba(17,17,16,.07)}

/* the alphabet runs down the edge of the list at every width */
.azscrub{
  position:sticky;top:calc(var(--top-h) + 10px);align-self:start;
  height:calc(var(--view-h) - 40px);
  display:flex;flex-direction:column;justify-content:space-between;align-items:center;
  padding:6px 0;border-left:1px solid var(--rule);
}
.azscrub a{font-family:var(--mono);font-size:9px;font-weight:500;color:var(--grey-2);line-height:1;
  width:22px;height:22px;display:grid;place-items:center;border-radius:50%;margin:0 auto;
  transition:color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease),transform .3s var(--ease-spring)}
.azscrub a:hover{color:var(--paper);background:var(--ink);transform:scale(1.18)}
.azscrub a.empty{color:var(--rule);pointer-events:none}
/* the letter you are standing in gets the same round mark as the K318 sigil */
.azscrub a.here{color:var(--ink);background:var(--acid);font-weight:500;
  box-shadow:0 0 0 3px rgba(230,255,46,.35);transform:scale(1.05)}
@media (max-width:900px){
  .azscrub{height:calc(var(--view-h) - 120px);background:rgba(255,255,255,.86);backdrop-filter:blur(6px)}
}

/* ===================================================================
   PILLAR FLOOD
   A pillar announces itself with a full-bleed band in its own colour,
   then gets out of the way so the reading ground stays paper.
   =================================================================== */
.flood{background:var(--flood,var(--lilac));padding:30px clamp(16px,3vw,44px) 28px}
.flood--tight{padding-top:22px;padding-bottom:22px}
.flood .mono,.flood .mono-s{color:rgba(17,17,16,.62)}
.flood .lede{color:rgba(17,17,16,.82)}
.flood-grid{display:grid;grid-template-columns:1.25fr .75fr;gap:36px;align-items:end}
.flood .prog{background:rgba(17,17,16,.22)}
.flood .prog i{background:var(--ink)}
@media(max-width:900px){.flood-grid{display:block}.flood-grid > div + div{margin-top:22px}}

/* A rail that tracks where you are inside a long page. Every left rail on the
   site is 300px — the width the article index has always used. At 250px the
   longer entries ("Revival Economics & Event Timing", "Reading Your Kingdom's
   RoE") wrapped onto a second line and the outline read as prose. */
.rail-l .sub{padding-left:12px;font-size:10.5px}
/* The reading time is the second half of a two-up row, and on the longer
   lesson titles it was breaking as "4 / min" across two lines. It is never
   wider than five characters — let it hold its line. */
.rail-l .sub span:last-child{white-space:nowrap}
/* a long nested run reads better with a little air above the first and
   below the last, so the group still holds together */
.rail-l a:not(.sub) + .sub{margin-top:2px}
.rail-l .sub + a:not(.sub){margin-top:8px}
.rail-l a.here{color:var(--ink);border-left:3px solid var(--ink);padding-left:10px}
.rail-sticky{position:sticky;top:var(--top-h);align-self:start;max-height:var(--view-h);overflow-y:auto;scrollbar-width:thin}

/* ===================================================================
   THE ROE CALLOUT
   The charter is the one page every player in the kingdom has to have
   read, so it gets a band of its own rather than a link in a list.
   =================================================================== */
.roe{background:var(--blue);color:#fff;border-radius:var(--r);padding:26px 30px 28px;margin-top:30px;
  display:grid;grid-template-columns:1.35fr .65fr;gap:34px;align-items:center}
.roe .eyebrow{font-family:var(--mono);font-size:8.5px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:rgba(255,255,255,.75);margin:0;white-space:nowrap}
.roe h2{margin:12px 0 0;font-size:clamp(28px,3.2vw,40px);font-weight:800;letter-spacing:-.032em;line-height:1.04}
.roe p{margin:12px 0 0;font-size:17px;line-height:1.5;color:rgba(255,255,255,.86);max-width:52ch}
.roe .btn{background-color:#fff;color:var(--ink);background-image:linear-gradient(var(--ink),var(--ink))}
.roe .btn:hover{color:#fff}
.roe .btn--ghost{background:transparent;color:#fff;border-color:rgba(255,255,255,.6)}
.roe-facts{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:rgba(255,255,255,.32);border:1px solid rgba(255,255,255,.32)}
.roe-facts div{background:var(--blue);padding:14px 12px}
.roe-facts b{display:block;font-size:26px;font-weight:800;letter-spacing:-.03em;line-height:1}
.roe-facts span{display:block;font-family:var(--mono);font-size:8.5px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:rgba(255,255,255,.75);margin-top:7px}
@media(max-width:900px){.roe{display:block}.roe-facts{margin-top:22px}}

/* ===================================================================
   K318 · STATUS TRACKER AND THE DIRECTORY
   =================================================================== */
.track{border-top:1.4px solid var(--ink)}
.trow{display:grid;grid-template-columns:1fr 190px 120px 96px;gap:18px;align-items:center;
  padding:14px 0;border-bottom:1px solid var(--rule)}
.trow h4{margin:0;font-size:17px;font-weight:600;letter-spacing:-.018em;line-height:1.25}
.trow .sub{margin:5px 0 0;font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--grey)}
.bar{height:6px;background:var(--sand);position:relative}
.bar i{display:block;height:100%;background:var(--ink)}
.bar--warn i{background:var(--flare)}
.barnum{font-family:var(--mono);font-size:10px;font-weight:500;letter-spacing:.08em;color:var(--grey);margin-top:6px;display:block}
.chip{font-family:var(--mono);font-size:8.5px;font-weight:500;letter-spacing:.13em;text-transform:uppercase;padding:4px 9px;border-radius:var(--r-pill);white-space:nowrap}
.chip--running{background:var(--ink);color:var(--paper)}
.chip--planned{background:var(--bone);color:var(--grey);border:1px solid var(--rule)}
.chip--blocked{background:var(--flare);color:#fff}
.chip--done{background:var(--lilac);color:var(--ink)}
@media(max-width:900px){
  .trow{grid-template-columns:1fr;gap:8px}
  .trow > *:nth-child(4){justify-self:start}
}

.who{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;margin-top:16px}
/* The card grid, and only that. k318-audit-clans.html carries .who on a
   byline span for an entirely different job, so this is scoped to the cards
   rather than widened on .who itself. Now the Vanguard has gone there are two
   cards rather than three, and a fixed three-column track left the last third
   of the row empty. auto-fit collapses the tracks with nothing in them, so the
   cards fill the column at whatever number the section happens to carry. */
.who:has(> .who-card){grid-template-columns:repeat(auto-fit,minmax(min(320px,100%),1fr))}
/* Lo: a lighter beige ground, so the cards sit on the page rather
   than float above it. */
.who-card{border:1px solid var(--rule);border-radius:var(--r);padding:20px 22px 22px;background:var(--bone);display:flex;flex-direction:column}
/* Both tiles carry a fixed ten rows, so each list runs its full height
   with no inner scroll, and the two cards come out level beside each
   other. */
.who-list{margin-top:14px}
.who-card h3{margin:10px 0 0;font-size:22px;font-weight:700;letter-spacing:-.026em}
/* rules between the rows, none under the last one — the button below needs
   no line above it */
.who-card .line + .line{border-top:1px solid var(--rule)}
.who-card .line{display:flex;justify-content:space-between;gap:12px;padding:9px 0;font-size:15px}
.who-card .line span:last-child{font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--grey);white-space:nowrap;align-self:center}
/* The global .foot carries page-edge padding; inside a card that
   pushed the link off the text column it belongs to. */
.who-card .foot{margin-top:auto;padding:18px 0 0;display:flex;justify-content:flex-start;
  border-top:1px solid var(--rule)}
/* a card closes on a text link, not another button */
.cardlink{font-family:var(--mono);font-size:10px;font-weight:500;letter-spacing:.13em;
  text-transform:uppercase;color:var(--blue)}
.cardlink:hover{color:var(--ink)}
.tbd{color:var(--grey-2);font-style:italic}
@media(max-width:900px){.who{grid-template-columns:1fr}}

/* the tracker in a half-width column: one line for the claim, one for the
   evidence, so nothing wraps three deep */
.track--tight .trow{grid-template-columns:1fr auto;gap:6px 14px;padding:13px 0}
.track--tight .trow h4{font-size:16px}
.track--tight .trow .sub{grid-column:1 / -1;margin:0}
.track--tight .trow .barwrap{grid-column:1 / -1;display:grid;grid-template-columns:1fr auto;gap:12px;align-items:center;margin-top:8px}
.track--tight .trow .barnum{margin:0;white-space:nowrap}

/* ===================================================================
   MODALS · a read one for tracker items, a write one for submissions
   =================================================================== */
.modal{position:fixed;inset:0;z-index:80;display:block;opacity:0;visibility:hidden;pointer-events:none;
  background:rgba(17,17,16,.45);padding:6vh 16px 16px;overflow-y:auto;
  transition:opacity .28s var(--ease),visibility 0s linear .28s}
.modal.open{opacity:1;visibility:visible;pointer-events:auto;transition-delay:0s,0s}
.modal-box{position:relative;max-width:720px;margin:0 auto;background:var(--paper);border-radius:var(--r);overflow:hidden;
  box-shadow:0 40px 80px -40px #000;transform:translateY(-16px) scale(.985);
  transition:transform .46s var(--ease-spring)}
.modal.open .modal-box{transform:none}
.modal-head{display:flex;justify-content:space-between;align-items:flex-start;gap:20px;
  padding:22px 26px 18px;border-bottom:1.4px solid var(--ink)}
.modal-head h2{margin:10px 0 0;font-size:26px;font-weight:700;letter-spacing:-.026em;line-height:1.15}
.modal-x{width:32px;height:32px;border-radius:50%;border:1px solid var(--rule);display:grid;place-items:center;
  font-size:15px;color:var(--grey);cursor:pointer;flex:none;transition:background var(--dur-fast) var(--ease)}
.modal-x:hover{background:var(--bone);color:var(--ink)}
.modal-body{padding:22px 26px 26px}
.modal-body h3{margin:22px 0 0;font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.14em;
  text-transform:uppercase;color:var(--grey)}
.modal-body h3:first-child{margin-top:0}
.modal-body p{margin:8px 0 0;font-family:var(--serif);font-weight:300;font-size:16.5px;line-height:1.55;color:var(--ink-2)}
.modal-body ol{margin:10px 0 0;padding-left:20px;font-size:15.5px;line-height:1.6;color:var(--ink-2)}
.modal-body ol li{margin:6px 0}
.modal-body ol li b{font-weight:600;color:var(--ink)}
.modal-foot{border-top:1px solid var(--rule);padding:16px 26px;display:flex;gap:10px;flex-wrap:wrap;align-items:center}
.who-line{display:flex;justify-content:space-between;gap:12px;padding:9px 0;border-bottom:1px solid var(--rule);font-size:15px}
.who-line span:last-child{font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--grey);align-self:center}

/* the form */
.field{margin-top:16px}
.field label{display:block;font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.14em;
  text-transform:uppercase;color:var(--grey);margin-bottom:7px}
.field input[type=text],.field textarea,.field select{width:100%;font-family:var(--sans);font-size:16px;font-weight:400;
  color:var(--ink);background:var(--paper);border:1px solid var(--rule);border-radius:var(--r);padding:11px 13px}
.field textarea{min-height:88px;resize:vertical;font-family:var(--serif);font-weight:300;line-height:1.5}
.field input:focus,.field textarea:focus,.field select:focus{outline:2px solid var(--blue);outline-offset:1px;border-color:var(--blue)}
.chips{display:flex;gap:8px;flex-wrap:wrap}
.chip-opt{font-family:var(--mono);font-size:9.5px;font-weight:500;letter-spacing:.11em;text-transform:uppercase;
  padding:8px 13px;border-radius:var(--r-pill);border:1px solid var(--rule);color:var(--grey);cursor:pointer;
  transition:all var(--dur-fast) var(--ease)}
.chip-opt.sel{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.field-row{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.consent{display:flex;gap:10px;align-items:flex-start;margin-top:16px;font-size:14.5px;line-height:1.45;color:var(--ink-2)}
.dropzone{border:1px dashed var(--rule);border-radius:var(--r);padding:18px;text-align:center;color:var(--grey);
  font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase}
@media(max-width:900px){.field-row{grid-template-columns:1fr}.modal{padding:0}.modal-box{border-radius:0;min-height:100dvh}}
.trow h4{cursor:pointer}
.trow h4:hover{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px}

/* stats that sit beside a page headline share its baseline: the numerals
   line up with the H1, and the labels hang below it */
.headstats{display:flex;gap:0;align-items:flex-end}
/* the same hairline-divided run of numerals the Glossarium panel uses */
.headstats > span{display:block;text-align:left;padding:0 18px 0 0}
.headstats > span + span{border-left:1px solid rgba(17,17,16,.2);padding-left:20px}
.headstats .num{display:block;font-size:34px;line-height:.82}
.headstats .mono-s{display:block;margin-top:9px}
/* The category filter sits where the article count used to: a small mono
   label and the Atlas's own dropdown, right-aligned in the pagehead. */
.afilter{display:flex;align-items:center;justify-content:flex-end;gap:12px}
.afilter-l{font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.13em;text-transform:uppercase;color:var(--grey)}
.afilter .asel-btn{min-width:156px}
.strip .h1{line-height:.9}

.pill--lilac{background:var(--lilac);border-color:var(--lilac);color:var(--ink)}
.pill--blue{background:var(--blue);border-color:var(--blue);color:#fff}
.pill--blue:hover{color:#fff;border-color:var(--ink);background:var(--ink)}
.qrow{cursor:pointer}

/* two panels across the foot of the desk: what is running right now, and
   where the Atlas itself stands */
/* min-width:0 on the tracks. A grid track's default minimum is its
   content's min-content, and the plate image in the second panel is
   1270px wide intrinsically — so without this it claims the whole row
   and the events panel collapses to a column of wrapped words. It only
   ever looked right because .morph is nowrap and propped the first
   track up; taking the rollover off the event headings exposed it. */
.homerow > *{min-width:0}
.homerow{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--rule);
  border-top:1px solid var(--rule);margin-top:auto;padding-top:0}
.homerow .homepanel{padding-top:24px}
.deskmain > .homerow{margin-top:36px}
.homepanel{background:var(--paper);padding:18px 0 4px}
.homepanel > .ph-head{display:flex;justify-content:space-between;align-items:baseline;padding:0 0 10px}
.ev-row{display:grid;grid-template-columns:14px 1fr auto;gap:12px;align-items:baseline;padding:9px 0;border-top:1px solid var(--rule)}
/* A row the Atlas has an entry for opens it in place. One that it does not
   stays inert rather than pretending — the pointer is the tell. */
.ev-row--open{cursor:pointer}
.ev-row--open:hover h4{color:var(--blue)}
.ev-row h4{margin:0;font-size:16px;font-weight:600;letter-spacing:-.016em}
.ev-row p{margin:4px 0 0;font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--grey)}
.live{width:9px;height:9px;border-radius:50%;background:var(--acid);box-shadow:0 0 0 3px rgba(230,255,46,.35);margin-top:5px}
.soon{width:9px;height:9px;border-radius:50%;background:transparent;border:1.4px solid var(--ink);margin-top:5px}
.later{width:9px;height:9px;border-radius:50%;background:var(--sand);margin-top:5px}
.risk{width:9px;height:9px;border-radius:50%;background:var(--flare);margin-top:5px}
.ledger{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--rule);border-top:1px solid var(--rule)}
.ledger > div{background:var(--paper);padding:14px 0 4px}
@media(max-width:900px){.homerow{grid-template-columns:1fr}.homepanel + .homepanel{border-top:1px solid var(--rule)}}

/* who's who: one ground per body, so the three read as three different
   kinds of thing rather than three lists */




/* Anything on the orange ground carries weight: at 300 the serif
   disappears into the fill, so copy there sets at 500 and the labels
   drop their transparency. */
.ask,.correction,.warn{font-weight:500}
.ask p,.correction p,.warn p{font-weight:500}
.ask .mono-s,.correction .mono-s,.warn .mono-s{opacity:1;color:#fff}
.correction p:last-child,.warn p:last-child,.ask p:last-child{font-family:var(--sans);letter-spacing:-.006em}

/* in the rails, a conflict count is a rail item like any other — same size,
   same tracking, just red. It is not a chip in there. */
.rail-l .st,.rail-l .st--cont{font-family:var(--mono);font-size:11px;font-weight:500;letter-spacing:.1em;
  text-transform:uppercase;background:none;padding:0;border-radius:0;color:var(--flare)}
.rail-l a:hover .st--cont{color:var(--flare)}

/* the screenshot lane: the single most valuable thing a reader can send */
.shot-drop{border:1px dashed var(--rule);border-radius:var(--r);padding:26px 18px;text-align:center;cursor:pointer;
  transition:border-color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease)}
.shot-drop:hover,.shot-drop.over{border-color:var(--blue);background:rgba(27,35,255,.04)}
.shot-drop .big{font-size:17px;font-weight:600;letter-spacing:-.018em;color:var(--ink);display:block}
.shot-drop .sm{font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;
  color:var(--grey);display:block;margin-top:8px}
.shot-prev{display:grid;grid-template-columns:96px 1fr;gap:14px;align-items:center;border:1px solid var(--rule);
  border-radius:var(--r);padding:12px;margin-top:12px}
.shot-prev img{width:96px;height:72px;object-fit:cover;border-radius:2px;display:block;background:var(--bone)}
.shot-prev .meta{font-size:14px;line-height:1.4}
.shot-prev .meta b{display:block;font-weight:600}
.shot-prev .drop-again{font-family:var(--mono);font-size:9px;letter-spacing:.12em;text-transform:uppercase;color:var(--blue);cursor:pointer}
.settles{background:var(--lilac);border-radius:var(--r);padding:14px 16px}
.settles p{margin:0;font-family:var(--serif);font-weight:300;font-size:16px;line-height:1.45}

/* rows that are links behave like links: the label goes blue on hover */
a.ev-row{color:inherit}
a.ev-row:hover h4{color:var(--blue)}
a.ev-row:hover{background:rgba(27,35,255,.03)}

.issue--quiet{border-top:0;padding-top:0;padding-bottom:34px}
.issue--quiet .b-quiet{margin-top:34px}

/* ===================================================================
   A FULL GLOSSARY ENTRY
   The short definition is what the list shows. This is the entry
   itself — the Atlas's own prose, its evidence, and what it links to.
   =================================================================== */
.entry-body h4{margin:24px 0 0;font-size:19px;font-weight:600;letter-spacing:-.02em}
.entry-body p{margin:10px 0 0;font-family:var(--serif);font-weight:300;font-size:17px;line-height:1.6;color:var(--ink-2);max-width:62ch}
.entry-body p b,.entry-body h4 + p b{font-weight:600;color:var(--ink)}
/* A missing page is worth saying once, quietly. It was a dashed box holding a
   17px italic sentence, which gave the one thing on the page with nothing to
   say the most room on it. Same type as the site's footer, which is where the
   eye already expects a note about the page rather than from it. */
.entry-stub{border:0;border-top:1px solid var(--rule);border-radius:0;padding:13px 0 0;margin-top:24px}
.entry-stub p{margin:0;font-family:var(--mono);font-size:10px;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;font-style:normal;
  color:var(--grey-2);line-height:1.7}
/* In a modal it runs across the bottom, outside the scroller, so it stays put
   while the entry scrolls behind it. */
.modal-foot.entry-note{padding:13px 26px;justify-content:flex-start;
  align-items:center;gap:16px;flex-wrap:wrap;
  background:var(--acid);border-top:1.4px solid var(--ink)}
.modal-foot.entry-note p{margin:0;font-family:var(--mono);font-size:10px;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;color:var(--ink);line-height:1.7}

.entry-head{background:var(--tint-other);color:var(--ink);padding:26px clamp(16px,3vw,40px) 28px}
.entry-head .h1{font-size:clamp(38px,4.6vw,56px)}
/* A leader's entry leads with their face, beside the name rather than above
   it. Only heads that have one become a row; every other entry keeps the
   block it has always been, which is why this hangs off :has rather than
   being the default. The portrait takes itself out on a 404, and when it goes
   the head goes back to a block with it. */
.entry-head:has(.entry-face){display:flex;gap:clamp(20px,3vw,34px);
  align-items:center;flex-wrap:wrap}
.entry-head-in{flex:1;min-width:min(300px,100%)}
.entry-face{flex:none;width:clamp(132px,17vw,208px);aspect-ratio:1;
  border-radius:var(--r);overflow:hidden;background:var(--ink);
  border:1px solid rgba(17,17,16,.14);display:block}
.entry-face img{width:100%;height:100%;object-fit:cover;display:block}
/* In the modal the head is tighter and the reading is right behind it, so the
   face is smaller there than on the entry's own page.

   The row rule has to be said again at the modal's own weight:
   `.modal-box .modal-head.entry-head` sets display:block and outranks a bare
   `.entry-head:has(…)`, so the head stayed a block and the portrait sat on
   top of the name instead of beside it. */
.modal-head .entry-face{width:clamp(96px,12vw,132px)}
.modal-box .modal-head.entry-head:has(.entry-face){display:flex;
  gap:clamp(18px,2.4vw,26px);align-items:center;flex-wrap:wrap}
.entry-meta{display:flex;gap:18px;flex-wrap:wrap;align-items:center;margin-top:14px}

.glrow p{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

/* ===================================================================
   CATEGORY TINTS
   The dot is the saturated mark; the panel behind an entry is the same
   hue at reading strength, so the colour tells you what kind of thing
   you have opened before you read a word.
   =================================================================== */
/* An opened entry always sits on lilac — the sheet colour — and the dot is
   what says which kind of thing it is. One ground, eight marks. */
.side--sheet{background:transparent;color:var(--ink)}

.cols{--tintcol:transparent}
.cols.tinted{background-image:
  linear-gradient(var(--rule),var(--rule)),
  linear-gradient(var(--tint,var(--lilac)),var(--tint,var(--lilac)));
  background-size:1px 100%,340px 100%;
  background-position:300px 0,right top;background-repeat:no-repeat}

/* ---------- the record behind an entry ---------- */
/* Every claim the Atlas holds for this term, with the status it was given and
   the kind of source it came from. Shown only when there is something to show. */
.record{margin-top:34px;padding-top:18px;border-top:1.4px solid var(--ink);scroll-margin-top:calc(var(--top-h) + 20px)}
.rec-head{display:flex;justify-content:space-between;align-items:baseline;gap:20px;flex-wrap:wrap;margin-bottom:6px}
.rec-head .h2{margin:0}
.rec{padding:15px 0;border-bottom:1px solid var(--rule);max-width:70ch}
.rec-meta{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.rec-meta .st{color:var(--ink)}
.rec p{margin:9px 0 0;font-size:16px;line-height:1.5;color:var(--ink-2)}
/* the one link out of a record: the same small mono the rest of the chrome
   uses, not a serif paragraph wearing uppercase */
.rec-more{display:inline-block;margin-top:16px;font-family:var(--mono);font-size:9px;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;color:var(--grey)}
.rec-more:hover{color:var(--blue)}

/* a run of outbound sources or long reads, used wherever the Atlas credits its
   own writing or someone else's */
.srclist{display:flex;flex-direction:column}
.srclist a{display:block;padding:11px 0;border-top:1px solid rgba(17,17,16,.2);font-size:15px;line-height:1.35}
.srclist a:last-child{border-bottom:1px solid rgba(17,17,16,.2)}
.srclist a span{display:block;margin-top:5px;font-family:var(--mono);font-size:8.5px;font-weight:500;
  letter-spacing:.12em;text-transform:uppercase;color:var(--grey)}
.srclist a:hover{color:var(--blue)}
/* Where a term is written up is a list of one to five names, and as rows it
   drew a rule above each and below the last — two lines, stacked under the
   label and over the record's own divider. Three rules to introduce one link.
   Named things the Atlas already sets as tags, so these are tags. */
.wrote-l{margin:28px 0 10px}
/* First thing in the panel: it needs the panel's own padding, not a paragraph
   break as well. */
.entry-body > .wrote-l:first-child{margin-top:4px}
.srclist--tags{flex-direction:row;flex-wrap:wrap;gap:6px;margin-top:2px}
.srclist--tags a{display:inline-flex;align-items:baseline;gap:8px;padding:7px 12px;
  border:1px solid var(--rule);border-top:1px solid var(--rule);border-radius:var(--r-pill);
  font-size:13.5px;line-height:1.2;white-space:nowrap}
.srclist--tags a:last-child{border-bottom:1px solid var(--rule)}
.srclist--tags a span{display:inline;margin:0;font-size:8.5px;color:var(--grey)}
.srclist--tags a:hover{border-color:var(--ink);color:var(--blue)}
/* Glossary tags: solid ink pills, white text, flipping to blue on rollover. */
.srclist--tags--ink a{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.srclist--tags--ink a:hover{background:var(--blue);border-color:var(--blue);color:#fff}

/* the mega nav's term of the day sits apart from the category columns */
.mega .dot{margin-right:8px;vertical-align:middle;position:relative;top:-1px}
.mega-tod{align-self:stretch;border-left:1.4px solid var(--ink);padding-left:30px}
.mega-tod h4{color:var(--grey)}
.mega-tod a{display:block;padding:0}
.mega-tod .tod-meta{display:block;font-family:var(--mono);font-size:8.5px;font-weight:500;
  letter-spacing:.12em;text-transform:uppercase;color:var(--grey);margin:0 0 8px}
.mega-tod b{display:block;font-size:26px;font-weight:800;letter-spacing:-.03em;line-height:1.05}
.mega-tod em{display:block;margin-top:9px;font-family:var(--serif);font-style:normal;font-weight:300;
  font-size:15px;line-height:1.45;color:var(--ink-2)}
.mega-tod a:hover b{color:var(--blue)}

/* The page footer rides the bottom of the window on every page. Sticky rather
   than fixed, so it still takes its own space at the end of the document and
   nothing hides behind it. On mobile the tab bar already owns that edge, so
   the footer goes back to sitting where it falls. */
footer.foot{position:sticky;bottom:0;z-index:40;background:var(--sand);
  border-top:1.4px solid #c1bcb0;color:var(--ink);font-weight:400;margin-top:auto}
/* Declared after the phone block, so the phone block has to be said
   again here or it loses on source order — which is why the footer
   was still riding the bottom of a phone screen, on top of the tab
   bar, with the page scrolling underneath it.
   The 96px was clearance for a fixed tab bar. The bar is in the flow now,
   so the clearance is dead space and the footer is just a footer. */
@media (max-width:900px){
  footer.foot{position:static;padding-bottom:16px;gap:6px;
    flex-direction:column;align-items:flex-start;font-size:9px;margin-top:0}
}
footer.foot a{color:inherit;border-bottom:1px solid rgba(17,17,16,.3)}
footer.foot a:hover{color:var(--blue);border-color:var(--blue)}

/* the entry, read in place */
.modal-box .modal-head.entry-head{display:block;border-radius:var(--r) var(--r) 0 0;padding:30px 34px 26px}
.modal-box .modal-body.entry-body{padding:26px 34px 34px;max-height:64vh;overflow:auto}
.modal-box .record{margin-top:28px}
.modal-x{position:absolute;top:16px;right:18px;z-index:2;width:34px;height:34px;border-radius:50%;
  border:0;background:rgba(17,17,16,.08);color:var(--ink);font-size:19px;line-height:1;cursor:pointer}
.modal-x:hover{background:var(--ink);color:var(--paper)}

/* the one big thing in a menu: set off by a rule, the way the term of the day is */
/* No min-width. A grid item wider than its track does not widen the track,
   it overflows — so at 1100px the Just published plate ran 37px past the
   menu's own right gutter and off the window. It takes the track it is
   given and the plate scales inside it. */
.mega-hero{align-self:stretch;border-left:1.4px solid var(--ink);padding-left:30px;min-width:0}
.mega .mega-hero-in{display:block;padding:0}
.mega .mh-row{display:flex;align-items:center;gap:14px;padding:9px 0;border-bottom:1px solid var(--rule)}
.mega .mh-date{flex:none;min-width:46px;text-align:center;background:var(--bone);border-radius:var(--r);padding:6px 6px 7px}
.mega .mh-date.is-conflict{background:var(--pink)}
.mega .mh-date.is-live{background:var(--acid)}
.mega .mh-date.is-k318{background:var(--pink)}
.mega .mh-date em{display:block;font-family:var(--mono);font-size:7.5px;font-weight:500;letter-spacing:.14em;
  text-transform:uppercase;color:var(--grey);font-style:normal}
.mega .mh-date b{display:block;font-size:20px;font-weight:800;letter-spacing:-.04em;line-height:.95;margin-top:2px;
  font-variant-numeric:tabular-nums}
.mega .mh-what{min-width:0}
.mega .mh-what b{display:block;font-family:var(--sans);font-size:15px;font-weight:600;
  letter-spacing:-.015em;line-height:1.2;text-transform:none;color:var(--ink)}
.mega .mh-what em{display:block;margin-top:3px;font-family:var(--mono);font-size:8.5px;font-weight:500;
  letter-spacing:.12em;text-transform:uppercase;color:var(--grey);font-style:normal}
.mega .mh-more{display:block;margin-top:14px;padding:0;font-family:var(--mono);font-size:8.5px;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;color:var(--grey)}
.mega .mega-hero-in:hover .mh-more{color:var(--blue)}

/* Rail items with no page behind them yet: present so the shape of the section
   is legible, faded and inert so nobody clicks into nothing. */
.rail-l .rail-off{display:flex;justify-content:space-between;gap:10px;opacity:.38;cursor:default;
  pointer-events:none}

/* ---------- the marker, and the data strip ---------- */
/* A highlighter stroke for the one phrase in a paragraph that carries the
   figure. Neon as a marker, never a field — so it only ever wraps a few words. */
.hl{background:var(--acid);padding:1px 3px;margin:0 -1px;border-radius:2px;
  box-decoration-break:clone;-webkit-box-decoration-break:clone;color:var(--ink)}

/* A dataset called out of the flow: the label, the figure at size, and the
   caveat that keeps the figure honest. */
.datastrip{background:var(--blue);color:#fff;border-radius:var(--r);padding:22px 24px 24px;margin:28px 0 0}
.datastrip .l{display:block;font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.13em;
  text-transform:uppercase;color:rgba(255,255,255,.78);margin:0}
.datastrip b{display:block;margin-top:10px;font-size:clamp(44px,5.4vw,68px);font-weight:800;
  letter-spacing:-.045em;line-height:.92;font-variant-numeric:tabular-nums}
.datastrip .c{display:block;margin-top:12px;font-family:var(--mono);font-size:9px;font-weight:500;
  letter-spacing:.12em;text-transform:uppercase;color:rgba(255,255,255,.78);line-height:1.6}

/* ---------- the long read: index left, sources right ----------
   The layout itself is further down, where the measure and the
   full-height rules are set. What is left here is how the rail's
   own contents look. */
.side--reads .rl{margin:0 0 9px;font-family:var(--mono);font-size:9px;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;color:var(--grey)}
.side--reads .rp{margin:0;font-size:14.5px;line-height:1.5;color:var(--ink-2)}
.side--reads .rp--cont{color:var(--flare)}
.side--reads .rp--cont a{color:var(--flare)}
.srcmini{margin-top:10px}
.srcmini a{display:block;padding:9px 0;border-top:1px solid var(--rule);font-size:14px;line-height:1.35}
.srcmini a:last-child{border-bottom:1px solid var(--rule)}
.srcmini a span{display:block;margin-top:4px;font-family:var(--mono);font-size:8px;font-weight:500;
  letter-spacing:.12em;text-transform:uppercase;color:var(--grey)}
.srcmini a:hover{color:var(--blue)}
/* an article that comes in parts announces each one */
.ar-view + .ar-view{margin-top:44px;padding-top:8px;border-top:1.4px solid var(--ink)}
.ar-viewlabel{margin:34px 0 0;font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.14em;
  text-transform:uppercase;color:var(--grey)}
.rail-l .idx-view{font-weight:500;color:var(--ink);margin-top:8px}
.rail-l .idx-view:first-of-type{margin-top:0}
@media(max-width:900px){.cols--reads{display:block}
  /* Stacked, the rail is the last thing on the page rather than a
     column beside it — and it keeps its rule as a top edge. */
  .cols--reads .side--reads{border-left:0;border-top:1px solid var(--rule)}}

/* ---------- the page head ---------- */
/* Every section leads with the same full-width band: eyebrow, name, and the one
   sentence saying what the section is. The rails start below it, not beside it. */
.pagehead{background:var(--lilac);padding:32px clamp(16px,3vw,40px) 34px}
/* a sticky band has to be opaque or the page scrolls through it */
.ar-head{background:var(--bone)}
/* the same band on the page's own ground, for sections that read better plain */
/* A tool is not an article: the name is orientation, not a headline, and
   every pixel it takes is a pixel of the thing you came to look at. */
/* The workshop reads as its own part of the Atlas: the reference sections keep
   the lilac, a tool you come to use gets the acid. --slim is this page only. */
.pagehead--slim{background:var(--acid);padding:18px clamp(16px,3vw,40px) 20px}
.pagehead--slim .h1{font-size:clamp(26px,3vw,34px)}
.pagehead--plain{background:var(--paper);border-bottom:1.4px solid var(--ink)}
.pagehead--plain .eyebrow{color:var(--grey)}
.pagehead--plain .lede{color:var(--ink-2)}
.pagehead--plain .pagehead-aside{border-left-color:var(--rule)}
.pagehead--plain .headstats > span + span{border-left-color:rgba(17,17,16,.2)}
/* and on the blue, where the section warrants it */
.pagehead--blue{background:var(--blue);color:#fff}
.pagehead--blue .eyebrow{color:rgba(255,255,255,.72)}
.pagehead--blue .lede{color:rgba(255,255,255,.86)}
.pagehead--blue .pagehead-aside{border-left-color:rgba(255,255,255,.3)}
.pagehead--acid{background:var(--acid)}
.pagehead--acid .eyebrow{color:rgba(17,17,16,.62)}
.pagehead--acid .lede{color:rgba(17,17,16,.82)}
.pagehead--acid .pagehead-aside{border-left-color:rgba(17,17,16,.28)}
.pagehead--acid .headstats > span + span{border-left-color:rgba(17,17,16,.28)}
.pagehead--bone{background:var(--bone);border-bottom:1.4px solid var(--ink)}
.pagehead--pink{background:var(--pink)}
.pagehead--pink .eyebrow{color:rgba(17,17,16,.62)}
.pagehead--pink .lede{color:rgba(17,17,16,.84)}
.pagehead--pink .pagehead-aside{border-left-color:rgba(17,17,16,.24)}
.pagehead--pink .mono{color:rgba(17,17,16,.62)}
.pagehead--pink .mono-s{color:rgba(17,17,16,.62)}
.pagehead--pink .prog{background:rgba(17,17,16,.22)}
.pagehead--pink .prog i{background:var(--ink)}
.pagehead--bone .eyebrow{color:var(--grey)}
.pagehead--bone .lede{color:var(--ink-2)}
.pagehead--bone .pagehead-aside{border-left-color:var(--rule)}
.pagehead--bone .headstats > span + span{border-left-color:rgba(17,17,16,.2)}
.pagehead .h1{margin:12px 0 0}
.pagehead .eyebrow{font-family:var(--mono);font-size:10px;font-weight:500;letter-spacing:.15em;
  text-transform:uppercase;color:rgba(17,17,16,.6);display:block}
.pagehead .lede{margin-top:14px;max-width:52ch;color:rgba(17,17,16,.82)}
.pagehead-grid{display:grid;grid-template-columns:1.15fr .85fr;gap:38px;align-items:end}
.pagehead-aside{border-left:1px solid rgba(17,17,16,.22);padding-left:30px}
.pagehead .headstats > span + span{border-left-color:rgba(17,17,16,.24)}
@media(max-width:900px){.pagehead-grid{grid-template-columns:1fr;gap:22px}
  .pagehead-aside{border-left:0;padding-left:0;border-top:1px solid rgba(17,17,16,.22);padding-top:20px}}

/* The fifteen articles sit folded until you are inside the ROE, so the rail
   stays readable from every other K318 page. */
.rail-l .roe-subs{display:grid;grid-template-rows:0fr;overflow:hidden;
  transition:grid-template-rows var(--dur) var(--ease),opacity .3s var(--ease);opacity:0}
.rail-l .roe-subs > *{min-height:0;display:flex;flex-direction:column;gap:11px}
.rail-l .roe-subs.open{grid-template-rows:1fr;opacity:1;margin-top:2px;overflow:visible}
/* once open the run must not clip — the last articles were being cut off */
.rail-l .roe-subs.open > *{overflow:visible}

/* ---------- the section band, held at the top ---------- */
/* Sticky, but it condenses: past the fold it drops the lede and the stat run and
   keeps only the eyebrow and the name, so it costs one slim bar rather than a
   third of the window. --head-h is what everything else sticky sits below. */
:root{--head-h:62px}
.pagehead,.ar-head{position:sticky;top:var(--top-h);z-index:30;
  transition:padding var(--dur) var(--ease),background var(--dur) var(--ease)}
.pagehead .h1,.ar-head .h1{transition:font-size var(--dur) var(--ease),margin var(--dur) var(--ease)}
.pagehead .lede,.ar-head .ar-lede,.pagehead-aside,.ar-head .ar-hero img{
  transition:opacity .22s var(--ease),max-height var(--dur) var(--ease),margin var(--dur) var(--ease)}

/* A page too short to scroll can opt its band out of the sticky-condense: it
   stays in flow and scrolls away, rather than jittering through the collapse
   over a few pixels. proto.js skips the scroll handler for it too. */
.pagehead--static{position:static}
.pagehead.is-stuck,.ar-head.is-stuck{padding-top:11px;padding-bottom:12px;
  border-bottom:1.4px solid var(--ink);box-shadow:0 10px 22px -20px rgba(0,0,0,.5)}
.pagehead.is-stuck .h1,.ar-head.is-stuck .h1{font-size:clamp(26px,2.4vw,32px);margin:5px 0 0}
/* .sb-lede was never in this list, so the stack builder's header stayed at
   full height for ever — 228px of a short window held by a sentence you have
   already read. */
.pagehead.is-stuck .lede,.pagehead.is-stuck .sb-lede,.ar-head.is-stuck .ar-lede,
.pagehead.is-stuck .pagehead-aside,.ar-head.is-stuck .ar-hero img{
  opacity:0;max-height:0;margin:0;overflow:hidden;pointer-events:none}
/* The upcoming-event tag rides in .ar-lede-row beside the lede. When the band
   is stuck the lede collapses, so the row is dead weight under the shrunk title.
   Zero the row's margin and lift the tag out of it, pinned to the right of the
   compact band at the page gutter — absolute right is measured from the padding
   box (the window edge), so it takes the gutter explicitly rather than sitting
   flush against the edge — so the tag stays visible on scroll without holding
   the row open. */
.ar-head.is-stuck .ar-lede-row{margin-top:0}
.ar-head.is-stuck .ev-state{position:absolute;right:clamp(16px,3vw,40px);top:50%;transform:translateY(-50%);margin:0}
.pagehead.is-stuck .eyebrow{font-size:8.5px}
.pagehead.is-stuck .pagehead-grid,.ar-head.is-stuck .ar-hero{display:block;gap:0}

/* everything else that sticks now sits below the condensed band.
   The height has to come down by the same amount it was pushed down, or the
   rail is still sized for a window that starts higher — which is what put the
   last few entries of the K318 rail behind the sticky footer. */
/* The 16px is air below the condensed band. On a page with no band there is
   nothing to sit below, and the offset only pushed the rail 16px past the top
   of its own column — so it rode pre-stuck, out of line with everything
   beside it. The gap belongs to the band and leaves with it. */
:root{--head-gap:16px}
.rail-sticky,.side--reads,.ctx{
  top:calc(var(--top-h) + var(--head-h) + var(--head-gap));
  max-height:calc(var(--view-h) - var(--head-h) - var(--head-gap))}
.glhead{top:calc(var(--top-h) + var(--head-h))}
.ar-h2,.lettergroup,.record{scroll-margin-top:calc(var(--top-h) + var(--head-h) + 16px)}
@media(max-width:900px){:root{--head-h:0px}.pagehead,.ar-head{position:static}}

/* In a 340px rail, buttons stack rather than squeeze — a two-line button label
   reads as a mistake. */
.btn-stack{display:grid;gap:8px;margin-top:20px}
.btn-stack .btn{justify-content:center;text-align:center;white-space:nowrap}
/* the rail is 340px; buttons stack, always */
.btn-stack .btn{min-width:0;overflow:hidden;text-overflow:ellipsis}

/* ---------- the tournament rotation ----------
   Three states, split by what you have to DO about a row rather than
   by what it is: flare for the one gone by tonight, acid for what is
   on with room, sand for what has not started. K318's own dates keep
   the pink they have everywhere else.

   The rows are stamped by npm run proto; the state on them is
   recomputed in the browser, because whether something ends tonight
   depends on when you are reading. */
.ending{width:9px;height:9px;border-radius:50%;background:var(--flare);box-shadow:0 0 0 3px rgba(255,74,23,.24);margin-top:5px}
.running{width:9px;height:9px;border-radius:50%;background:var(--acid);box-shadow:0 0 0 3px rgba(230,255,46,.35);margin-top:5px}
.coming{width:9px;height:9px;border-radius:50%;background:var(--sand);margin-top:5px}
.passed{width:9px;height:9px;border-radius:50%;background:var(--rule);margin-top:5px}

/* The tier colours. The calendar reads them off its row dots, the key off its chips. */
.dot--epic{background:var(--ink)}
.dot--kvk{background:var(--flare)}
.dot--standard{background:var(--acid)}
.dot--mini{background:var(--sand);border:1px solid var(--rule)}
.dot--kingdom{background:var(--pink)}
/* Grouped events (Ragnarök, Trials of Olympus): no box of their own. The row's
   own top/bottom hairlines bound them like any other row; the parts nest inside
   as Version 2 clean rows (name + note, no connectors). */
.cal-parts-label{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--grey);margin:14px 0 4px}
.cal-parts{display:flex;flex-direction:column}
.cal-part{display:flex;gap:14px;align-items:baseline;padding:8px 0}
.cal-part + .cal-part{border-top:1px solid var(--rule)}
.cal-part .cpn{font-weight:500;font-size:15px;flex:0 0 auto;min-width:180px}
.cal-part .cpd{color:var(--grey);font-size:13px}
/* A clan tournament needs somebody else before it starts, so it is
   marked in the heading rather than buried in the rules. */
.cal-scope,.cal-tag{
  display:inline-block;margin-left:10px;vertical-align:2px;
  font-family:var(--mono);font-size:8px;font-weight:500;letter-spacing:.12em;
  text-transform:uppercase;padding:3px 7px;border-radius:var(--r-pill);
}
.cal-scope{background:var(--lilac);color:var(--ink)}
.cal-tag{background:var(--bone);color:var(--grey);border:1px solid var(--rule)}
/* The four cross-kingdom PvP events the KvK treaty names. Flagged in the data
   (kvk:true), marked here so the calendar shows at a glance which rows are the
   ones you can fight other kingdoms in. Flare outline, no fill — a mark, not a
   loud cell. */
.cal-tag--kvk{background:var(--bone);border-color:var(--flare);color:var(--flare)}

/* Event-guide state tag — set live by proto.js from the schedule (window.ATLAS).
   It rides at the bottom-right of the guide header, aligned to the foot of the
   lede, so it never adds a row above the title. Hidden until it has something to
   say, so a guide for an event that is not on the calendar shows nothing. Lives
   here (not lesson.css) so it does not inline into every Academy lesson. */
.ar-lede-row{display:flex;align-items:flex-end;gap:8px 24px;flex-wrap:wrap;margin-top:16px}
.ar-lede-row .ar-lede{margin-top:0;margin-bottom:0}
.ev-state{flex:0 0 auto;margin-left:auto;font-family:var(--mono);font-size:10.5px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;border-radius:var(--r-pill);padding:4px 11px;white-space:nowrap}
.ev-state:empty{display:none}
.ev-state.is-live{background:var(--flare);color:#fff}
.ev-state.is-soon{border:1px solid var(--rule);color:var(--grey)}

/* A drawn placeholder standing where an illustration will go.
 *
 * It takes the geometry of the image it replaced, NOT the whole frame.
 * A gallery cell has a caption underneath it — the monster's name, its
 * family — and a placeholder sized to the cell pushes that caption out
 * of the box entirely.
 *
 * The child combinator matters too: a placeholder is a <span>, and so
 * is the second line of every caption, so .gcell span would otherwise
 * set the placeholder in 8px mono. */
.gcell > .ph{width:100%;max-width:88px;height:64px;display:block;margin:0 auto}
.plate > .ph,
.readfeature-plate > .ph{width:100%;height:100%;min-height:110px;display:block}
.thumb.ph{width:100%;height:100%;display:block}
/* An article's inline figure, standing in for a drawing. */
.ar-img.ph{display:block;width:100%;min-height:200px;border-radius:var(--r)}

/* Both halves of a band starting on the same line. The default is
   bottom-aligned, which suits a band whose right side is a stat row; a
   right side holding a heading, a bar and a button has to start where
   the left side's eyebrow does. */
.pagehead-grid--top{align-items:start}

/* Button and prompt on one line, so the right column stops out-growing
   the left and the band reads as one band. */
.acad-cta{margin-top:18px;display:flex;gap:18px;align-items:center;flex-wrap:wrap}
/* An account is an offer, not a gate, so it is quieter than the button
   beside it. */
.acad-account{
  margin:0;max-width:26ch;font-family:var(--mono);font-size:9px;font-weight:500;
  letter-spacing:.1em;text-transform:uppercase;line-height:1.8;color:rgba(17,17,16,.6);
}
.acad-account a{color:var(--ink);border-bottom:1px solid rgba(17,17,16,.35)}
.acad-account a:hover{color:var(--blue);border-color:var(--blue)}

/* ---------- the two doors ----------
   Sign in and the kingdom gate are the same kind of page — a door with
   a field in it — so they share a shape: the band, the form on the
   left, the reason it is worth doing on the right. */
.signin{display:grid;grid-template-columns:minmax(0,1fr) 330px;flex:1;align-items:start}
.signin-box{padding:38px clamp(16px,3vw,40px) 54px;max-width:460px}
.signin-aside{
  border-left:1px solid var(--rule);align-self:stretch;
  padding:38px clamp(16px,3vw,40px) 54px 30px;background:var(--bone);
}
.signin-aside h4{margin:0 0 16px;color:var(--grey)}
/* The prototype's .field rule only ever met text, textarea and select;
   a password box is none of those, and it is the field that matters
   most on both of these pages. */
.signin .field input[type=password]{
  width:100%;font-family:var(--sans);font-size:16px;font-weight:400;
  color:var(--ink);background:var(--paper);
  border:1px solid var(--rule);border-radius:var(--r);padding:11px 13px;
}
.signin .field input:focus{outline:2px solid var(--blue);outline-offset:1px;border-color:var(--blue)}
.signin .field label em{font-style:normal;color:var(--grey-2)}
.signin .field:first-child{margin-top:0}
.signin-submit{margin-top:26px;width:100%}
.signin-error{
  margin:0 0 22px;padding:12px 14px;border-radius:var(--r);
  background:var(--pink);color:var(--ink);font-size:15px;line-height:1.4;
}
.signin-swap{
  margin:22px 0 0;font-family:var(--mono);font-size:9.5px;font-weight:500;
  letter-spacing:.12em;text-transform:uppercase;color:var(--grey);
}
.signin-swap a{color:var(--blue)}
.signin-list{margin:0;padding:0;list-style:none}
.signin-list li{
  padding:0 0 14px;margin-bottom:14px;border-bottom:1px solid var(--rule);
  font-size:15px;line-height:1.45;color:var(--ink-2);
}
.signin-list li:last-child{border-bottom:0}
.signin-list b{font-weight:600;color:var(--ink)}
.signin-note{
  margin:8px 0 0;font-family:var(--mono);font-size:9px;font-weight:500;
  letter-spacing:.1em;text-transform:uppercase;line-height:1.7;color:var(--grey);
}
@media(max-width:900px){
  .signin{grid-template-columns:1fr}
  .signin-box{max-width:none}
  .signin-aside{border-left:0;border-top:1px solid var(--rule);padding-left:clamp(16px,3vw,40px)}
}

/* The monster and item records, in the modal shell. What is particular
   to each is only what goes at the top of it. */
.mon-art{
  background:var(--bone);border-radius:var(--r);padding:18px;margin-bottom:20px;
  display:flex;align-items:center;justify-content:center;
}
/* The tile's own shape, so a drawing cut once works in the tile, the modal and
   the Register index. Full bleed: these are painted panels with their own
   ground rather than cut-outs. */
.mon-art--has{aspect-ratio:1.77;height:auto;min-height:0;padding:0;overflow:hidden;
  border-radius:var(--r)}
.mon-art--has img{width:100%;height:100%;object-fit:cover;object-position:center top;
  display:block}
/* The codex bestiary cards are 360x440 with a ground of their own. Cropped to
   the tile's landscape they lose half the drawing, so they sit inside the
   plate instead of filling it. */
.mon-art--in{background:var(--lilac)}
.mon-art--in img{object-fit:contain;object-position:center}

/* The game's own stat card, in the order it prints it. */
.mon-figs{display:grid;grid-template-columns:repeat(auto-fit,minmax(88px,1fr));
  gap:14px;margin-top:14px;padding-bottom:16px;border-bottom:1px solid var(--rule)}
/* Four figures across a phone fit three to a row and strand the fourth. Two
   by two reads as a stat card; three and a leftover reads as a mistake. */
@media(max-width:560px){.mon-figs{grid-template-columns:1fr 1fr}}
.mon-figs div{display:flex;flex-direction:column;gap:3px}
.mon-figs b{font-size:26px;line-height:1}
.mon-figs span{font-family:var(--mono);font-size:8.5px;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;color:var(--grey)}
.mon-feats{display:flex;flex-wrap:wrap;gap:6px;margin-top:14px}
.mon-bon{margin-top:12px}
.mon-bon div{display:flex;justify-content:space-between;gap:16px;padding:9px 0;
  border-bottom:1px solid var(--rule);font-size:15px;color:var(--ink-2)}
.mon-bon div:last-child{border-bottom:0}
.mon-bon b{font-weight:600;color:var(--ink);white-space:nowrap}
/* The Herald's field chips, reused — same job, same size. */
.mon-feats .chip-f{font-family:var(--mono);font-size:8.5px;font-weight:500;
  letter-spacing:.11em;text-transform:uppercase;color:var(--ink-2);background:var(--bone);
  border-radius:var(--r-pill);padding:5px 10px;white-space:nowrap}
.mon-art .ph{width:100%;height:180px;display:block}
.modal-body .qv-pills{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
/* "font:inherit" is the usual button reset, but it is a shorthand — it took
   the pill's mono, its size and its weight with it and handed the tag the
   body's face at the body's size. Reset only what a button needs, and take
   the tag size the Herald already uses for the same job. */
.modal-body .pill{cursor:pointer;background:none;
  font-family:var(--mono);font-size:8.5px;font-weight:500;letter-spacing:.11em;
  text-transform:uppercase;padding:5px 10px}
.modal-body .pill:hover{border-color:var(--ink);color:var(--ink)}
.item-list{margin:8px 0 0;padding-left:20px;list-style:disc}
.item-list li{
  margin-top:6px;font-family:var(--serif);font-weight:300;font-size:16px;
  line-height:1.5;color:var(--ink-2);
}
.item-list li::marker{color:var(--grey-2)}
/* The shell scrolls its own body, so a long record cannot push its own
   close button off the top of a short screen. */
.modal-box{max-height:88vh;display:flex;flex-direction:column}
.modal-box > .modal-head,.modal-box > .modal-foot{flex:none}
.modal-box > .modal-body{overflow-y:auto;min-height:0}

/* ---------- the calendar's three columns ----------
   The rail on the left is where you are; the dates in the middle; the
   catalogue on the right, beside the dates rather than below thirty-
   nine rows of them, where nobody would reach it. */
.cols--cal{grid-template-columns:300px minmax(0,1fr) 260px}
/* The column dividers are painted on the GRID, not on the columns — a 1px
   gradient the full height of the layout — so they run to the bottom of the
   window whatever the columns hold. A border on the sidebar itself stopped
   where the rotation list stopped, which on a 12,000px page is about four
   inches in. The left divider comes from .cols; this adds the right one at
   the rotation column's edge, and the sidebar gives up its own border so the
   two do not paint a double line a pixel apart. */
.cols--cal{
  background-image:linear-gradient(var(--rule),var(--rule)),
                   linear-gradient(var(--rule),var(--rule));
  background-size:1px 100%,1px 100%;
  background-position:300px 0,calc(100% - 260px) 0;
  background-repeat:no-repeat;
}
.side--cal{
  border-left:0;padding:26px 24px;position:sticky;
  top:var(--top-h);align-self:start;max-height:var(--view-h);
  overflow-y:auto;overscroll-behavior:contain;
}
.side-note{margin:10px 0 0;font-size:13.5px;line-height:1.5;color:var(--grey)}
.side--cal .evlist{display:block;margin-top:14px}
.side--cal .evlist a{display:block;font-size:14.5px;padding:8px 0;border-bottom:1px solid var(--rule)}
.side--cal .evlist a:hover{color:var(--blue)}

/* A colour that has to be learned by inference is a colour that gets
   ignored, so the key sits above the list rather than being implied. */
.cal-key{display:flex;gap:12px 18px;flex-wrap:wrap;align-items:center;flex:1 1 auto;min-width:0}
.cal-key-item{
  display:inline-flex;align-items:center;gap:8px;font-family:var(--mono);
  font-size:9px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--grey);
}
.dot--ending{background:var(--flare)}
.dot--running{background:var(--acid)}
.dot--coming{background:var(--sand)}
.dot--passed{background:var(--rule)}
.dot--k318{background:var(--pink)}


/* The side column holds the summon-mastery rotation — the one list on this
   page you read weeks out — so below 1200px it drops under the calendar
   rather than disappearing. Hiding it was fine when it only held a catalogue
   of every event; it is not fine now that the rotation lives there. */
@media(max-width:1200px){
  /* The rotation column is gone, so its divider goes with it. */
  .cols--cal{grid-template-columns:300px minmax(0,1fr);
    background-image:linear-gradient(var(--rule),var(--rule));
    background-size:1px 100%;background-position:300px 0}
  .side--cal{grid-column:1/-1;position:static;max-height:none;overflow:visible;
    border-top:1px solid var(--rule);padding:28px 24px 34px}
}
/* Below 900 the columns stack, so there is nothing left to divide. The reset
   has to be restated here: .cols drops its own background at this width, but
   .cols--cal sets one later in the file and would otherwise win and leave a
   rule ruled down the middle of a single-column page. */
@media(max-width:900px){.cols--cal{display:block;background-image:none}}

/* ---------- the read layout, everywhere ----------
   From the V1 study. It lived inside read-cp-runs.html's own <style>
   block, which is why the Register's twelve sections could not see it
   — they had the sidebar's rules but not the column that holds one. */
.cols--reads{
  /* The centre stops at the measure; everything past it goes to the
     sources rail, which has more to show than the prose has to gain.
     That makes the right track elastic, so its rule can no longer be
     painted at a fixed offset on the grid — it is a border on the
     cell itself now, and the cell stretches the full column height. */
  grid-template-columns:300px minmax(0,var(--read-max)) minmax(300px,1fr);
  background-image:linear-gradient(var(--rule),var(--rule));
  background-size:1px 100%;
  background-position:300px top;background-repeat:no-repeat;
}
.cols--reads .rail-l{background:var(--paper);padding-top:34px;top:var(--top-h)}
/* On the horizontal mobile rail, keep the band's top and bottom padding even. */
@media(max-width:900px){.cols--reads .rail-l{padding-top:12px}}
/* The prose begins on the same line as the rail beside it. It used to
   start 74px lower — the body's own top padding, plus the margin the
   first heading carries to hold itself off the paragraph above, which
   for the first heading is nothing at all. */
.cols--reads .main{padding-top:34px}
.ar-body > :first-child{margin-top:0}
/* The cell holds the border and the height; the pane inside it holds
   the stickiness. Sticky on the cell itself would collapse it to the
   height of its own content and the rule would stop mid-page. */
.cols--reads .side--reads{
  position:static;align-self:stretch;max-height:none;overflow:visible;
  border-left:1px solid var(--rule);padding:0}
.cols--reads .side--reads > .sticky-in{
  position:sticky;top:calc(var(--top-h) + var(--head-h) + var(--head-gap));
  /* --rail-avail tracks the pane's live top each frame (proto.js), so the rail
     always runs the whole way to the footer, whether at rest or stuck. */
  max-height:var(--rail-avail, calc(100dvh - 404px));
  overflow-y:auto;overscroll-behavior:contain;padding:34px 24px}
/* The terms a piece leans on, given a ground of their own — the one
   thing in the rail a reader reaches for mid-sentence. */
/* The entry's own drawing, sitting in the head beside its definition. The
   head is the tinted band, so the art lands on its category's colour without
   needing a plate of its own. */
/* The band under the name: the stone, then the three things worth knowing,
   run across rather than stacked. It sits in the head on the head's own
   beige, so it needs no panel of its own — a rule separates it from the
   definition beneath instead. */
/* One hairline weight throughout — the band is a quiet frame around three
   figures, not a heading rule. */
.gem-card{--gem-rule:rgba(17,17,16,.14);
  display:flex;align-items:stretch;gap:0;
  margin:16px 0 0;padding:0;
  border-top:1px solid var(--gem-rule);
  border-bottom:1px solid var(--gem-rule)}
/* The stone's own column of the band, carrying the same side padding as the
   figures beside it — so the drawing centres in the space that runs up to the
   first divider, rather than sitting against the band's left edge with the
   gap doing the spacing. No ground: the head's beige runs through behind it. */
.gem-plate{flex:none;align-self:center;
  width:clamp(84px,10vw,104px);height:clamp(56px,6.6vw,68px);
  padding:0 clamp(10px,1.6vw,18px);
  display:grid;place-items:center;background:none;overflow:hidden}
/* Nudged 5px left of true centre. The drawing's own bounding box is not its
   optical centre — the stone leans right inside it — so measuring centred and
   looking centred are not the same thing here. */
.entry-art{max-width:100%;max-height:100%;width:auto;height:auto;
  object-fit:contain;display:block;transform:translateX(-5px)}
.gem-facts{margin:0;display:flex;flex:1;min-width:0}
/* A hairline between the facts rather than a gap doing the separating —
   three figures in a row read as three, not as one run-on line. Drawn as an
   inset rule rather than a border: a border runs the full height and welds
   the two horizontals into a table, which is not what this is. */
.gem-facts div{position:relative;
  display:flex;flex-direction:column;justify-content:center;gap:5px;
  flex:1;min-width:0;padding:20px clamp(10px,1.6vw,18px)}
/* Every column gets one, the first included — the stone is a column of the
   band too, and without a rule after it the drawing and the effect read as a
   single unit. */
.gem-facts div::before{content:"";position:absolute;left:0;top:14px;bottom:14px;
  width:1px;background:var(--gem-rule)}
.gem-facts dt{font-family:var(--mono);font-size:8.5px;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;color:var(--grey)}
.gem-facts dd{margin:0;font-size:clamp(15px,1.5vw,19px);font-weight:600;
  letter-spacing:-.015em;color:var(--ink);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
/* Which of the two rare-crypt appearances, as a mark rather than a clause.
   The value becomes a flex row so the disc centres on the word rather than
   sitting on the text baseline, which dropped it below the cap height. */
.gem-facts dd:has(.gem-fx){display:inline-flex;align-items:center}
.gem-fx{display:inline-flex;align-items:center;justify-content:center;flex:none;
  width:19px;height:19px;margin-left:9px;border-radius:50%;
  font-family:var(--mono);font-size:9px;font-weight:500;font-style:normal;
  letter-spacing:0;line-height:1}
.gem-fx--r{background:var(--flare);color:#fff}
.gem-fx--l{background:var(--blue);color:#fff}
/* The band is the head's last thing, so the definition under it keeps its air. */
.gem-card + .lede-wrap{margin-top:20px}

/* The definition, folded away once the reading starts.
   grid-template-rows 0fr/1fr rather than max-height: it animates to the
   content's real height, so a two-line definition and a six-line one both
   close cleanly instead of snapping at an arbitrary cap. */
.modal-box .entry-head .lede{margin:0;max-width:56ch;color:rgba(17,17,16,.82)}
.modal-box .lede-wrap{display:grid;grid-template-rows:1fr;
  transition:grid-template-rows .34s cubic-bezier(.2,.75,.2,1),
    opacity .2s ease,margin-top .34s cubic-bezier(.2,.75,.2,1)}
.modal-box .lede-wrap > .lede{overflow:hidden;min-height:0}
.modal-box.tight .lede-wrap{grid-template-rows:0fr;opacity:0;margin-top:0}

/* The name shrinks with it, so what is gained is reading and not white space. */
.modal-box .modal-head.entry-head{transition:padding .34s cubic-bezier(.2,.75,.2,1)}
.modal-box .entry-t{font-size:clamp(30px,3.4vw,44px);margin:0;
  transition:font-size .34s cubic-bezier(.2,.75,.2,1)}
.modal-box.tight .entry-t{font-size:clamp(22px,2.4vw,30px)}
.modal-box.tight .modal-head.entry-head{padding-top:20px;padding-bottom:0}
.modal-box.tight .gem-card{margin-top:12px}
/* Folded, the band's bottom hairline and the head's own black rule end up a
   few pixels apart and read as a mistake. The black one wins: the grey goes,
   and the head closes right under the figures. */
.modal-box.tight .gem-card{border-bottom-color:transparent}
@media(prefers-reduced-motion:reduce){
  .modal-box .lede-wrap,.modal-box .entry-t,
  .modal-box .modal-head.entry-head{transition:none}
}

/* The ladder, at the end of the reading. */
.gem-th{margin:30px 0 0}
.gem-note{margin:12px 0 0;font-size:14px;line-height:1.5;color:var(--grey)}
/* Three columns and a drawing do not fit a phone. The rules go with them —
   a vertical rule between stacked rows separates nothing. */
@media(max-width:620px){
  .gem-card{flex-direction:column;align-items:flex-start;gap:0;padding-bottom:16px}
  .gem-plate{width:60px;height:60px;padding:0;align-self:flex-start;margin:16px 0 6px}
  /* Stacked, the stone sits against the left edge — nothing to centre it in. */
  .entry-art{transform:none}
  .gem-facts{flex-direction:column;width:100%;gap:0}
  .gem-facts div{flex:none;padding:11px 0;
    border-top:1px solid var(--gem-rule)}
  .gem-facts div::before{display:none}
  .gem-facts div:first-child{border-top:0}
}

.glossbox{background:var(--blue);color:#fff;border-radius:var(--r);padding:18px 20px 20px}
.glossbox .rl{color:rgba(255,255,255,.72);margin:0 0 9px}
.glossbox .rp{color:#fff;font-size:15px;line-height:1.55}
.glossbox a{color:#fff;border-bottom:1px solid rgba(255,255,255,.4)}
.glossbox a:hover{border-color:#fff}
.glossbox .grow{display:block;padding:11px 0;border-top:1px solid rgba(255,255,255,.18);border-bottom:0;text-decoration:none}
.glossbox .grow:first-of-type{border-top:0;padding-top:2px}
.glossbox .grow:last-of-type{padding-bottom:0}
.glossbox .grow b{display:block;font-size:16px;font-weight:600;letter-spacing:-.012em;color:#fff}
.glossbox .grow span{display:block;margin-top:3px;font-size:13px;line-height:1.45;color:rgba(255,255,255,.82)}
.glossbox .grow:hover b{text-decoration:underline}
.glossbox .grow:not(a):hover b{text-decoration:none;cursor:default}

/* A link inside body copy. Underlined rather than bordered so it survives a
   line break, at the thickness and offset the calendar and roster rows
   already use. It carries its own weight, which is why a linked title needs
   no ** in the data file. */
.ar-a{font-weight:600;text-decoration:underline;text-decoration-thickness:1px;
  text-underline-offset:3px;text-decoration-color:rgba(17,17,16,.35);
  transition:text-decoration-color .15s ease}
.ar-a:hover{text-decoration-color:currentColor}
/* Air after the glossary tile. .side-rl on its own loses to the
   rail's own .rl rule, which zeroes the margin — so it is said at the
   specificity that actually applies. */
.side-rl,.side--reads .rl.side-rl{margin-top:34px}
.side-cta{margin-top:20px}
/* Where you are, and what stands behind the page. */
.ar-topline{
  display:flex;justify-content:space-between;gap:24px;flex-wrap:wrap;
  font-family:var(--mono);font-size:9.5px;font-weight:500;letter-spacing:.14em;
  text-transform:uppercase;color:var(--grey);
}
@media(max-width:1200px){
  /* No room for three tracks. The sources drop under the piece rather
     than out of it — they are what the piece stands on. */
  .cols--reads{grid-template-columns:300px minmax(0,1fr);background-image:none}
  .cols--reads .side--reads{grid-column:2;border-left:0;
    border-top:1px solid var(--rule)}
  .cols--reads .side--reads > .sticky-in{position:static;max-height:none}
}
@media(max-width:900px){.cols--reads{display:block}}


/* ==============================================================
   The article body
   --------------------------------------------------------------
   These lived inside each article page's own <style> block —
   duplicated across six of them, and missing from the Register's
   twelve sections, which is why .ar-intro had nothing to do there.
   One copy, here, so a change to how the Atlas sets prose lands
   everywhere at once.
   ============================================================== */
.ar-head .h1{font-size:clamp(38px,4.6vw,58px);margin:12px 0 0;max-width:17ch}
.ar-hero{display:grid;grid-template-columns:1.15fr .85fr;gap:36px;align-items:center}
.ar-hero img{width:100%;height:auto;display:block;max-height:280px;object-fit:contain}
.ar-lede{margin-top:16px;max-width:54ch;font-family:var(--serif);font-weight:300;
  font-size:clamp(18px,1.5vw,21px);line-height:1.5;color:rgba(17,17,16,.82)}
.ar-body{padding:0 0 24px;max-width:none}
.ar-h2{margin:40px 0 0;font-size:clamp(26px,2.6vw,34px);font-weight:800;letter-spacing:-.03em;
  line-height:1.08;scroll-margin-top:calc(var(--top-h) + 20px)}
.ar-h3{margin:26px 0 0;font-size:20px;font-weight:600;letter-spacing:-.02em}
/* An icon leading a subsection heading (the chest-source sections). */
.ar-h3 svg{width:32px;height:32px;padding:7px;box-sizing:border-box;background:var(--blue);border-radius:50%;color:#fff;vertical-align:-10px;margin-right:11px}
/* A pull-quote: one relevant line lifted from the article and set big in the
   Walkout display cut, the way the wordmark reads. Used sparingly. */
.ar-pull{font-family:var(--script);font-weight:400;font-size:clamp(27px,3.3vw,38px);
  line-height:1.08;letter-spacing:-.005em;color:var(--ink);margin:36px 0;
  padding:2px 0 2px 22px;border-left:3px solid var(--blue);max-width:none}
/* Highlighter for a phrase that matters: always the GP neon yellow (--acid),
   never another accent, cloned across line breaks so a wrapped highlight keeps
   its shape. */
.ar-mark{background:var(--acid);color:var(--ink);font-weight:500;
  padding:.02em .22em;border-radius:3px;
  -webkit-box-decoration-break:clone;box-decoration-break:clone}
.ar-p{margin:14px 0 0;font-family:var(--serif);font-weight:300;font-size:18px;line-height:1.62;color:var(--ink-2)}
.ar-p b{font-weight:600;color:var(--ink)}
/* The walkout: a script sign-off on the last line, matching the chest guide. */
.ar-walkout{display:block;font-family:var(--script);color:var(--blue);
  font-size:clamp(14px,calc(6vw - 3px),46px);line-height:1.08;letter-spacing:.01em;margin-top:32px}
/* A sentence that leads a paragraph rather than sitting inside one. */
.ar-lead{display:block;font-weight:600;color:var(--ink)}
/* The instruction a step ends on — do this, now. */
.ar-rec{font-weight:600;color:var(--ink)}
.ar-ul li .ar-lead{margin-bottom:3px}
.ar-ul{margin:14px 0 0;padding-left:20px}
.ar-ul li{margin-top:9px;font-family:var(--serif);font-weight:300;font-size:17px;line-height:1.55;color:var(--ink-2)}
.ar-ul li b{font-weight:600;color:var(--ink)}
.ar-steps{margin:18px 0 0;padding:0;list-style:none;counter-reset:s}
.ar-steps li{counter-increment:s;position:relative;padding:14px 0 14px 46px;border-top:1px solid var(--rule);
  font-family:var(--serif);font-weight:300;font-size:17px;line-height:1.55;color:var(--ink-2)}
.ar-steps li b{font-weight:600;color:var(--ink)}
.ar-steps li::before{content:counter(s,decimal-leading-zero);position:absolute;left:0;top:17px;
  font-family:var(--mono);font-size:10px;font-weight:500;letter-spacing:.1em;color:var(--grey)}
.ar-call{border-radius:var(--r);padding:18px 20px;margin:24px 0 0;background:var(--bone);border:1px solid var(--rule)}
/* The in-article calculator: a framed panel like a callout, two number fields
   off the scout report, and the result set big in blue so the figure lands. */
.ar-calc{border-radius:var(--r);border:1px solid var(--rule);background:var(--bone);padding:18px 20px;margin:24px 0 0}
.ar-calc-h{font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.13em;text-transform:uppercase;color:var(--grey);margin-bottom:14px}
.ar-calc-fields{display:flex;flex-wrap:wrap;gap:16px}
.ar-calc-f{flex:1 1 160px;display:flex;flex-direction:column;gap:7px}
.ar-calc-f>span{font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--grey)}
.ar-calc-f input{font-family:var(--sans);font-size:22px;font-weight:800;letter-spacing:-.02em;font-variant-numeric:tabular-nums;color:var(--ink);background:var(--paper);border:1px solid var(--rule);border-radius:var(--r);padding:9px 12px;width:100%}
.ar-calc-f input:focus{outline:none;border-color:var(--blue)}
.ar-calc-out{display:flex;flex-wrap:wrap;gap:28px;margin-top:18px;padding-top:16px;border-top:1px solid var(--rule)}
.ar-calc-r{display:flex;flex-direction:column;gap:4px}
.ar-calc-r b{font-family:var(--sans);font-size:34px;font-weight:800;letter-spacing:-.04em;font-variant-numeric:tabular-nums;line-height:.9;color:var(--blue)}
.ar-calc-r>span{font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--grey)}
.ar-calc-note{margin:14px 0 0;font-family:var(--serif);font-weight:300;font-size:15px;line-height:1.5;color:var(--ink-2)}
/* The loadout picker uses .field labels over the Atlas's own .asel dropdowns
   (atlasSelect enhances the plain selects); this only lays them out on one row. */
.ar-calc--loadout .ld-picks{display:flex;flex-wrap:wrap;gap:16px 22px;margin-bottom:2px}
.ar-calc--loadout .ld-picks .field{margin-top:0;flex:1 1 150px;min-width:0}
.ar-calc--loadout .asel{width:100%}
.ar-calc--loadout .asel-btn{width:100%;justify-content:space-between}
.ar-calc--loadout .ar-pair{margin-top:20px}
/* Wide horizontal cards, stacked, for the captain setups. Reuses the bone
   sheet and an acid icon chip like the table keys. */
.ar-herocards{display:flex;flex-direction:column;gap:12px;margin:22px 0 0}
.ar-herocard{display:flex;gap:15px;align-items:flex-start;background:var(--bone);border:1px solid var(--rule);border-radius:18px;padding:16px 20px}
.ar-herocard-i{flex:none;display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:10px;background:var(--acid);color:var(--ink)}
.ar-herocard-i svg{width:19px;height:19px}
.ar-herocard-b{min-width:0}
.ar-herocard-t{display:block;font-family:var(--sans);font-size:16.5px;font-weight:700;letter-spacing:-.01em;color:var(--ink);margin-bottom:3px}
.ar-herocard-b p{margin:0;font-family:var(--serif);font-weight:300;font-size:14.5px;line-height:1.5;color:var(--ink-2)}
.ar-herocard-b p b{font-weight:600;color:var(--ink)}
/* The captain picker reuses .chips / .chip-opt (multi-select) and renders its
   recommendations as the same hero cards, with a captain list inside each. */
.ar-calc--captains .chip-opt:not(.sel){background:transparent}
.cap-out{margin-top:20px}
.cap-empty{margin:0;font-family:var(--serif);font-weight:300;font-size:15px;line-height:1.5;color:var(--grey)}
.cap-rec .cap-trio{list-style:none;margin:8px 0 9px;padding:0;display:flex;flex-direction:column;gap:5px}
.cap-rec .cap-trio li{font-family:var(--serif);font-weight:300;font-size:14.5px;line-height:1.35;color:var(--ink-2)}
.cap-rec .cap-trio li b{font-family:var(--sans);font-weight:600;font-size:13.5px;color:var(--ink);margin-right:7px}
.cap-rec .cap-why{margin:0;font-family:var(--serif);font-weight:300;font-size:13.5px;line-height:1.45;color:var(--grey)}
/* The mercs Portal/City toggle: the shared chips control over two guide-card
   sets, one shown at a time. [hidden] needs the explicit rule to beat the
   tiles' own display. */
.ar-calc--mercs .chip-opt:not(.sel){background:transparent}
.ar-calc--mercs .merc-set{margin-top:18px}
.ar-calc--mercs .merc-set[hidden]{display:none}
.ar-call--warn{background:var(--acid);border-color:var(--acid)}
.ar-call--note{background:var(--neon);border-color:var(--neon)}
.ar-call--good{background:var(--blue);border-color:var(--blue);color:#fff}
.ar-call--good .ar-call-l{color:rgba(255,255,255,.75)}
.ar-call-l{display:block;font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.13em;
  text-transform:uppercase;color:var(--grey);margin-bottom:8px}
.ar-call p{margin:0;font-size:16px;line-height:1.5;font-weight:400}
.ar-call--warn .ar-call-l,.ar-call--note .ar-call-l{color:rgba(17,17,16,.62)}

/* Check-marked list: the tick stands in for the bullet, for a set of things
   the reader confirms rather than a sequence. */
.ar-ul--check{list-style:none;padding-left:0;margin:16px 0 0}
.ar-ul--check li{position:relative;padding-left:30px;margin-top:12px;font-family:var(--serif);
  font-weight:300;font-size:17px;line-height:1.55;color:var(--ink-2)}
.ar-ul--check li:first-child{margin-top:0}
.ar-ul--check li b{font-weight:600;color:var(--ink)}
.ar-ck{position:absolute;left:0;top:3px;width:18px;height:18px;color:var(--blue)}
.ar-ck svg{width:100%;height:100%;display:block}

/* Framed tiles: two across on a wide read, one on a phone. So four tiles read
   as a 2x2 and a pair sits side by side. Bone ground and a hairline, same
   family as the callout. The --stat row sets the title as a figure. */
.ar-cards{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin:22px 0 0}
.ar-card{background:var(--bone);border:1px solid var(--rule);border-radius:var(--r);padding:16px 18px}
.ar-card-t{display:block;font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.13em;
  text-transform:uppercase;color:var(--grey);margin:0}
.ar-card p{margin:8px 0 0;font-family:var(--serif);font-weight:300;font-size:16px;line-height:1.5;color:var(--ink-2)}
.ar-card p b{font-weight:600;color:var(--ink)}
.ar-cards--stat .ar-card-i{display:block;line-height:0;color:var(--blue);margin-bottom:12px}
.ar-cards--stat .ar-card-i svg{width:16px;height:16px}
.ar-cards--stat .ar-card-t{font-family:var(--sans);font-size:clamp(26px,3.5vw,34px);font-weight:800;
  letter-spacing:-.03em;line-height:1.04;color:var(--blue);text-transform:none;font-variant-numeric:tabular-nums}
.ar-cards--stat .ar-card p{margin-top:7px;font-size:14px}
@media(max-width:560px){.ar-cards{grid-template-columns:1fr}}

/* Tournament-style tiles: beige ground, blue rule and type, an icon up top,
   for describing actual things. Shared with the event guides, which inline
   their own copy; reads pull it from here. --n is the column count; the icon
   is sized to the meganav's. */
.ar-tiles{display:grid;gap:10px;grid-template-columns:repeat(var(--n,3),1fr);margin:22px 0 0}
.ar-tiles--cards{display:flex}
.ar-tiles--cards .ar-tile{flex:1 1 0;min-width:0;display:flex;flex-direction:column;text-align:left;margin:0;
  padding:20px 22px 28px;border-radius:var(--r);background:var(--bone);
  border:1px solid var(--blue);color:var(--blue)}
.ar-tile-i{display:block;margin:0;padding:0;line-height:0;color:var(--blue)}
.ar-tile-i svg{width:16px;height:16px}
.ar-tiles--cards .ar-tile figcaption>b{display:block;margin:12px 0 0;font-size:19px;font-weight:600;
  letter-spacing:-.018em;line-height:1.18;color:var(--blue)}
.ar-tiles--cards .ar-tile p b{font-weight:600}
.ar-tiles--cards .ar-tile p{margin:8px 0 0;font-family:var(--serif);font-weight:300;
  font-size:16px;line-height:1.45;color:var(--blue)}
.ar-tiles--cards .ar-tile figcaption{display:flex;flex-direction:column}
@media(max-width:560px){.ar-tiles{grid-template-columns:1fr}.ar-tiles--cards{flex-direction:column}}
.ar-tw{overflow-x:auto;margin:24px 0 0}
.ar-t{width:100%;border-collapse:collapse;font-size:15px}
.ar-t th{text-align:left;padding:10px 16px 10px 0;border-bottom:1.4px solid var(--ink);font-family:var(--mono);
  font-size:8.5px;font-weight:500;letter-spacing:.13em;text-transform:uppercase;color:var(--grey);white-space:nowrap}
.ar-t td{padding:12px 16px 12px 0;border-bottom:1px solid var(--rule);vertical-align:top;line-height:1.45;color:var(--ink-2)}
.ar-t td b{color:var(--ink);font-weight:600}
.ar-fig{margin:28px 0 0}
.ar-fig-plate{height:190px;border-radius:var(--r)}
.ar-fig figcaption{margin-top:10px;font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.12em;
  text-transform:uppercase;color:var(--grey);line-height:1.6}
.ar-band{background:var(--bone);border-radius:var(--r);padding:4px 26px 28px;margin:32px 0 0}
.ar-band .ar-h2:first-child{margin-top:26px}
.ar-open{background:var(--pink);border-radius:var(--r);padding:20px 22px;margin:32px 0 0}
.ar-q{margin:0 0 12px;font-size:16px;line-height:1.5}
.ar-q:last-child{margin-bottom:0}
.ar-unknowns{background:var(--bone);border-radius:var(--r);padding:24px 26px 26px;margin:34px 0 0}
.ar-unknowns .ar-sec{margin-top:0;padding-top:0;border-top:0}
.ar-unknowns .ar-open{background:none;padding:0;margin:16px 0 0}
.ar-checklist{border:1.6px solid var(--ink);border-radius:var(--r);margin:30px 0 0;background:var(--paper);overflow:hidden}
.ar-cl-head{background:var(--ink);color:var(--paper);padding:13px 22px}
.ar-cl-l{font-family:var(--mono);font-size:11px;font-weight:500;letter-spacing:.14em;text-transform:uppercase}
.ar-cl-gl{margin:0;padding:15px 22px 2px;font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.13em;text-transform:uppercase;color:var(--grey)}
.ar-cl-row{display:flex;gap:16px;align-items:flex-start;padding:17px 22px;border-top:1.5px solid var(--ink);cursor:pointer;transition:background var(--dur-fast) var(--ease)}
.ar-cl-row:first-of-type,.ar-cl-gl + .ar-cl-row{border-top:0}
.ar-cl-head + .ar-cl-row{border-top:1.5px solid var(--ink)}
.ar-cl-row:hover{background:var(--bone)}
.ar-cl-row input{position:absolute;opacity:0;width:1px;height:1px}
.ar-cl-box{flex:0 0 auto;width:26px;height:26px;border:1.6px solid var(--ink);border-radius:5px;display:grid;place-items:center;margin-top:1px;background:var(--paper);transition:background var(--dur-fast) var(--ease)}
.ar-cl-box svg{width:16px;height:16px;stroke:var(--ink);stroke-width:2.6;opacity:0;transition:opacity var(--dur-fast) var(--ease)}
.ar-cl-row input:checked + .ar-cl-box{background:var(--acid)}
.ar-cl-row input:checked + .ar-cl-box svg{opacity:1}
.ar-cl-row input:focus-visible + .ar-cl-box{outline:2px solid var(--blue);outline-offset:2px}
.ar-cl-t{font-size:18px;line-height:1.42;letter-spacing:-.012em;color:var(--ink)}
.ar-cl-t b{font-weight:600}
.ar-cl-row input:checked ~ .ar-cl-t{color:var(--grey)}
.ar-cl-row input:checked ~ .ar-cl-t b{text-decoration:line-through;text-decoration-thickness:1.6px}
@media(max-width:520px){.ar-cl-t{font-size:16px}}
.ar-claims{margin:26px 0 0}
.ar-claim{display:grid;grid-template-columns:50px 96px 1fr;gap:14px;padding:11px 0;
  border-top:1px solid var(--rule);align-items:baseline}
.ar-cid{font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.1em;color:var(--grey)}
.ar-claim p{margin:0;font-size:15px;line-height:1.45;color:var(--ink-2)}
.ar-sources{margin:36px 0 0;padding-top:18px;border-top:1.4px solid var(--ink)}
.read-main{padding:34px clamp(16px,3vw,40px) 30px;max-width:var(--read-max)}
.ar-topline{display:flex;justify-content:space-between;gap:24px;flex-wrap:wrap;
  font-family:var(--mono);font-size:9.5px;font-weight:500;letter-spacing:.14em;
  text-transform:uppercase;color:var(--grey)}
.read-main .h1 .morph{vertical-align:top}
.read-main .h1:hover .m-sans,.read-main .h1:hover .m-walk{
  transition-delay:calc(var(--i,0) * .16s)}
.read-main .h1:hover .m-sans{clip-path:inset(0 0 0 100%)}
.read-main .h1:hover .m-walk{clip-path:inset(0 0 0 0)}
.ar-lede{margin-top:22px;max-width:44ch;font-family:var(--serif);font-weight:300;
  font-size:clamp(19px,1.7vw,23px);line-height:1.36;color:var(--ink)}
.read-head{display:block}
/* The hero: full-bleed of the read column and flush to the top, so the drawing
   meets the nav. Negative margins cancel the read-main padding. */
.read-herotop{margin:-34px calc(-1 * clamp(16px,3vw,40px)) 28px;line-height:0;background:var(--ink)}
.read-herotop img{width:100%;height:auto;display:block}
.read-banner{margin:0 0 26px;border-radius:var(--r);overflow:hidden;line-height:0;border:1px solid var(--rule)}
.read-banner img{width:100%;height:auto;display:block}
.read-banner--ph .ph{display:block;width:100%;aspect-ratio:16/5;border-radius:0}
.read-art{width:100%;height:auto;max-height:260px;object-fit:contain;display:block}
/* The article's own plate, under the lede. Lo's drawings for these are made
   for a dark ground — cream stone, acid detail, no background of their own —
   so the plate supplies the black rather than the artwork carrying it. That
   way one file reads correctly whatever ground the page is on. */
.read-hero{margin:26px 0 0;background:var(--ink);border-radius:var(--r);
  overflow:hidden;display:flex;align-items:center;justify-content:center;
  padding:26px 20px}
.read-hero img{width:100%;max-width:520px;height:auto;display:block}
/* The same distinction the article cards make. Most drawings are composed with
   air in them and want the padding and the 520px cap — the gatehouse does. The
   goblet was drawn tight, and inside a capped, padded frame it floats in the
   middle of a colour field with nothing touching an edge. --bleed drops both
   so the drawing runs the full width of the frame and reaches its top and
   bottom. */
.read-hero--bleed{padding:0}
.read-hero--bleed img{width:100%;max-width:none;height:auto}
/* Ink suits a night scene and swallows anything else. Drawings that are dark
   line on bone need the ground the monster plates use, or they sit black on
   black and the reader sees a hole. */
.read-hero--ink{background:var(--ink)}
.read-hero--lilac{background:var(--lilac)}
.read-hero--flare{background:var(--flare)}
.read-hero--acid{background:var(--acid)}
@media (max-width:640px){.read-hero{padding:18px 14px;margin-top:20px}}
.ar-diagram svg{width:100%;height:auto;display:block;color:var(--ink)}
.ar-diagram figcaption{margin-top:12px;max-width:62ch}
.ar-diagram figcaption b{display:block;font-family:var(--sans);font-size:17px;font-weight:600;
  letter-spacing:-.018em;text-transform:none;color:var(--ink)}
.ar-diagram figcaption span{display:block;margin-top:6px;font-family:var(--mono);font-size:9px;
  font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--grey);line-height:1.6}
.ar-intro{column-count:2;column-gap:38px;margin-top:34px;padding-top:26px;border-top:1px solid var(--rule)}
.ar-intro > *{break-inside:avoid}
.ar-intro .ar-p{margin:0 0 14px}
.ar-intro .ar-p:first-child{margin-top:0}
.ar-sec + .ar-p,.ar-sec + .ar-tw,.ar-sec + .ar-pair{margin-top:16px}
/* Lo: a table lines up with the prose rather than running to the
   page edges. The bleed came from the same clamp the page uses for
   its own padding, cancelled out; it is gone, and the table keeps
   both its edges. */
.ar-pair .ar-tw{margin:0;overflow-x:auto}
.ar-pair .ar-t--dark{min-width:100%}
.ar-pair .ar-t--dark th:first-child,.ar-pair .ar-t--dark td:first-child{
  padding-left:14px}
.ar-pair .ar-t--dark th:last-child,.ar-pair .ar-t--dark td:last-child{
  padding-right:14px}
.ar-pair .datastrip{margin:0;border-radius:var(--r);
  padding:20px 22px 22px;display:flex;align-items:baseline;
  gap:10px 28px;flex-wrap:wrap}
.ar-pair .datastrip b{margin:0;font-size:clamp(36px,4vw,52px);line-height:.9;order:1}
.ar-pair .datastrip .l{order:0;flex-basis:100%;margin:0}
.ar-pair .datastrip .c{order:2;margin:0;flex:1;min-width:220px}
.ar-t--dark thead th{background:var(--charcoal);color:var(--bone);border-bottom:0;padding:12px 14px;font-size:9px}
.ar-t--dark td{padding:12px 14px;border-bottom:1px solid var(--rule)}
.ar-t--dark{border:1px solid var(--rule)}
.ar-pair .ar-t--dark tbody tr:last-child td{border-bottom:0}

/* ---------- a table whose first column is a key ----------
   Some tables exist to tell one thing from another that sounds like it —
   exploration cost against exploration efficiency, one captain slot against
   the next. That column is a label, not prose: it takes a ground of its own,
   it does not wrap mid-phrase, and it carries the set's icon in a tinted chip
   so two rows can be told apart before either is read.

   One ground for every chip, not one per row. A colour per row reads as a
   legend and invites the question of what each colour means; the acid is the
   Atlas's marker and it means "this is the key", which is true of all of
   them. The chip sits above its label rather than beside it, so the column is
   only as wide as the longest word and the prose columns keep the room. */
.ar-t--keys td:first-child{
  background:var(--bone);vertical-align:middle;color:var(--ink);font-weight:600}
.ar-t--keys th:first-child,.ar-t--keys .tk-t{white-space:nowrap}
.tkey{display:flex;flex-direction:column;align-items:flex-start;gap:9px;line-height:1.25}
.tkey .tk-i{flex:0 0 auto;width:30px;height:30px;border-radius:var(--r);
  display:grid;place-items:center;background:var(--acid)}
.tkey .tk-i svg{width:17px;height:17px;display:block}
@media(max-width:900px){.ar-t--keys .tk-t{white-space:normal}}

/* A column of short values sits better centred against the tall prose cell
   beside it. Named per table in the data, because which columns are values
   and which are prose is a fact about the table, not about the layout. */
.ar-t td.vmid{vertical-align:middle}

/* A section can name the ground it stands on before it names itself — the
   kicker a band would otherwise repeat as a heading outside it. Sits on the
   section's own top rule, so the rule reads as belonging to the pair. */
.ar-sec-eyebrow{margin:46px 0 0;padding-top:18px;border-top:1.4px solid var(--ink);
  font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.15em;
  text-transform:uppercase;color:var(--grey)}
.ar-sec-eyebrow + .ar-sec{margin-top:8px;padding-top:0;border-top:0}
.ar-band .ar-sec-eyebrow:first-child{margin-top:26px}

/* A figure's caption, given a ground of its own. Under a drawing that is
   itself mostly white space, a bare caption reads as the next paragraph
   starting early. The box closes the figure, and the margin under it stops
   the real paragraph crowding in. A modifier rather than a change to
   .ar-diagram, so the hand-written reads keep the caption they were set
   with — promote it if it turns out to be the better default. */
/* Both classes in the selector on purpose. `.ar-diagram--boxed figcaption` is
   ONE class plus a type — exactly the specificity of `.ar-diagram figcaption`
   in the read pages' own style block, which comes later in the document and
   was therefore winning. Qualifying with .ar-fig, which is on the same
   element, takes it to two classes and settles it. */
.ar-fig.ar-diagram--boxed{margin-bottom:52px}
.ar-fig.ar-diagram--boxed figcaption{
  margin-top:20px;padding:18px 20px;background:var(--bone);
  border-radius:var(--r);max-width:none}
/* One caption, not a headline over a block of mono capitals. Long copy is
   never set in caps here — it reads as shouting and it is slower. The lead
   stays bold and runs into the rest of the sentence. */
.ar-fig.ar-diagram--boxed figcaption b,
.ar-fig.ar-diagram--boxed figcaption span{
  display:inline;font-family:var(--serif);font-weight:300;
  font-size:17px;line-height:1.55;letter-spacing:0;text-transform:none;
  color:var(--ink-2);margin:0}
.ar-fig.ar-diagram--boxed figcaption b{font-weight:600;color:var(--ink)}
/* The figure announces itself above the drawing, the way a section does. It
   used to sit in the caption as a bold first line, which made the box below
   read as a heading arriving after the thing it heads. */
.ar-fig-head{margin:0 0 18px;font-family:var(--sans);
  font-size:clamp(20px,1.9vw,25px);font-weight:700;letter-spacing:-.026em;
  line-height:1.14;color:var(--ink)}

/* The standfirst holds at 44ch, which is a good measure for a short one and
   leaves a long one stranded halfway across the column. This opts a page out
   and lets it run to the column's own edge. A modifier rather than a change
   to .ar-lede, so the six hand-written reads keep the measure they were set
   with — promote it if it turns out to be the better default. */
.read-main .ar-lede.ar-lede--wide{max-width:none}

/* ---------- the night dial ----------
   The arcs draw themselves in, staggered, and any ring dims when another is
   hovered. Both are CSS so the figure stays a static SVG in the page and
   needs no script; both stop under prefers-reduced-motion, where the arcs are
   simply already drawn. */
.nightdial .nd-run,.nightdial .nd-dead{
  stroke-dasharray:var(--len) var(--len);
  stroke-dashoffset:var(--len);
  animation:nd-draw .9s cubic-bezier(.22,1,.36,1) forwards;
  animation-delay:calc(var(--i, 0) * .18s + .1s)}
.nightdial .nd-dead{animation-delay:calc(var(--i, 0) * .18s + .7s)}
@keyframes nd-draw{to{stroke-dashoffset:0}}

.nightdial .nd-ring,.nightdial .nd-key{transition:opacity .22s ease}
.nightdial:hover .nd-ring,.nightdial:hover .nd-key{opacity:.34}
.nightdial .nd-ring:hover,.nightdial .nd-key:hover{opacity:1}
/* hovering a legend row lifts its ring, and the other way round */
.nightdial:has(.nd-key[data-ring="0"]:hover) .nd-ring[data-ring="0"],
.nightdial:has(.nd-ring[data-ring="0"]:hover) .nd-key[data-ring="0"],
.nightdial:has(.nd-key[data-ring="1"]:hover) .nd-ring[data-ring="1"],
.nightdial:has(.nd-ring[data-ring="1"]:hover) .nd-key[data-ring="1"],
.nightdial:has(.nd-key[data-ring="2"]:hover) .nd-ring[data-ring="2"],
.nightdial:has(.nd-ring[data-ring="2"]:hover) .nd-key[data-ring="2"]{opacity:1}
.nightdial .nd-key{cursor:default}

@media(prefers-reduced-motion:reduce){
  .nightdial .nd-run,.nightdial .nd-dead{animation:none;stroke-dashoffset:0}
  .nightdial:hover .nd-ring,.nightdial:hover .nd-key{opacity:1}
}

/* ---------- the reading column's own furniture ----------
   Everything here overrides a rule of the same weight in the read pages'
   <style> block, which loads after this file — so each selector carries a
   second class (.read-main) to win on specificity rather than on order. The
   modifier trap, again. */

/* A numbered run reads as a sequence, not as a list with numbers beside it.
   The disc is an outline at rest — filled, in any colour, a column of them
   down the left shouts over the thing it is numbering — and takes the acid
   only under the cursor, where it marks the step being read. */
.read-main .ar-steps li{padding-left:58px}
.read-main .ar-steps li::before{
  /* Centred against the item rather than pinned near its top, so a step that
     wraps to three lines keeps its numeral beside the middle of them. */
  top:50%;transform:translateY(-50%);
  width:34px;height:34px;border-radius:50%;
  background:var(--paper);color:var(--ink);
  box-shadow:inset 0 0 0 1.6px var(--ink);
  display:grid;place-items:center;
  font-size:11px;font-weight:600;letter-spacing:.04em;
  transition:background-color .18s ease}
.read-main .ar-steps li:hover::before{background:var(--acid)}
@media(prefers-reduced-motion:reduce){
  .read-main .ar-steps li::before{transition:none}
}

/* A bullet in a guide is a tip, so it gets a mark rather than a dot. A lilac
   disc with a tick through it: the lilac keeps it off the ink the bold
   lead-ins are already using, and the tick says "this is a thing to do"
   rather than "this is an item". Drawn inline because CSS cannot reach
   icons.json. */
.read-main .ar-ul{list-style:none;padding-left:30px}
.read-main .ar-ul li{position:relative}
.read-main .ar-ul li::before{
  content:"";position:absolute;left:-27px;top:.36em;width:15px;height:15px;
  background:no-repeat center/15px 15px
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='9' fill='%23cec5ff'/><path d='M8 12.2l2.6 2.6L16 9.4' fill='none' stroke='%23111110' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/></svg>")}

/* A check-marked list carries only its own blue tick — suppress the read
   layout's default circle-check bullet so the two don't double up. The read
   layout also indents .ar-ul 30px; the check list starts at the text margin
   instead, with the tick sitting where the paragraph text starts. */
.read-main .ar-ul--check li::before{display:none}
.read-main .ar-ul--check{padding-left:0}

/* A callout's label is a heading. Set as a mono kicker it named the box
   without ever making the case for reading it, which is the one job it has.

   Three classes deep on purpose. `.ar-call--warn .ar-call-l` in the read
   pages' own <style> block is also two classes and loads later, so a
   two-class selector here ties and loses — which is how these labels ended up
   at 62% ink. Nothing on this site sets a heading in a faded colour. */
.read-main .ar-call .ar-call-l{
  font-family:var(--sans);font-size:clamp(19px,1.8vw,23px);font-weight:700;
  letter-spacing:-.025em;line-height:1.12;text-transform:none;
  color:var(--ink);margin-bottom:12px}
.read-main .ar-call.ar-call--good .ar-call-l{color:#fff}

/* Same rule, everywhere else a label names something rather than describing
   it: the part marker and the kicker over a section heading. Size and weight
   carry the hierarchy; colour does not have to. */
.read-main .ar-viewlabel,.read-main .ar-sec-eyebrow{color:var(--ink)}

/* A closing line, at reading-plus size — the sentence the section was for. */
.read-main .ar-p--lead{
  font-size:clamp(19px,1.7vw,22px);line-height:1.45;color:var(--ink);margin-top:22px}

/* An aside the prose can run around, for a box the reader may take or leave.
   Headings clear it so a section never starts beside one. */
.read-main .ar-call--side{float:right;width:48%;margin:10px 0 22px 30px;clear:right}
.read-main .ar-sec,.read-main .ar-sec-eyebrow{clear:both}
@media(max-width:900px){
  .read-main .ar-call--side{float:none;width:auto;margin-left:0}
}

/* A figure whose explanation is the point: the number on the left, the
   sentence beside it at reading size instead of shrunk into a mono caption. */
.read-main .datastrip--wide{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
  gap:4px 36px;align-items:center}
.read-main .datastrip--wide .l{grid-column:1;grid-row:1;margin:0}
.read-main .datastrip--wide b{grid-column:1;grid-row:2;margin:6px 0 0}
.read-main .datastrip--wide .c{grid-column:2;grid-row:1/3;margin:0;
  font-family:var(--sans);font-size:clamp(16px,1.5vw,19px);line-height:1.42;
  letter-spacing:-.005em;text-transform:none;color:rgba(255,255,255,.94)}
@media(max-width:760px){
  .read-main .datastrip--wide{grid-template-columns:1fr}
  .read-main .datastrip--wide .c{grid-column:1;grid-row:3;margin-top:14px}
}

/* A callout and the figure that belongs to it, read as one block. */
.read-main .ar-call:has(+ .datastrip){
  border-bottom-left-radius:0;border-bottom-right-radius:0;margin-bottom:0}
.read-main .ar-call + .datastrip{
  margin-top:0;border-top-left-radius:0;border-top-right-radius:0}

/* ---------- folds that open smoothly ----------
   <details> has no height of its own to animate, so this leans on
   ::details-content and interpolate-size, which Chromium has. Where they are
   missing the fold still opens — just instantly, the way it did before.

   The easing is a soft overshoot rather than a linear slide: it settles
   rather than stopping, which is what makes it read as one movement instead
   of a panel appearing. Shared by every .acc on the site, so the Clash plan
   and CP Runs get it too; the +/− marker is left alone because it is the
   Atlas's established affordance. */
@supports (interpolate-size: allow-keywords){
  :root{interpolate-size:allow-keywords}
}
.acc::details-content{
  block-size:0;overflow:hidden;
  transition:block-size .42s cubic-bezier(.22,1,.36,1);
}
.acc[open]::details-content{block-size:auto}
.acc summary,.acc summary::before{transition:color .2s ease}
.acc summary:hover{color:var(--blue)}

/* ---------- a claims group that folds ----------
   Thirty-six ledger rows under six headings is a wall, and a reader consults
   a ledger rather than reading it. Each group folds instead, with its count
   on the summary so the shape of the evidence is legible while it is shut.
   The rows keep their own grid; only the run of them is indented to sit under
   the summary it belongs to. */
/* The heading needs air before the first fold, or the section rule and the
   fold's own top rule read as one double line. */
.ar-sec + .acc{margin-top:26px}
.acc > .ar-claims{margin:10px 0 18px 20px}
.acc .ar-claim{grid-template-columns:52px 92px minmax(0,1fr)}
.acc .ar-claim p{margin:0}
.acc-n{float:right;font-family:var(--mono);font-size:9px;font-weight:500;
  letter-spacing:.11em;text-transform:uppercase;color:var(--grey)}
@media(max-width:900px){.acc > .ar-claims{margin-left:0}}

/* A numeric range is one word. "10–30" broken across two lines reads as two
   numbers, and it also lets a column collapse narrower than its own content.
   Applied to every range the renderer finds, so no table has to ask. */
.nb{white-space:nowrap}

/* ---------- a callout with a plate beside it ----------
   The same callout, given a picture. The plate is a placeholder field until a
   drawing exists: the Atlas shows an empty field rather than a broken image,
   the same way a monster with no artwork does. */
.ar-call--art{display:grid;grid-template-columns:132px minmax(0,1fr);gap:22px;align-items:start}
/* Copy first, picture second — for a block whose point is the sentence and
   whose drawing is support rather than subject. */
.ar-call--art-right{grid-template-columns:minmax(0,1fr) clamp(180px,30%,300px)}
.ar-call--art-right .ar-call-body{order:0}
.ar-call--art-right .ar-call-plate{order:1;min-height:100%}
.ar-call--art .ar-call-plate{align-self:stretch;min-height:104px;border-radius:var(--r);
  background:rgba(17,17,16,.05)}
.ar-call--art .ar-call-body{min-width:0}
@media(max-width:760px){
  .ar-call--art{grid-template-columns:1fr}
  .ar-call--art .ar-call-plate{min-height:74px}
}

/* Who wrote it and how long it takes, at the head of the piece.
   It was set in the same grey as the kicker beside it and vanished
   into the rule — it is the thing a reader decides on, so it carries
   the ink and the weight. */
.ar-topline .ar-by{color:var(--ink);font-size:11px;letter-spacing:.11em}
.readcard .m + h3{margin-top:6px}
.readcard .m:first-child{color:var(--ink);font-weight:500}

/* The drawn mark on a mega-nav row. Sized to the cap height of the
   label beside it, so it reads as part of the line and not as an
   illustration hung off the front of it. */
.mega-icon{margin-right:13px;vertical-align:-2px;flex:0 0 auto;opacity:.8}
.mega a:hover .mega-icon{opacity:1}
/* the caption under a marked row starts where its title starts */
.mega a:has(.mega-icon) span{padding-left:28px}

/* Community Questions — the list, the question, and the four ways in. */
/* Same shape as a long read: the question stops at the measure and
   the width past it goes to the lanes. */
.cols--q{grid-template-columns:420px minmax(0,var(--read-max)) minmax(268px,1fr)}
/* The cell carries the rule for the whole height of the column; the
   pane inside it follows the scroll. */
.side--q{position:static;align-self:stretch;max-height:none;overflow:visible;
  border-left:1px solid var(--rule);padding:0}
.side--q > .sticky-in{position:sticky;top:var(--top-h);max-height:var(--view-h);
  overflow-y:auto;overscroll-behavior:contain;padding:26px 24px}
.side--q .rl{margin:0 0 9px;font-family:var(--mono);font-size:9px;font-weight:500;
  letter-spacing:.12em;text-transform:uppercase;color:var(--grey)}
.qways{display:grid;gap:8px;margin:16px 0}
.qways a{display:block;border:1px solid var(--rule);border-radius:var(--r);
  padding:11px 13px;background:var(--paper);
  transition:border-color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease)}
.qways a:hover{border-color:var(--ink);background:rgba(17,17,16,.03)}
.qways b{display:block;font-size:14.5px;font-weight:600;letter-spacing:-.01em}
.qways span{display:block;margin-top:3px;font-size:12.5px;line-height:1.4;color:var(--grey)}
@media (max-width:1180px){
  /* No room for a third column, but the four lanes are the point of
     the page — they drop under the question rather than disappearing,
     and the border moves to the top edge where the seam now is. */
  .cols--q{grid-template-columns:360px minmax(0,1fr)}
  .side--q{grid-column:2;border-left:0;border-top:1px solid var(--rule)}
  .side--q > .sticky-in{position:static;max-height:none}
  .qways{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:900px){
  .cols--q{grid-template-columns:minmax(0,1fr)}
  .side--q{grid-column:1}
}
@media (max-width:560px){
  .qways{grid-template-columns:minmax(0,1fr)}
}

/* The last row of a list has no rule under it — the heading that
   starts the next section already draws that line, and two of them
   stacked reads as a gap in the page. */
.row:last-child,.glrow:last-child,.qrow:last-child,
.srcmini a:last-child,.evlist a:last-child{border-bottom:0}

/* ---------- a door, not a page ----------------------------------
   The gate the clan articles use, lifted out of one page so the
   kingdom gate can wear it too. Centred on a bare field: nothing to
   read but what is behind the door and how to open it. */
.gate{min-height:calc(100dvh - var(--nav-h) - var(--foot-h));
  background:var(--bone);display:flex;align-items:center;justify-content:center;
  padding:24px clamp(16px,3vw,40px)}
.gate-box{max-width:46ch;text-align:left}
.gate-form{display:flex;gap:10px;margin-top:20px;flex-wrap:wrap}
.gate-form input{font:inherit;font-size:16px;border:1px solid var(--ink);
  border-radius:var(--r-pill);padding:12px 18px;background:var(--paper);
  color:var(--ink);min-width:200px}
.gate-form input:focus{outline:0;box-shadow:0 0 0 3px rgba(27,35,255,.18)}
.gate-error{margin:20px 0 0;background:var(--pink);color:var(--ink);
  border-radius:var(--r);padding:11px 14px;font-size:14.5px;line-height:1.4}
.gate-box a{border-bottom:1px solid rgba(17,17,16,.3)}
.gate-box a:hover{color:var(--blue);border-color:var(--blue)}

/* ---------- the mark draws itself under the cursor ---------------
   Hovering the wordmark hands the pointer over to the Atlas's own
   hand-drawn mark, which scribbles itself in. 273 traced pen marks,
   revealed in the order they were drawn — there are no strokes to
   dash, so the drawing is the reveal.

   cursor:url() cannot animate and is capped at about 128px by most
   browsers, so the real pointer is hidden and this follows it. */
/* Anywhere the mark takes over the pointer. The wordmark's block —
   not the whole bar: the nav links keep their pointer, because a link
   that does not look clickable is a worse trade than a smaller zone. */
.nav .mark:hover,.scribble-zone:hover,.scribble-zone:hover *{cursor:none}
/* The wordmark answers a little past its own letters, but only where the bar
   has room to spare. Below this the links are already tightening and the mark
   must not reach into them. */
@media(min-width:1240px){.nav .mark{padding-right:96px}}
/* The quote is two elements, the line and who said it; they are one
   zone so the pointer does not flicker crossing between them. */
/* The zone is the corner, not the sentence. It was an inline-block sitting
   exactly around the quote, so two thirds of the block a reader would call
   "the quote" did nothing — the eyebrow above it, the column either side of
   it, and the page margin to its left. The padding grows the hit area; the
   matching negative margin keeps the type where it was. */
.scribble-zone{display:block;max-width:100%}
/* The label reaches across its third of the strip, bounded so it never grows
   into the date sitting in the middle of it. */
.strip .scribble-zone{display:inline-block;margin:-12px 0 -13px -40px;
  padding:12px clamp(40px,26vw,450px) 13px 40px}
/* And the quote meets the strip rather than starting twelve pixels under it,
   so the corner is one region rather than two with a seam. */
.deskgrid > div > .scribble-zone{margin:-30px -20px 0 -44px;padding:30px 20px 14px 44px}
/* Said here rather than in the phone block, which is declared earlier and
   would lose on source order. A phone has no hover, so these are a mouse
   affordance charging rent on a touch screen: the label's padding pushed the
   strip into three rows, and the quote's negative margin — sized for a 44px
   desktop gutter against a 16px phone one — hung it 28px off the left edge. */
@media (max-width:900px){
  .strip .scribble-zone{margin:0;padding:0}
  .deskgrid > div > .scribble-zone{margin:0;padding:0}
}
.scribble{position:fixed;left:0;top:0;z-index:200;width:120px;
  pointer-events:none;opacity:0;
  /* Held near the top, where a hand would hold a pen — so the tilt
     swings the body of the drawing rather than pivoting it about its
     own middle. */
  transform-origin:34% 18%;
  transform:translate3d(-9999px,-9999px,0);
  transition:opacity .14s var(--ease)}
.scribble.on{opacity:1}
/* No shadow. It is ink on the page, not a sticker above it. */
.scribble svg{display:block;width:100%;height:auto;overflow:visible}
.scribble path{opacity:0}
.scribble.draw path{opacity:1;transition:opacity .09s linear}
@media (prefers-reduced-motion:reduce){
  /* No scribble, just the mark. */
  .scribble.draw path{transition:none}
  .scribble path{transition-delay:0s!important}
}

/* ---------- headlines break where a person would break them ------
   561px on the first line and 136 on the second is not two lines, it
   is one line with a word fallen off the end. text-wrap:balance makes
   the browser even them up, which is the thing the eye was asking for
   and what the &nbsp; binding could only approximate one case at a
   time. It applies to headings only — balancing body copy costs more
   than it returns, and browsers cap it at a few lines anyway. */
h1,h2,h3,h4,
.h1,.h2,.lede,.ar-h2,.ar-h3,.eyebrow,
.readcard h3,.regtile h3,.who-card h3,.b-tile h3,.b-hero h3,
.krule h3,.kfind h3,.cacard h3,.qrow h4{text-wrap:balance}
/* The standfirst under a headline reads better ragged than balanced —
   it is a paragraph, not a title. */
.ar-lede,.b-hero .lede{text-wrap:pretty}

/* ---------- the Atlas's own select ----------------------------------------
   A native <select> can be styled shut and never open — the menu belongs to
   the OS. This is the same control drawn in the Atlas's own terms: mono caps,
   an ink edge, and the acid marking what is chosen. The real select is still
   underneath, so the page works with no JavaScript at all. */
.asel{position:relative;display:inline-flex;max-width:100%;min-width:0}
.asel > select{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none;
  clip:rect(0 0 0 0);overflow:hidden}
.asel-btn{display:inline-flex;align-items:center;gap:10px;max-width:100%;min-width:0;
  font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink);background:var(--paper);
  border:1px solid var(--rule);border-radius:var(--r-pill);
  padding:10px 14px;line-height:1;cursor:pointer;white-space:nowrap}
.asel-btn:hover{border-color:var(--ink)}
.asel-btn:focus-visible{outline:none;border-color:var(--ink);
  box-shadow:0 0 0 3px rgba(17,17,16,.12)}
.asel--set .asel-btn{background:var(--ink);border-color:var(--ink);color:var(--paper)}
/* The chosen option can be longer than the control — "Epic & event (15)" in a
   third of a phone's width — so the label truncates and the chevron stays. */
.asel-v{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.asel-c{width:6px;height:6px;flex:none;
  border-right:1.4px solid currentColor;border-bottom:1.4px solid currentColor;
  transform:translateY(-2px) rotate(45deg);transition:transform .18s ease}
.asel.open .asel-c{transform:translateY(1px) rotate(-135deg)}

/* display:flex below would beat the browser's own [hidden] rule, so the menu
   would never actually close. Any element that sets display and is toggled
   with `hidden` needs this. */
.asel-menu[hidden]{display:none}
/* Above the rails, the mega nav, and the modals it opens inside — the War
   parties pop-up is z-80, and a menu at 70 fell behind it. It is portalled to
   the body while open, so this z-index alone decides what covers it. */
.asel-menu{position:absolute;z-index:90;top:calc(100% + 6px);left:0;min-width:100%;
  max-width:calc(100vw - 24px);
  max-height:min(320px,60vh);overflow-y:auto;overscroll-behavior:contain;
  background:var(--paper);border:1.4px solid var(--ink);border-radius:var(--r);
  box-shadow:0 18px 34px -22px rgba(0,0,0,.55);padding:5px;
  display:flex;flex-direction:column;gap:1px;
  animation:asel-drop .16s cubic-bezier(.2,.75,.2,1) both}
.asel--up .asel-menu{top:auto;bottom:calc(100% + 6px);transform-origin:bottom left}
/* A menu wider than its button runs off the screen when the button is near the
   right edge. Hang it off the right instead. */
.asel--right .asel-menu{left:auto;right:0}
@keyframes asel-drop{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
.asel-o{display:block;width:100%;text-align:left;
  font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-2);background:none;border:0;
  border-radius:calc(var(--r) - 4px);padding:9px 11px;line-height:1.2;
  cursor:pointer;white-space:nowrap}
.asel-o:hover{background:var(--bone);color:var(--ink)}
.asel-o:focus-visible{outline:none;background:var(--bone);color:var(--ink);
  box-shadow:inset 0 0 0 1.4px var(--ink)}
.asel-o.on{background:var(--acid);color:var(--ink)}
@media(prefers-reduced-motion:reduce){
  .asel-menu{animation:none}
  .asel-c{transition:none}
}

/* ---------- the index filter bar ------------------------------------------
   Shared by the monster index and the gem index. It lived in the monster
   page's generated CSS until the gems needed it too, at which point one
   page had the chrome and the other did not. */
/* An index past the point where scrolling is a way of finding
   something. Search on the left, the narrowing controls on the right. */
.monfilter{display:flex;flex-wrap:wrap;gap:12px 18px;align-items:center;
  padding-bottom:16px;margin-bottom:2px;border-bottom:1px solid var(--rule)}
.mf-q{flex:1 1 200px;min-width:0;font:inherit;font-size:15px;color:var(--ink);
  background:var(--paper);border:1px solid var(--rule);border-radius:var(--r-pill);
  padding:10px 16px}
.mf-q:focus{outline:none;border-color:var(--ink)}
.mf-q::placeholder{color:var(--grey)}
.mf-by{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-left:auto}
.mf-label{font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.13em;
  text-transform:uppercase;color:var(--grey);white-space:nowrap}
/* Before JavaScript upgrades it this is a plain select, styled as far as a
   select can be. Once .asel wraps it (see proto.css) the real control is the
   Atlas's own, and this only has to not look broken in the meantime. */
.mf-sel{position:relative;display:inline-flex}
.mf-sel select{appearance:none;-webkit-appearance:none;
  font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink);background:var(--paper);
  border:1px solid var(--rule);border-radius:var(--r-pill);
  padding:10px 14px;line-height:1;cursor:pointer}
.asel .mf-sel,.mf-sel:has(> .asel){border:0;padding:0}
/* The count is a result of the controls above it, not another control — it
   needs air between them or it reads as a third thing on the same row. */
.mf-count{flex:1 1 100%;margin:8px 0 0;font-family:var(--mono);font-size:9px;
  font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--grey)}
/* .tile sets display:flex, which beats the browser's own [hidden] rule — so a
   card marked hidden stays on screen unless this says otherwise. */
.monfam[hidden],.moncard[hidden]{display:none}
.mf-none{margin:26px 0 0;font-size:16px;color:var(--ink-2)}
/* Filtering rearranges the grid, so the cards move rather than blink. Each
   one is measured before and after, then played from where it was to where
   it landed — a FLIP, so the transform runs on the compositor and ninety
   cards still move at frame rate. Cards leaving fade in place; cards
   arriving fade up. */
.moncard,.gemrow{transition:opacity .22s ease}
.moncard.mf-out,.gemrow.mf-out{opacity:0;pointer-events:none}
.moncard.mf-in,.gemrow.mf-in{animation:mf-rise .3s cubic-bezier(.2,.75,.2,1) both}
@keyframes mf-rise{from{opacity:0;transform:translateY(10px) scale(.985)}
  to{opacity:1;transform:none}}
.monfam,.gemfam{transition:opacity .22s ease}
@media(prefers-reduced-motion:reduce){
  .moncard,.gemrow,.monfam,.gemfam{transition:none}
  .moncard.mf-in,.gemrow.mf-in{animation:none}
}

/* ---------- the stack builder --------------------------------------------
   The controls live in the sticky rail and the stack fills the page, because
   the stack is the thing you came to look at. The old layout spent 900px on
   a header and put the first real number 1,874px down. */
.sb-rail{gap:10px;text-transform:none;letter-spacing:0;font-family:var(--sans);
  font-size:15px;color:var(--ink)}
.sb-rail > b{display:flex;align-items:center;font-family:var(--mono);font-size:11.5px;font-weight:500;letter-spacing:.13em;
  text-transform:uppercase;color:var(--grey)}
.sb-sec{margin-top:16px;padding-top:14px;border-top:1px solid var(--rule)}

.sb-f{display:flex;flex-direction:column;gap:6px}
.sb-k{font-family:var(--mono);font-size:11px;font-weight:500;letter-spacing:.12em;
  text-transform:uppercase;color:var(--grey)}
.sb-i{font:inherit;font-size:15px;font-weight:600;color:var(--ink);
  background:var(--paper);border:1px solid var(--rule);border-radius:var(--r-pill);
  padding:8px 14px;width:100%}
.sb-i:focus{outline:none;border-color:var(--ink)}
.sb-f .mf-sel,.sb-f .asel{width:100%}
.sb-f .asel-btn{width:100%;justify-content:space-between}

/* One row per troop type: on/off, and how much of its ladder to use. */
/* The row was a flex row until a type could open into its ladder. The
   ladder is a block below the header, not a sibling beside it — left as a
   flex item it sat next to the name and ran out of the rail. */
/* The Barracks groups the army before it lists it, and a flat list of seven
   hid that Engineer and Catapult are one category and Swordsman another. */
.sb-cat{display:block;margin:14px 0 4px;font-family:var(--mono);font-size:9.5px;
  font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--grey)}
.sb-cat:first-child{margin-top:6px}
.sb-type{display:block;padding:5px 0;opacity:.5;transition:opacity .15s ease}
.sb-type.on{opacity:1}
.sb-chk{display:flex;align-items:center;gap:8px;cursor:pointer;min-width:0}
.sb-chk input{width:14px;height:14px;accent-color:var(--ink);flex:none}
.sb-tn{font-size:15px;font-weight:600;letter-spacing:-.012em;white-space:nowrap}
.sb-dot{width:8px;height:8px;border-radius:50%;flex:none;display:inline-block;
  background:var(--rule);vertical-align:1px;margin-right:7px}
.cls-melee{background:#1b23ff}.cls-ranged{background:#e6ff2e}
.cls-mounted{background:#ff4a17}.cls-flying{background:#cec5ff}
.cls-siege{background:#111110}
.sb-th{display:flex;align-items:center;justify-content:space-between;gap:8px}
.sb-more{display:inline-flex;align-items:center;gap:6px;font-family:var(--mono);
  font-size:10.5px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;
  color:var(--grey);background:none;border:0;padding:2px 0;cursor:pointer;white-space:nowrap}
.sb-more:hover{color:var(--ink)}
.sb-more{min-width:0;overflow:hidden;text-overflow:ellipsis}
.sb-tn{overflow:hidden;text-overflow:ellipsis}
.sb-more .asel-c{width:5px;height:5px;border-width:1.2px}
.sb-more[aria-expanded="true"]{color:var(--ink)}
.sb-more[aria-expanded="true"] .asel-c{transform:translateY(1px) rotate(-135deg)}

/* The ladder: which tiers you use, and how many of each you actually own. */
.sb-tiers{margin:8px 0 12px;padding:10px 10px 4px;background:var(--bone);
  border-radius:var(--r);min-width:0}
.sb-tr{display:grid;grid-template-columns:16px 1fr minmax(0,62px);gap:8px;
  align-items:center;padding:3px 0;cursor:pointer}
.sb-tr--h{cursor:default;padding-bottom:5px}
.sb-tr--h span{font-family:var(--mono);font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--grey)}
.sb-tr--h span:last-child{text-align:right}
.sb-tr input[type=checkbox]{width:13px;height:13px;accent-color:var(--ink);margin:0}
.sb-trt{font-size:14px;font-weight:600}
.sb-tr.off .sb-trt{color:var(--grey);text-decoration:line-through}
.sb-have{font:inherit;font-size:14px;font-weight:600;text-align:right;width:100%;
  background:var(--paper);border:1px solid var(--rule);border-radius:var(--r-pill);
  padding:4px 8px}
.sb-have:focus{outline:none;border-color:var(--ink)}
.sb-hint{margin:8px 0 6px;font-size:12.5px;line-height:1.45;color:var(--ink-2)}

/* A layer you have run out of, so the number is not a target but a ceiling. */
.sb-cap{display:block;font-family:var(--mono);font-size:9.5px;font-style:normal;
  letter-spacing:.1em;text-transform:uppercase;color:var(--flare);margin-top:2px}

/* Title on the left, count on the right — the same shape as a troop row, and
   the only one that survives the count not fitting on the title's line. */
.sb-btog{display:flex;width:100%;align-items:center;justify-content:space-between;
  gap:10px;text-align:left;font:inherit;
  font-family:var(--mono);font-size:11.5px;font-weight:500;letter-spacing:.13em;
  text-transform:uppercase;color:var(--grey);background:none;border:0;padding:0;cursor:pointer}
.sb-btog[aria-expanded="true"]{color:var(--ink)}
.sb-btl{display:inline-flex;align-items:center;min-width:0}
.sb-btr{display:inline-flex;align-items:center;gap:8px;flex:none}
.sb-sum{white-space:nowrap}
.sb-btog[aria-expanded="true"] .asel-c{transform:translateY(1px) rotate(-135deg)}
.sb-bgrid{display:flex;flex-direction:column;gap:4px;margin-top:4px}
.sb-brow{display:grid;grid-template-columns:1fr 52px 52px;gap:6px;align-items:center}
.sb-brow--h span{font-family:var(--mono);font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--grey);text-align:center}
.sb-bk{font-size:14px;font-weight:600;text-transform:capitalize}
.sb-bi{font:inherit;font-size:14px;font-weight:600;width:100%;text-align:right;
  background:var(--paper);border:1px solid var(--rule);border-radius:var(--r-pill);padding:5px 9px}
.sb-bi:focus{outline:none;border-color:var(--ink)}

/* The answer, at the top, always. */
.sb-strip{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));
  gap:1px;background:var(--rule);
  border-top:1.4px solid var(--ink);border-bottom:1.4px solid var(--ink)}
.sb-s{background:var(--paper);padding:16px clamp(14px,2vw,22px)}
.sb-s .num{margin:0;font-size:clamp(20px,2.4vw,27px);line-height:1}
.sb-s .mono-s{margin:6px 0 0}
.sb-s--bad .num{color:var(--flare)}

.sb-t{margin-top:0}
.sb-t th:nth-child(n+3),.sb-t td:nth-child(n+3){text-align:right}
/* This column is the order the enemy works down the list, and it shipped with
   a blank header and 9px grey numerals — the one piece of information the
   table exists to convey, set as though it were a footnote. */
/* The shaded rows carry a 2px inset bar on this cell, and the cell had no
   left padding — so the numeral was printed underneath its own marker. */
.sb-t .sb-ixh,.sb-t .sb-ix{width:52px;text-align:left;padding-left:11px}
.sb-t .sb-ix{font-family:var(--mono);font-size:12px;font-weight:500;color:var(--ink)}
.sb-t tr:not(.sb-hit) .sb-ix{color:var(--grey)}
.sb-t .sb-n b{font-size:17px;letter-spacing:-.02em}
/* T1 and T5 are different units with different jobs, so the tier is part of
   the layer's name — not a grey superscript hanging off the end of it. */
.sb-tt{display:inline-block;margin-left:8px;padding:3px 8px;vertical-align:1px;
  font-family:var(--mono);font-size:11.5px;font-weight:500;font-style:normal;
  letter-spacing:.05em;color:var(--ink);background:var(--rule);border-radius:4px}

/* The shaded band is gone. Each blow gets a heading of its own, which says
   what the colour could only imply — and the last one, the layers that swing
   without being touched, is the reason the page exists. */
.sb-t tr.sb-band td{padding:20px 0 7px;border-bottom:0;text-align:left}
.sb-t tr.sb-band b{display:inline-block;font-family:var(--mono);font-size:10px;
  font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--ink)}
.sb-t tr.sb-band i{display:inline-block;margin-left:10px;font-style:normal;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--grey)}
.sb-t tr.sb-band--free td{padding-top:26px;border-top:1.4px solid var(--ink)}
.sb-t tr.sb-band--free b{color:var(--blue)}
.sb-t tr:first-child.sb-band td{padding-top:6px}
/* One hard edge, still — it marks the layer the heading is about. */
.sb-t tr.sb-hit td:first-child{box-shadow:inset 2px 0 0 var(--ink)}
.sb-t tr.sb-prot td:first-child{box-shadow:inset 2px 0 0 var(--blue)}
.sb-t tr.sb-hit.sb-prot td:first-child{box-shadow:inset 2px 0 0 var(--blue)}

/* The setup is the point: say it is kept, so nobody retypes it. */
.sb-keep{margin-top:18px;padding-top:14px;border-top:1px solid var(--rule)}
.sb-kept{margin:0 0 10px;font-size:13px;line-height:1.5;color:var(--ink-2)}
.sb-kept.is-said{color:var(--ink);font-weight:600}
/* The two setup actions, at the head of the page. Set apart from the help
   buttons beside them by a rule, because one pair explains the tool and the
   other changes what you have built with it. */
.sb-acts{display:flex;flex-wrap:wrap;align-items:center;gap:7px;
  padding-left:14px;margin-left:7px;border-left:1px solid rgba(17,17,16,.2)}
.sb-acts .btn{font-size:9px;padding:9px 15px}
.sb-acts .btn.is-armed{color:var(--paper);background:var(--flare);border-color:var(--flare)}
.sb-acts .btn.is-armed:hover{background:var(--ink);border-color:var(--ink)}
.sb-said{font-family:var(--mono);font-style:normal;font-size:9px;font-weight:500;
  letter-spacing:.1em;text-transform:uppercase;color:rgba(17,17,16,.6)}
.sb-said.is-said{color:var(--ink)}
@media(max-width:760px){
  .sb-acts{padding-left:0;margin-left:0;border-left:0;width:100%}
}
.sb-keepb{display:flex;flex-direction:column;gap:6px;align-items:flex-start}
.sb-keepb .btn{font-size:10px;padding:8px 13px}
/* Armed: one more click and the setup is gone. Says so, in the one colour
   this page reserves for something you cannot take back. */
.sb-keepb .btn.is-armed{color:var(--paper);background:var(--flare);border-color:var(--flare)}
.sb-keepb .btn.is-armed:hover{background:var(--ink);border-color:var(--ink)}

.sb-t .sb-ix i{font-style:normal;color:var(--grey);font-weight:400}
/* A warning is a left edge and a line of text, not a filled band. */
.sb-note{padding:12px 0 12px 14px;background:none;border-bottom:1px solid var(--rule);
  border-left:2px solid var(--flare)}
/* Not a warning — nothing is wrong. An explanation, so an unspent cap does
   not read as a bug. */
.sb-note--note{border-left-color:var(--blue)}
.sb-note--tie{background:var(--bone);border:0;border-left:2px solid var(--rule);
  border-radius:0;margin-top:16px;padding:12px 14px}
.sb-note p{margin:0;font-size:14.5px;line-height:1.5}
/* ---- the empty page ------------------------------------------------------
   Not an error and not an apology: the only screen with room to say what the
   three steps are, shown to the one reader who needs them. */
.sb-empty{padding:26px 0;font-size:15px;color:var(--ink-2)}
.sb-start{padding:34px clamp(16px,2.2vw,26px) 32px;background:var(--bone);
  border-radius:var(--r);max-width:62ch}
.sb-startk{margin:0 0 12px;font-family:var(--mono);font-size:11px;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;color:var(--grey)}
.sb-starth{margin:0 0 22px;font-size:clamp(21px,2.2vw,26px);line-height:1.24;
  letter-spacing:-.026em;font-weight:800;text-wrap:balance}
.sb-startl{margin:0;padding:0;list-style:none;counter-reset:st}
.sb-startl li{position:relative;padding-left:34px;margin-bottom:13px;font-size:15px;
  line-height:1.5;color:var(--ink-2);max-width:56ch}
.sb-startl li b{color:var(--ink);font-weight:700}
.sb-startl li::before{counter-increment:st;content:counter(st);position:absolute;
  left:0;top:1px;width:21px;height:21px;border-radius:50%;background:var(--ink);
  color:var(--paper);font-family:var(--mono);font-size:10px;font-weight:500;
  display:grid;place-items:center}
.sb-startf{margin:24px 0 0;padding-top:20px;border-top:1px solid var(--rule);
  font-size:14px;color:var(--ink-2)}
.sb-startb{font:inherit;font-size:14px;color:var(--blue);background:none;border:0;
  padding:0;cursor:pointer;text-decoration:underline;text-underline-offset:2px}
.sb-startb:hover{color:var(--ink)}
.sb-foot{margin:18px 0 0;font-size:13.5px;line-height:1.55;color:var(--grey);max-width:70ch}
.sb-foot br{content:"";display:block;height:9px}

@media(max-width:900px){
  .sb-rail{position:static;max-height:none}
  .sb-range .mf-sel select,.sb-range .asel-btn{font-size:9px}
}

/* ---- the target rail ---- */
.sb-side{gap:10px;text-transform:none;letter-spacing:0;font-family:var(--sans);
  font-size:15px;color:var(--ink);display:flex;flex-direction:column}
.sb-side > b{display:flex;align-items:center;font-family:var(--mono);font-size:11.5px;font-weight:500;letter-spacing:.13em;
  text-transform:uppercase;color:var(--grey)}
.sb-sec2{margin-top:18px;padding-top:14px;border-top:1px solid var(--rule)}
.sb-tsel{width:100%}
.sb-tsel select,.sb-tsel .asel,.sb-tsel .asel-btn{width:100%}
.sb-tsel .asel-btn{justify-content:space-between}
.sb-shint{margin:4px 0 0;font-size:13px;line-height:1.5;color:var(--ink-2)}

.sb-tcard{margin-top:6px;padding:14px;background:var(--bone);border-radius:var(--r)}
.sb-tn2{margin:0;font-size:20px;font-weight:800;letter-spacing:-.028em;line-height:1.1}
.sb-tc{margin:4px 0 0;font-family:var(--mono);font-size:10px;font-weight:500;
  letter-spacing:.11em;text-transform:uppercase;color:var(--grey)}
.sb-tstats{margin:12px 0 0;display:flex;flex-direction:column;gap:7px}
.sb-tstats div{display:flex;justify-content:space-between;gap:12px;align-items:baseline}
.sb-tstats dt{font-family:var(--mono);font-size:11px;font-weight:500;letter-spacing:.11em;
  text-transform:uppercase;color:var(--grey)}
.sb-tstats dd{margin:0;font-size:15.5px;font-weight:600;letter-spacing:-.012em}

.sb-vs{display:flex;flex-direction:column;gap:1px;margin-top:4px}
.sb-vsr{display:grid;grid-template-columns:1fr auto;gap:6px 10px;align-items:baseline;
  padding:8px 10px;background:var(--paper);border:1px solid var(--rule);border-radius:var(--r)}
.sb-vsr span{font-size:14px}
.sb-vsr b{font-size:15px;font-weight:700}
/* One accent, and only when your stack is actually walking into it. */
.sb-vsr.hot{border-color:var(--flare)}
.sb-vsr.hot b{color:var(--flare)}
.sb-vsr i{grid-column:1 / -1;font-style:normal;font-family:var(--mono);font-size:10px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--grey)}
.sb-warn2{margin:12px 0 0;padding:11px 13px;font-size:14px;line-height:1.5;
  background:var(--bone);border-left:2px solid var(--flare);color:var(--ink-2)}
.sb-warn2 b{color:var(--ink)}
.sb-tlink{margin-top:14px;align-self:flex-start;font-size:10px;padding:8px 13px}

/* ---- first run ----------------------------------------------------------
   The setup was the barrier: a dozen decisions before the page said anything
   back. One question at a time, in the order they depend on each other, and
   skippable throughout — the defaults behind it are a real stack. */
.sb-onboarding .cols--3 > .rail-l,
.sb-onboarding .cols--3 > .main,
.sb-onboarding .cols--3 > .rail-r{filter:blur(2px);opacity:.35;pointer-events:none}
.ob-wrap{position:fixed;inset:var(--top-h) 0 0;z-index:70;display:grid;place-items:start center;
  padding:clamp(16px,5vh,60px) 20px;overflow-y:auto;background:rgba(239,238,233,.86)}
.ob-card{width:min(560px,100%);background:var(--paper);border:1.4px solid var(--ink);
  border-radius:var(--r);padding:clamp(20px,3vw,30px)}
.ob-top{display:flex;align-items:center;justify-content:space-between;gap:16px}
.ob-step{font-family:var(--mono);font-size:8.5px;font-weight:500;letter-spacing:.13em;
  text-transform:uppercase;color:var(--grey)}
.ob-skip{font-family:var(--mono);font-size:8.5px;font-weight:500;letter-spacing:.11em;
  text-transform:uppercase;color:var(--grey);background:none;border:0;padding:0;cursor:pointer}
.ob-skip:hover{color:var(--ink)}
.ob-h{margin:16px 0 0;font-size:clamp(22px,2.6vw,29px);font-weight:800;letter-spacing:-.03em;
  line-height:1.1}
.ob-why{margin:9px 0 0;font-size:14.5px;line-height:1.55;color:var(--ink-2);max-width:54ch}
.ob-body{margin-top:20px}
.sb-big{font-size:26px !important;font-weight:800;letter-spacing:-.03em;padding:12px 18px !important}

.ob-types,.ob-sq{display:flex;flex-wrap:wrap;gap:7px}
.ob-t{display:inline-flex;align-items:center;gap:8px;cursor:pointer;
  padding:9px 13px;border:1px solid var(--rule);border-radius:var(--r-pill);
  font-size:14px;font-weight:600;background:var(--paper)}
.ob-t.on{border-color:var(--ink);background:var(--bone)}
.ob-t input{width:14px;height:14px;accent-color:var(--ink);margin:0}
.ob-tgt{display:block;margin-top:12px}
.ob-tgt select,.ob-tgt .asel,.ob-tgt .asel-btn{width:100%}
.ob-tgt .asel-btn{justify-content:space-between}

.ob-counts{display:flex;flex-direction:column;gap:14px;max-height:46vh;overflow-y:auto}
.ob-cn{margin:0 0 7px;font-size:14px;font-weight:700}
.ob-cr{display:flex;flex-wrap:wrap;gap:6px}
.ob-cr label{display:inline-flex;align-items:center;gap:5px}
.ob-cr i{font-family:var(--mono);font-size:8px;font-style:normal;letter-spacing:.09em;
  color:var(--grey);width:16px}
.ob-cr .sb-have{width:62px}

.ob-nav{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:24px}
.ob-dots{display:flex;gap:5px;justify-content:center;margin-top:18px}
.ob-dots i{width:5px;height:5px;border-radius:50%;background:var(--rule)}
.ob-dots i.on{background:var(--ink)}
.ob-dots i.done{background:var(--ink-2)}

/* Three columns are three steps, and saying so costs one numeral each. */
.sb-num{display:inline-flex;align-items:center;justify-content:center;
  width:18px;height:18px;margin-right:9px;border-radius:50%;flex:none;
  background:var(--ink);color:var(--paper);font-style:normal;
  font-size:10px;letter-spacing:0;line-height:1;
  /* The digit has no descender, so centring its BOX leaves the ink sitting
     high in the disc. BureauMono's ascent and descent are 0.9em and 0.3em,
     which puts the ink centre 0.045em above the box centre; this puts it
     back. Stated in em so it survives the next size change. */
  padding-top:0.09em}

/* The section label. It was an anonymous flex item, which is why it could
   only be nudged rather than aligned — there was nothing to select. Same
   correction as the numeral, for the same reason: uppercase with no
   descenders sits high when its box is centred. */
.sb-lbl{display:block;line-height:1;padding-top:0.06em}
.sb-lede{margin:8px 0 0;font-size:15px;line-height:1.5;color:var(--ink-2);max-width:62ch}

/* What the table is telling you, in words, before the table. */
/* This is the answer to the whole page, and it was set at the same weight as
   a caption. It gets the room and the size. */
/* Its own block with air under it — butted straight against the stats row the
   two read as one slab and the summary stopped being a summary. */
.sb-march{padding:28px clamp(16px,2.2vw,26px) 28px;background:var(--bone);
  border-radius:var(--r);margin-bottom:26px}
.sb-mk{display:flex;align-items:center;gap:9px;
  margin:0 0 14px;padding-bottom:12px;border-bottom:1px solid var(--rule);
  font-family:var(--mono);font-size:11px;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;color:var(--grey)}
/* The headline. Everything else in the block folds away behind it. */
.sb-ml{margin:0;font-size:clamp(22px,2.5vw,29px);line-height:1.22;
  letter-spacing:-.028em;color:var(--ink);max-width:34ch;text-wrap:balance}
.sb-ml b{color:var(--ink);font-weight:800}

/* The reasoning. It was set at 23px against a 29px headline, which is close
   enough that the eye reads four paragraphs of equal weight and gives up.
   Two sizes down, and behind a toggle. */
.sb-mrest{margin-top:16px;padding-top:16px;border-top:1px solid var(--rule)}
.sb-mrest[hidden]{display:none}
.sb-ml2{margin:0 0 10px;font-size:15px;line-height:1.55;color:var(--ink-2);
  max-width:62ch;text-wrap:pretty}
.sb-ml2:last-child{margin-bottom:0}
.sb-ml2 b{color:var(--ink);font-weight:700}
.sb-mtog{display:inline-flex;align-items:center;gap:8px;margin-top:16px;
  font-family:var(--mono);font-size:9.5px;font-weight:500;letter-spacing:.12em;
  text-transform:uppercase;color:var(--grey);background:none;
  border:1px solid var(--rule);border-radius:var(--r-pill);padding:8px 14px;cursor:pointer}
.sb-mtog:hover{color:var(--ink);border-color:var(--ink)}
.sb-mtog[aria-expanded="true"]{color:var(--ink)}
.sb-mtog[aria-expanded="true"] .asel-c{transform:translateY(1px) rotate(-135deg)}
.sb-ml:last-of-type{margin-bottom:0}
/* The two ways in belong at the top of the page, not buried under the answer
   — somebody who does not know what they are looking at never scrolls to the
   thing that would tell them. They survive the header collapsing, because
   that is exactly when a lost reader goes looking for them. */
.sb-head{display:flex;align-items:flex-end;justify-content:space-between;gap:24px}
.sb-headt{min-width:0}
.sb-hows{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;
  gap:12px;flex:none;padding-bottom:3px}
.sb-hows .btn{font-size:9px;padding:9px 15px}
.pagehead.is-stuck .sb-hows{padding-bottom:0}
@media(max-width:820px){
  .sb-head{flex-direction:column;gap:14px}
  .sb-hows{justify-content:flex-start}
}
.sb-how{font-family:var(--mono);font-size:8.5px;font-weight:500;
  letter-spacing:.12em;text-transform:uppercase;color:var(--ink);background:none;
  border:0;border-bottom:1px solid var(--ink);padding:0 0 2px;cursor:pointer}
.sb-how:hover{color:var(--blue);border-color:var(--blue)}
.sb-mk svg{flex:none;color:var(--ink)}

/* ---- the raid ---- */
.sb-noraid{padding:12px 14px;background:var(--bone);border-radius:var(--r)}
.sb-noraid p{margin:0 0 9px;font-size:13px;line-height:1.5;color:var(--ink-2)}
.sb-noraid .mf-sel,.sb-noraid .asel,.sb-noraid .asel-btn{width:100%}
.sb-noraid .asel-btn{justify-content:space-between}

.sb-raid{display:flex;flex-direction:column;gap:6px;margin-top:4px}
.sb-rr{display:grid;grid-template-columns:1fr auto auto;gap:6px 8px;align-items:center;
  padding:9px 10px;background:var(--bone);border-radius:var(--r)}
.sb-rn{font-size:14px;font-weight:700;letter-spacing:-.015em;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sb-rc{display:inline-flex;align-items:center;gap:2px}
.sb-rc button{width:20px;height:20px;border:1px solid var(--rule);background:var(--paper);
  border-radius:50%;font-size:12px;line-height:1;cursor:pointer;color:var(--ink);padding:0}
.sb-rc button:hover{border-color:var(--ink)}
.sb-rc b{min-width:20px;text-align:center;font-size:13px;font-family:var(--mono)}
.sb-rx{width:20px;height:20px;border:0;background:none;color:var(--grey);font-size:14px;
  line-height:1;cursor:pointer;padding:0}
.sb-rx:hover{color:var(--flare)}
.sb-rr i{grid-column:1 / -1;font-style:normal;font-family:var(--mono);font-size:8px;
  letter-spacing:.09em;text-transform:uppercase;color:var(--grey)}

.sb-rsum{display:grid;grid-template-columns:1fr 1fr;gap:1px;margin-top:10px;
  background:var(--rule);border:1px solid var(--rule);border-radius:var(--r);overflow:hidden}
.sb-rsum div{background:var(--paper);padding:10px 12px}
.sb-rsum dt{font-family:var(--mono);font-size:8px;letter-spacing:.11em;
  text-transform:uppercase;color:var(--grey)}
.sb-rsum dd{margin:3px 0 0;font-size:18px;font-weight:800;letter-spacing:-.025em}

/* ---- the guided tour ----------------------------------------------------
   Anchored to real controls rather than a modal in the middle of the screen:
   the point is to teach the page, and a box over the top of it teaches
   nothing. The page stays usable while the tour talks. */
#tour{position:fixed;inset:0;z-index:80;pointer-events:auto;cursor:pointer}
#tour-card{cursor:default}
#tour.away{opacity:0;transition:opacity .18s;pointer-events:none}
#tour.away #tour-card{pointer-events:none}
/* A 2px black rectangle round the thing being discussed read as a validation
   error. The dimming already says "look here" — so the ring is only the hole
   in it, softened at the corners, with a faint bloom to lift the target off
   the darkened page. No stroke. */
#tour-ring{position:fixed;border-radius:10px;
  box-shadow:0 0 0 9999px rgba(17,17,16,.5), 0 0 0 5px rgba(255,255,255,.5);
  transition:all .28s cubic-bezier(.2,.75,.2,1);pointer-events:none}
#tour-card{position:fixed;background:var(--paper);border:1.4px solid var(--ink);
  border-radius:var(--r);padding:16px 18px 14px;pointer-events:auto;
  box-shadow:0 20px 40px -24px rgba(0,0,0,.5);
  transition:top .28s cubic-bezier(.2,.75,.2,1),left .28s cubic-bezier(.2,.75,.2,1)}
.tc-step{margin:0;font-family:var(--mono);font-size:8px;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;color:var(--grey)}
.tc-t{margin:7px 0 0;font-size:18px;font-weight:800;letter-spacing:-.025em;line-height:1.15}
.tc-b{margin:7px 0 0;font-size:13.5px;line-height:1.5;color:var(--ink-2)}
.tc-nav{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:14px}
.tc-nav span{display:flex;gap:6px}
.tc-nav .btn{font-size:8.5px;padding:7px 12px}
.tc-skip{font-family:var(--mono);font-size:8.5px;font-weight:500;letter-spacing:.11em;
  text-transform:uppercase;color:var(--grey);background:none;border:0;padding:0;cursor:pointer}
.tc-skip:hover{color:var(--ink)}
/* The thing being pointed at stays above the dimming, and stays usable. */
.has-tour #sb-form,.has-tour #sb-side,.has-tour #sb-out{position:relative}

/* A line under each control saying what it is and where the number lives.
   This is the one text on the page a lost reader is actually meant to read,
   and it was set in --grey — the same token as a column label, lighter than
   the figures nobody has to read at all. */
.sb-hint2{display:block;margin-top:5px;font-style:normal;font-size:13px;
  line-height:1.45;color:var(--ink-2)}
.sb-hint3{margin-top:-2px;margin-bottom:2px}

/* ---- the manual ---------------------------------------------------------
   Long-form, read once and referred back to. Set like the reading pages
   rather than like the rail: the reader is here to understand, not to scan. */
.sb-man p{font-size:16px;line-height:1.6;max-width:62ch}
.sb-man-lede{font-size:18px;line-height:1.5;letter-spacing:-.012em;color:var(--ink);
  padding-bottom:20px;border-bottom:1px solid var(--rule)}
.sb-man h3{margin:30px 0 12px;font-family:var(--mono);font-size:9px;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;color:var(--grey)}
.sb-man-o,.sb-man-u{margin:0;padding-left:0;list-style:none;max-width:62ch}
.sb-man-o{counter-reset:man}
.sb-man-o li,.sb-man-u li{position:relative;padding-left:34px;margin-bottom:14px;
  font-size:16px;line-height:1.55;color:var(--ink-2)}
.sb-man-o li b,.sb-man-u li b{color:var(--ink);font-weight:700}
.sb-man-o li::before{counter-increment:man;content:counter(man);position:absolute;
  left:0;top:1px;width:21px;height:21px;border-radius:50%;background:var(--ink);
  color:var(--paper);font-family:var(--mono);font-size:10px;font-weight:500;
  display:grid;place-items:center}
.sb-man-u li::before{content:"";position:absolute;left:6px;top:10px;width:9px;
  height:1.4px;background:var(--ink)}
.sb-man-end{margin-top:30px;padding-top:22px;border-top:1.4px solid var(--ink)}

/* The rails' dropdowns were set at 9px — the same control the rest of the
   page uses at 9px reads fine in a filter bar and does not read at all when
   it is the thing you are filling in. */
.sb-rail .asel-btn,.sb-side .asel-btn{font-size:10.5px;padding:9px 13px}
.sb-rail .asel-o,.sb-side .asel-o{font-size:10.5px}
.sb-ownc{margin-top:14px;padding-top:14px;border-top:1px solid var(--rule);
  margin-bottom:0;padding-bottom:0;border-bottom:0}

/* ---- monsters and mercenaries you own -----------------------------------
   Same shape as the tier ladder, because it answers the same kind of
   question. Two lines per unit: what it is, then its card. */
.sb-own{padding:12px 12px 12px}
/* No longer a field — a read-out of what the war party carries. */
.sb-ownc{margin:12px 0 0;padding:11px 0 0;border-top:1px solid var(--rule);
  border-bottom:0;font-family:var(--mono);font-size:10.5px;font-weight:500;
  letter-spacing:.06em;text-transform:uppercase;color:var(--grey);
  font-variant-numeric:tabular-nums}
.sb-ownr{padding:10px 0;border-top:1px solid var(--rule)}
.sb-ownr:first-of-type{border-top:0;padding-top:0}
.sb-ownh{display:flex;align-items:center;gap:8px}
.sb-ownn{flex:1;min-width:0;font-size:14.5px;font-weight:700;padding:6px 11px}
.sb-ownx{flex:none;width:22px;height:22px;display:grid;place-items:center;font-size:15px;
  line-height:1;color:var(--grey);background:none;border:1px solid var(--rule);
  border-radius:50%;cursor:pointer;padding:0}
.sb-ownx:hover{color:var(--paper);background:var(--flare);border-color:var(--flare)}
.sb-owng{display:grid;grid-template-columns:1fr 1fr;gap:7px 8px;margin-top:9px}
.sb-owng label{display:flex;flex-direction:column;gap:3px;min-width:0}
.sb-owng span:first-child{font-family:var(--mono);font-size:10px;font-weight:500;
  letter-spacing:.1em;text-transform:uppercase;color:var(--grey)}
.sb-owng input{font:inherit;font-size:14px;font-weight:600;width:100%;
  background:var(--paper);border:1px solid var(--rule);border-radius:var(--r-pill);padding:5px 9px}
.sb-owng input:focus{outline:none;border-color:var(--ink)}
/* The odd one out in a five-field hand-entered card takes the full width.
   A roster pick only asks two things, and those sit side by side. */
.sb-owng label:last-child{grid-column:1 / -1}
.sb-owng--ref label:last-child{grid-column:auto}
.sb-owng .mf-sel,.sb-owng .asel,.sb-owng .asel-btn{width:100%}
.sb-owng .asel-btn{justify-content:space-between;font-size:10px;padding:7px 11px}
/* The dragon's three figures sit in a row of their own — they are one fact
   said three ways, not three separate questions. */
.sb-dgrid{grid-template-columns:repeat(3,1fr);margin-top:12px}
.sb-dgrid label:last-child{grid-column:auto}
.sb-dchk{padding:2px 0 8px}
.sb-dnote{margin-top:12px;padding-top:12px;border-top:1px solid var(--rule)}
.sb-ownwait{margin:-4px 0 12px}
/* Outside the melee/ranged/mounted/flying triangle, so no enemy unit-type
   bonus can reach it. Worth saying — it is the reason to bring one. */
.sb-ownfree{display:block;margin-top:3px;font-style:normal;font-family:var(--mono);
  font-size:9.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--blue)}
.sb-dot.cls-epic-hunter,.sb-dot.cls-scout{background:var(--grey)}
.sb-ownadd{margin-bottom:8px;font-size:10px;padding:8px 13px}
/* Picked off the roster, the way a raid squad is. */
.sb-ownadd2{display:block;margin-top:12px}
.sb-ownadd2 select,.sb-ownadd2 .asel,.sb-ownadd2 .asel-btn{width:100%}
.sb-ownadd2 .asel-btn{justify-content:space-between}
/* A roster pick states its card instead of asking you to type it. */
.sb-ownn2{flex:1;min-width:0;font-size:14.5px;font-weight:700;letter-spacing:-.012em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sb-ownref{display:block;margin-top:3px;font-style:normal;font-family:var(--mono);
  font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--grey)}

/* The chip carries which cap the last column is counted in. */
.sb-tt--monster,.sb-tt--merc{background:var(--ink);color:var(--paper)}

.sb-na{font-style:normal;color:var(--rule)}

/* ---- a squad, and the monsters inside it --------------------------------
   The squad is the parent: it carries the type, and the troops that make it
   up are nested in it, which is how the game has it. The old shape put the
   type on a single monster and multiplied — that could not describe a squad
   of two different monsters, nor two squads of different types. */
.sb-addsq{margin-top:10px;font-size:10px;padding:9px 14px}
.sb-sq{margin-top:10px;padding:12px;background:var(--paper);
  border:1px solid var(--rule);border-radius:var(--r)}
.sb-sqh{display:flex;align-items:center;gap:8px;padding-bottom:10px;
  border-bottom:1px solid var(--rule)}
.sb-sqn{flex:1;min-width:0;font-family:var(--mono);font-size:10px;font-weight:500;
  letter-spacing:.12em;text-transform:uppercase;color:var(--grey)}
/* Inherits the uppercase mono every other dropdown on the page uses. It was
   overridden to capitalize, which made the one control sitting between two
   uppercase ones the odd word out. */
.sb-sqt .asel-btn,.sb-sqt select{width:104px;font-size:10px;padding:6px 10px}
.sb-sqt .asel-btn{justify-content:space-between}

/* A monster arrives as some number of units, each holding some number of
   individuals — two questions, so two fields, and the row spells out what
   they multiply to rather than leaving you to do it. */
/* Each monster is a tile on the beige ground, the way it read before — the
   squad card is the container and these are the things in it, which a row
   divided by hairlines did not say. */
.sb-tr2{margin-top:8px;padding:12px 13px;background:var(--bone);border-radius:var(--r)}
.sb-tr2:first-of-type{margin-top:10px}
.sb-tr2h{display:flex;align-items:center;gap:8px}
.sb-tr2 .sb-rn{flex:1;min-width:0;font-size:14px;font-weight:700;letter-spacing:-.012em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sb-tr2g{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:8px;align-items:end}
.sb-f2{display:flex;flex-direction:column;gap:3px;min-width:0}
.sb-tr2g span{font-family:var(--mono);font-size:9.5px;font-weight:500;letter-spacing:.1em;
  text-transform:uppercase;color:var(--grey)}
/* Softened off the pill. A field you type a scouted figure into should look
   like a field, not a tag. */
.sb-tr2g input{font:inherit;font-size:14px;font-weight:700;width:100%;text-align:right;
  background:var(--paper);border:1px solid var(--rule);border-radius:5px;padding:6px 10px}
/* The stepper, back where it was useful — units is a number you nudge. */
.sb-tr2g .sb-rc{display:flex;align-items:center;justify-content:space-between;gap:4px;
  background:var(--paper);border:1px solid var(--rule);border-radius:5px;padding:3px 4px}
.sb-tr2g .sb-rc b{flex:1;text-align:center;font-size:14px;font-weight:700}
.sb-tr2g .sb-rc button{width:22px;height:22px;flex:none;display:grid;place-items:center;
  font-size:14px;line-height:1;color:var(--grey);background:none;border:0;cursor:pointer;
  border-radius:4px;padding:0}
.sb-tr2g .sb-rc button:hover{color:var(--paper);background:var(--ink)}
.sb-tr2g input:focus{outline:none;border-color:var(--ink)}
.sb-tr2g input::placeholder{color:var(--grey-2);font-weight:500}
/* Label left, field right, on its own line — the shape Lo asked for back.
   Corners at 5px rather than a pill, which was the note before it. */
.sb-re{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:9px}
.sb-re > span{font-family:var(--mono);font-size:9.5px;font-weight:500;letter-spacing:.1em;
  text-transform:uppercase;color:var(--grey)}
.sb-re input{font:inherit;font-size:14px;font-weight:700;width:96px;text-align:right;
  background:var(--paper);border:1px solid var(--rule);border-radius:5px;padding:6px 11px}
.sb-tr2h .sb-rc button{background:var(--paper)}
.sb-re input:focus{outline:none;border-color:var(--ink)}
.sb-re input::placeholder{color:var(--grey-2);font-weight:500}

.sb-tr2 i{display:block;margin-top:8px;font-style:normal;font-family:var(--mono);
  font-size:9.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--grey)}
.sb-rx--s{width:19px;height:19px;font-size:13px}
.sb-addm{display:block;margin-top:10px}
.sb-addm select,.sb-addm .asel,.sb-addm .asel-btn{width:100%}
.sb-addm .asel-btn{justify-content:space-between}
.sb-sqtot{margin:10px 0 0;font-family:var(--mono);font-size:9.5px;letter-spacing:.09em;
  text-transform:uppercase;color:var(--grey)}

/* Where the card already says the type, there is nothing to choose. */
/* Same slot, same voice — it replaces the dropdown rather than sitting
   beside it, so it should not look like a different kind of thing. */
.sb-rtf{display:flex;align-items:baseline;gap:6px;font-family:var(--mono);
  font-size:10px;font-weight:500;letter-spacing:.12em;text-transform:uppercase}
.sb-rtf i{font-style:normal;font-family:var(--mono);font-size:8.5px;letter-spacing:.09em;
  text-transform:uppercase;color:var(--grey)}

.sb-rnote{margin-top:12px;padding:11px 13px;background:var(--bone);
  border-left:2px solid var(--rule)}

/* ---- who may march against this ----------------------------------------
   A rule about what is allowed, not a suggestion, so it reads as a short
   list of facts rather than a warning. */
.sb-epic{margin-top:8px;padding:12px 14px;background:var(--bone);border-radius:var(--r)}
.sb-epict{margin:0 0 9px;font-size:14px;line-height:1.5;color:var(--ink)}
.sb-epicl{margin:0;padding:0;list-style:none}
.sb-epicl li{position:relative;padding-left:16px;margin-bottom:7px;font-size:13px;
  line-height:1.5;color:var(--ink-2)}
.sb-epicl li:last-child{margin-bottom:0}
.sb-epicl li::before{content:"";position:absolute;left:0;top:9px;width:8px;height:1.4px;
  background:var(--blue)}
.sb-epic + .sb-epic{margin-top:7px}
/* Two squads that no single march can answer. The one place in this panel
   where something is actually wrong. */
.sb-clash{margin:10px 0 0;padding:11px 13px;font-size:13px;line-height:1.5;
  background:var(--bone);border-left:2px solid var(--flare);color:var(--ink-2)}

/* ---- saved targets -------------------------------------------------------
   A library of camps you fight again, kept apart from your setup — Start
   over empties the page and leaves these alone. */
.sb-saved{display:flex;flex-direction:column;gap:1px;margin-top:8px}
.sb-savedr{display:flex;align-items:center;gap:6px;padding:8px 10px;
  background:var(--paper);border:1px solid var(--rule);border-radius:var(--r)}
.sb-savedl{flex:1;min-width:0;text-align:left;background:none;border:0;padding:0;
  cursor:pointer;display:block}
.sb-savedl b{display:block;font-size:14px;font-weight:700;letter-spacing:-.012em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sb-savedl i{display:block;margin-top:2px;font-style:normal;font-family:var(--mono);
  font-size:9.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--grey)}
.sb-savedl:hover b{color:var(--blue)}
.sb-savenew{display:flex;gap:6px;margin-top:10px}
.sb-savei{flex:1;min-width:0;font:inherit;font-size:14px;background:var(--paper);
  border:1px solid var(--rule);border-radius:var(--r-pill);padding:7px 12px}
.sb-savei:focus{outline:none;border-color:var(--ink)}
.sb-saveb{flex:none;font-size:10px;padding:8px 14px}
.sb-savedn{margin:8px 0 0;font-size:12.5px;line-height:1.45;color:var(--grey);min-height:0}
.sb-savedn.is-said{color:var(--ink)}

/* ---- the hero and the captains -------------------------------------------
   Their bonuses are prose in the Atlas, not figures, so the page shows what
   it was told and calculates none of it. The warnings underneath are the
   part that earns its place. */
.sb-capsh{margin-top:16px;padding-top:14px;border-top:1px solid var(--rule)}
.sb-capf{margin-top:10px}
.sb-cmdd{display:block;margin-top:5px;font-style:normal;font-size:12.5px;
  line-height:1.45;color:var(--grey)}
.sb-cmdw{margin:12px 0 0;padding:10px 12px;font-size:13px;line-height:1.5;
  background:var(--paper);border-left:2px solid var(--flare);color:var(--ink-2)}

/* A captain is a rate times a level. Neither alone is worth printing. */
.sb-caplv{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:8px}
.sb-caplv input{font:inherit;font-size:14px;font-weight:700;width:78px;text-align:right;
  background:var(--paper);border:1px solid var(--rule);border-radius:5px;padding:5px 10px}
.sb-caplv input:focus{outline:none;border-color:var(--ink)}
.sb-caplv input::placeholder{color:var(--grey-2);font-weight:500}
.sb-capfig{display:block;margin-top:8px;font-size:17px;font-weight:800;letter-spacing:-.02em;
  color:var(--blue)}
.sb-capfig i{display:block;margin-top:2px;font-style:normal;font-family:var(--mono);
  font-size:9px;font-weight:500;letter-spacing:.09em;text-transform:uppercase;color:var(--grey)}
.sb-capfig--none{font-size:12.5px;font-weight:500;color:var(--grey)}
.sb-cmdfoot{margin-top:14px;padding-top:12px;border-top:1px solid var(--rule)}
.sb-herolv{margin-top:10px}
.sb-capfig--talent{color:var(--ink)}
/* The Atlas's own sentence about levelling, with its status on the end. */
.sb-heronote{margin-top:10px;padding:10px 12px;background:var(--paper);
  border-left:2px solid var(--rule);color:var(--ink-2)}
.sb-heronote b{font-family:var(--mono);font-size:8.5px;font-weight:500;letter-spacing:.1em;
  text-transform:uppercase;color:var(--flare)}

/* ---- a commander and their kit -------------------------------------------
   Four of these fully open would bury the rail, so a card collapses to a name,
   a level and what it is carrying, and only one opens at a time. */
.sb-cmdc{margin-top:10px;padding:11px 12px;background:var(--bone);border-radius:var(--r)}
.sb-cmdc.open{background:var(--paper);border:1px solid var(--rule);padding:10px 11px}
.sb-cmdh{display:flex;align-items:center;gap:8px}
.sb-cmdk{font-family:var(--mono);font-size:9.5px;font-weight:500;letter-spacing:.11em;
  text-transform:uppercase;color:var(--grey);flex:none}
.sb-cmdn{flex:1;min-width:0;display:flex;align-items:center;justify-content:space-between;
  gap:6px;font:inherit;font-size:14.5px;font-weight:700;letter-spacing:-.012em;
  background:none;border:0;padding:0;cursor:pointer;text-align:left}
.sb-cmdn:hover{color:var(--blue)}
.sb-cmdn[aria-expanded="true"] .asel-c{transform:translateY(1px) rotate(-135deg)}
.sb-cmdsum{margin:4px 0 0;font-family:var(--mono);font-size:9.5px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--grey)}
.sb-kit{margin-top:10px}
.sb-kith{margin-top:14px;padding-top:12px;border-top:1px solid var(--rule);display:block}

/* One worn thing: what it is, optionally its name, and its level. */
.sb-kitr{display:grid;grid-template-columns:1fr auto auto;gap:6px;align-items:center;
  margin-top:7px}
.sb-kits{min-width:0}
.sb-kits .asel-btn,.sb-kits select{width:100%;font-size:9.5px;padding:6px 10px}
.sb-kits .asel-btn{justify-content:space-between}
.sb-kitn{grid-column:1 / -1;font:inherit;font-size:13.5px;width:100%;background:var(--paper);
  border:1px solid var(--rule);border-radius:5px;padding:5px 10px}
.sb-kitn:focus{outline:none;border-color:var(--ink)}
.sb-kitl{display:flex;align-items:center;gap:4px;flex:none}
.sb-kitl span{font-family:var(--mono);font-size:9px;letter-spacing:.09em;
  text-transform:uppercase;color:var(--grey)}
.sb-kitl input{font:inherit;font-size:13.5px;font-weight:700;width:46px;text-align:right;
  background:var(--paper);border:1px solid var(--rule);border-radius:5px;padding:5px 7px}
.sb-kitl input:focus{outline:none;border-color:var(--ink)}
.sb-kitl input::placeholder{color:var(--grey-2);font-weight:500}
.sb-kitadd{margin-top:9px;font-size:9.5px;padding:7px 12px}
.sb-bhint{margin-top:8px}
.sb-bhint2{margin-top:5px;margin-bottom:8px;color:var(--grey)}
.sb-cmdsave{display:flex;align-items:center;gap:9px;flex-wrap:wrap;margin-top:12px;
  padding-top:11px;border-top:1px solid var(--rule)}
.sb-cmdsave .btn{font-size:9.5px;padding:7px 12px}
.sb-cmdsave .sb-savedn{margin:0;font-style:normal}
/* Who this device belongs to. A label, not an account. */
.sb-user{margin-top:16px;padding-top:14px;border-top:1px solid var(--rule)}
.sb-usern{margin:8px 0 0;font-family:var(--mono);font-size:9.5px;letter-spacing:.09em;
  text-transform:uppercase;color:var(--grey)}
/* HP is the column that moves a layer. Str is for the totals only. */
.sb-brow--h .sb-bhp{color:var(--ink)}
.sb-cmdfoot2{margin-top:8px;padding-top:0;border-top:0;color:var(--grey)}
.sb-kitq{flex:none}
.sb-kitq .asel-btn,.sb-kitq select{width:104px;font-size:9.5px;padding:6px 9px}
.sb-kitq .asel-btn{justify-content:space-between}
/* What a commander adds to the march: three caps and a score. */
.sb-caps4{display:grid;grid-template-columns:1fr 1fr;gap:7px 8px;margin-top:9px}
.sb-caps4 label{display:flex;flex-direction:column;gap:3px;min-width:0}
.sb-caps4 span{font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.1em;
  text-transform:uppercase;color:var(--grey)}
.sb-caps4 input{font:inherit;font-size:13.5px;font-weight:700;width:100%;text-align:right;
  background:var(--paper);border:1px solid var(--rule);border-radius:5px;padding:5px 9px}
.sb-caps4 input:focus{outline:none;border-color:var(--ink)}
.sb-caps4 input::placeholder{color:var(--grey-2);font-weight:500}
.sb-starsel .asel-btn,.sb-starsel select{width:104px;font-size:10px;padding:6px 10px}
.sb-starsel .asel-btn{justify-content:space-between}
/* Where the setups live: this browser, or the account. */
/* Signed in, the nav's sign-in link becomes your name and a way out.
   Same size and colour as the link it replaces, so the bar does not
   jump when the session resolves. */
.nav-who--in{display:flex;align-items:baseline;gap:10px}
.nav-name{font-family:var(--mono);font-size:10px;font-weight:500;letter-spacing:.13em;
  text-transform:uppercase;color:var(--acid);white-space:nowrap;text-decoration:none;
  border-bottom:1px solid transparent;transition:border-color var(--dur-fast) var(--ease)}
.nav-name:hover{border-bottom-color:var(--acid)}
.nav-out{font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.11em;
  text-transform:uppercase;color:rgba(244,241,233,.5);background:none;border:0;padding:0;
  cursor:pointer;white-space:nowrap;transition:color var(--dur-fast) var(--ease)}
.nav-out:hover{color:var(--acid)}

.sb-acctl{margin:8px 0 0;font-size:13px;line-height:1.5;color:var(--ink-2)}
.sb-acctl a{color:var(--blue);text-underline-offset:2px}

/* ---- what you own, ticked ------------------------------------------------
   Same shape as the troop list two sections up: everything you could own,
   with a box beside it and the count where the tier range would be. */
.sb-ownlist{display:flex;flex-direction:column;gap:1px;margin-bottom:12px}
.sb-ownrow{display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:5px 0;opacity:.55;transition:opacity .15s ease}
.sb-ownrow.on{opacity:1}
.sb-ownrow .sb-chk{flex:1;min-width:0}
.sb-ownrow .sb-tn{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Unticked, the health is the thing worth knowing — it decides where the
   layer lands. Ticked, it is replaced by the only question left. */
.sb-ownhp{flex:none;font-style:normal;font-family:var(--mono);font-size:9.5px;
  letter-spacing:.08em;text-transform:uppercase;color:var(--grey)}
.sb-ownn3{display:flex;align-items:center;gap:5px;flex:none}
.sb-ownn3 > span{font-size:13px;color:var(--grey)}
.sb-ownn3 input{font:inherit;font-size:13.5px;font-weight:700;width:72px;text-align:right;
  background:var(--paper);border:1px solid var(--rule);border-radius:5px;padding:4px 9px}
.sb-ownn3 input:focus{outline:none;border-color:var(--ink)}
.sb-ownn3 input::placeholder{color:var(--grey-2);font-weight:500}

/* stack:parties:start — war parties, and the capacity read-out that replaced
   the Leadership box. Left-rail bolded text never goes past 500. */
.sb-caps{display:grid;grid-template-columns:1fr;gap:0;margin:10px 0 0;
  border-top:1px solid var(--rule)}
.sb-caps>div{display:flex;align-items:baseline;justify-content:space-between;gap:10px;
  padding:8px 0;border-bottom:1px solid var(--rule)}
.sb-caps dt{font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.12em;
  text-transform:uppercase;color:var(--grey)}
.sb-caps dd{margin:0;font-size:16px;font-weight:500;letter-spacing:-.02em;
  font-variant-numeric:tabular-nums;display:flex;align-items:baseline;gap:6px}
.sb-caps dd i{font-family:var(--mono);font-size:8.5px;font-weight:500;letter-spacing:.1em;
  text-transform:uppercase;color:var(--grey-2);font-style:normal}
.sb-caps .sb-caps--0 dd{color:var(--grey-2)}
.sb-capedit{margin-top:11px}
.sb-cap0{margin-top:9px}
.sb-cap0 p{margin:0 0 10px;font-size:13px;line-height:1.5;color:var(--ink-2)}

.sb-wp{margin-top:10px}
.sb-wpn{margin:0;font-size:14.5px;font-weight:500;letter-spacing:-.015em;
  display:flex;align-items:baseline;justify-content:space-between;gap:8px}
.sb-wpn i{font-family:var(--mono);font-size:8.5px;font-weight:500;letter-spacing:.1em;
  text-transform:uppercase;color:var(--grey-2);font-style:normal;flex:none}
.sb-wpc{margin:4px 0 10px;font-size:12.5px;line-height:1.5;color:var(--ink-2)}

/* The pop-up. Wider than the reading modals — it is a workbench, not a card. */
.sb-wpm .modal-box{max-width:860px}
.sb-wpsub{margin:7px 0 0;font-family:var(--sans);font-size:13px;line-height:1.5;
  color:var(--grey);max-width:52ch}
/* .modal-box is a flex column capped at 88vh and its .modal-body child is
   the scroller — that pairing is what makes every other modal scrollable.
   This body is not called .modal-body (that class styles paragraphs as serif
   and it landed on the commander cards), so it has to carry the scrolling
   itself. Without min-height:0 a flex child refuses to shrink below its
   content and the box clips it instead. */
.sb-wpbody{padding:0 0 22px;font-family:var(--sans);color:var(--ink);
  flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain}
.sb-wpm .modal-head{flex:none}
.sb-wpstrip{display:flex;flex-wrap:wrap;gap:6px;padding:16px 26px;
  border-bottom:1px solid var(--rule);position:sticky;top:0;background:var(--paper);z-index:2}
.sb-wptab{font:inherit;font-size:12.5px;font-weight:500;letter-spacing:-.01em;
  padding:7px 13px;border-radius:999px;border:1px solid var(--rule);background:transparent;
  color:var(--ink-2);cursor:pointer;transition:background var(--dur-fast) var(--ease),
  border-color var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}
.sb-wptab:hover{border-color:var(--ink);color:var(--ink)}
.sb-wptab.on{background:var(--ink);border-color:var(--ink);color:var(--paper)}
.sb-wptab--new{font-family:var(--mono);font-size:10px;letter-spacing:.08em;
  text-transform:uppercase;border-style:dashed}
.sb-wpname{display:flex;align-items:flex-end;gap:14px;padding:18px 26px 0;flex-wrap:wrap}
.sb-wpname label{flex:1 1 240px;display:flex;flex-direction:column;gap:5px;min-width:0}
.sb-wpacts{display:flex;gap:7px;flex:none}
.sb-wpdel:hover{border-color:var(--red,#b3261e);color:var(--red,#b3261e)}
.sb-caps--wp{grid-template-columns:repeat(3,1fr);gap:0 20px;margin:16px 26px 0;
  border-top:1px solid var(--ink)}
.sb-cmdwrap--wp{padding:4px 26px 0}
@media (max-width:720px){
  .sb-caps--wp{grid-template-columns:1fr}
  .sb-wpname{padding:16px 18px 0}
  .sb-wpstrip{padding:14px 18px}
  .sb-cmdwrap--wp{padding:4px 18px 0}
}
/* stack:parties:end */

/* An assumed stock ceiling reads differently from a counted one — it is the
   page's guess doing the limiting, and you can replace it. */
.sb-cap--guess{color:var(--grey-2);font-style:normal;border-bottom:1px dotted var(--grey-2)}

/* war-party:tiles:start — four commanders side by side, then one of them
   with the pop-up to itself. Bolded text stays at 500. */
.sb-tiles{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin:18px 26px 0}
.sb-tile{position:relative;border:1px solid var(--rule);border-radius:var(--r);
  background:var(--paper);min-height:150px;display:flex}
.sb-tile--on{border-color:var(--ink)}
.sb-tileb,.sb-tile--empty{font:inherit;text-align:left;background:none;border:0;cursor:pointer;
  padding:13px 14px 14px;display:flex;flex-direction:column;gap:3px;width:100%;color:var(--ink);
  border-radius:var(--r)}
.sb-tile--empty{border:1px dashed var(--rule);background:transparent;justify-content:flex-start}
.sb-tile--empty:hover{border-color:var(--ink);background:var(--bone)}
.sb-tileb:hover{background:var(--bone)}
.sb-tile--empty:focus-visible,.sb-tileb:focus-visible{outline:2px solid var(--ink);outline-offset:1px}
.sb-tk{font-family:var(--mono);font-size:8.5px;font-weight:500;letter-spacing:.14em;
  text-transform:uppercase;color:var(--grey)}
.sb-tile .sb-tn{font-size:16px;font-weight:500;letter-spacing:-.02em;line-height:1.2;margin-top:2px}
.sb-tile--empty .sb-tn{color:var(--grey-2)}
.sb-tl{font-family:var(--mono);font-size:10px;letter-spacing:.03em;color:var(--ink-2);
  font-variant-numeric:tabular-nums;margin-top:3px}
.sb-tc{font-size:11.5px;line-height:1.4;color:var(--grey)}
.sb-tcap{margin-top:auto;padding-top:9px;font-size:15px;font-weight:500;
  font-variant-numeric:tabular-nums;display:flex;align-items:baseline;gap:5px}
.sb-tcap i{font-family:var(--mono);font-size:8px;font-weight:500;letter-spacing:.1em;
  text-transform:uppercase;color:var(--grey-2);font-style:normal}
.sb-tadd{margin-top:auto;font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink)}
.sb-tilex{position:absolute;top:7px;right:7px;opacity:0;transition:opacity var(--dur-fast) var(--ease)}
.sb-tile--on:hover .sb-tilex,.sb-tilex:focus-visible{opacity:1}

/* the one-commander frame */
.sb-one{padding:0 26px}
/* The way back stays put — the kit below it is taller than the pop-up. */
.sb-oneh{display:flex;align-items:center;gap:14px;padding:16px 0 14px;
  border-bottom:1px solid var(--rule);margin-bottom:4px;
  position:sticky;top:0;z-index:2;background:var(--paper)}
.sb-back{font:inherit;font-family:var(--mono);font-size:9.5px;font-weight:500;letter-spacing:.12em;
  text-transform:uppercase;background:none;border:0;padding:0;cursor:pointer;color:var(--grey);
  display:flex;align-items:center;gap:6px;transition:color var(--dur-fast) var(--ease)}
.sb-back:hover{color:var(--ink)}
.sb-onek{font-family:var(--mono);font-size:9.5px;font-weight:500;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink);margin-left:auto}
.sb-onepick{margin-top:14px}
.sb-onenone{margin:16px 0 0;font-size:13.5px;line-height:1.55;color:var(--grey)}
.sb-onef{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:20px;padding:14px 0 0;
  border-top:1px solid var(--rule);position:sticky;bottom:0;background:var(--paper);z-index:2}
.sb-onesave{margin-left:auto}

@media (max-width:720px){
  .sb-tiles{grid-template-columns:1fr 1fr;gap:8px;margin:16px 18px 0}
  .sb-one{padding:0 18px}
}
@media (max-width:420px){ .sb-tiles{grid-template-columns:1fr} }

/* Flat on the account page: the grid and the frame lose the modal's gutters. */
.sb-wpm--flat .sb-tiles{margin:18px 0 0}
.sb-wpm--flat .sb-one{padding:0}
/* war-party:tiles:end */

/* meganav:heads:start — a column heading that is a page says so. Same size
   and colour as the labels it sits beside, so the arrow is the only tell
   until you reach it. */
.mega .mega-h{font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.15em;
  text-transform:uppercase;color:var(--ink);
  transition:color var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease)}
.mega .mega-h i{font-style:normal;font-size:10px;line-height:1;color:var(--grey-2);
  transition:transform var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}
.mega .mega-h:hover{color:var(--blue);border-bottom-color:var(--blue)}
.mega .mega-h:hover i{transform:translateX(2px);color:var(--blue)}
/* The label that used to be the heading, demoted to a footnote under the
   column so nothing was lost in the swap. */
.mega .mega-note{display:block;margin-top:9px;font-family:var(--mono);font-size:8.5px;
  font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--grey-2);
  font-style:normal}
/* meganav:heads:end */

/* meganav:fact:start — one fact out of the anthologies, where three counts
   of the Atlas's own filing used to be. */
/* The source label sits on the same line as the column headings beside it,
   and the name on the same line as their first row. */
/* .mega a sets a 6px top padding and outranks a bare class. */
.mega .mh-fact{display:block;padding:0 0 16px;border-bottom:1px solid var(--rule)}
.mega .mh-fact .mh-src{display:flex;align-items:center;min-height:13.5px;
  line-height:13.5px;padding-bottom:4px;margin-bottom:12px}
.mega .mh-fact b{margin-top:0}
.mh-src{display:block;font-family:var(--mono);font-size:8.5px;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;color:var(--grey-2)}
.mh-fact b{display:block;margin-top:6px;font-size:21px;font-weight:700;letter-spacing:-.024em;
  line-height:1.15}
.mh-fact em{display:block;margin-top:7px;font-family:var(--serif);font-style:normal;
  font-weight:300;font-size:15.5px;line-height:1.5;color:var(--ink-2)}
.mh-fact:hover b{color:var(--blue)}
.mh-more--quiet{color:var(--grey-2)}
/* meganav:fact:end */

/* meganav:tiles:start */
/* Three cards in a row, not a stack of wide strips. A course or a tool is a
   thing you pick, and a card is the shape that says so.

   Everything below is written as `.mega .mt …` on purpose: `.mega a span`
   dresses every span inside a menu link as a small-caps caption, and it
   outranks a bare class. The tile's own rows are divs for the same reason. */
/* A panel with tiles gets explicit proportions rather than auto-fit's equal
   tracks. Spanning tracks was guesswork: auto-fit lays as many as the width
   allows, so tiles(3) + articles(1) + plate(2) fitted at 1600px, left a
   spare track open as dead air, and wrapped the plate onto a second row at
   1280. Three named proportions cannot wrap and leave nothing spare. */
.mega-in:has(.mega-tiles){
  grid-template-columns:minmax(0,2.9fr) minmax(0,.85fr) minmax(0,1.15fr)}
.mega-tiles{min-width:0}
/* The tiles take the height of the panel rather than of their own copy. The
   plate beside them set the row and the cards stopped two-thirds of the way
   down it, which is the empty band under the first card. Stretch also keeps
   the three level when one blurb runs to a third line. */
.mega-tiles{display:flex;flex-direction:column}
.mt-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;
  align-items:stretch;grid-auto-rows:1fr;max-width:600px;flex:1;min-height:0}
/* A fourth tool would drop to a second row and sit alone in the first
   column with two empty cells beside it. Four across instead, on one line.
   Written as "a fourth that is also the last" rather than against the
   Workshop by name, so a fifth folds back to a clean 3x2 on its own and the
   Academy gets the same if it ever reaches four. The width comes from the
   middle column of the panel, which is why the captions there are short. */
.mt-grid:has(> .mt:nth-child(4):last-child){
  grid-template-columns:repeat(4,minmax(0,1fr));max-width:800px}

/* Beige card, blue rule, blue type. No aspect ratio: the content filled
   about half a 3:4 box and the rest was empty card. */
.mega .mt{display:flex;flex-direction:column;padding:13px 14px 15px;
  border-radius:var(--r);background:var(--bone);border:1px solid var(--blue);
  color:var(--blue);transition:background var(--dur-fast) var(--ease)}
.mega .mt:hover{background:var(--paper)}

.mega .mt .mt-i{display:block;margin:0;padding:0;line-height:0;flex:none;color:var(--blue)}
.mega .mt .mt-i svg{width:16px;height:16px}
.mega .mt .mt-pills{display:flex;flex-wrap:wrap;gap:4px;justify-content:flex-start;
  margin:14px 0 0;padding:0;min-width:0}
.mega .mt .mt-pills i{font-family:var(--mono);font-style:normal;font-size:6.5px;font-weight:500;
  letter-spacing:.05em;text-transform:uppercase;color:var(--blue);white-space:nowrap;
  border:1px solid var(--blue);border-radius:var(--r-pill);padding:3px 5px;
  overflow:hidden;text-overflow:ellipsis}

.mega .mt .mt-body{display:block;margin:12px 0 auto;padding:0}
.mega .mt b{display:block;font-size:16px;font-weight:600;letter-spacing:-.018em;
  line-height:1.18;text-transform:none;color:var(--blue)}
.mega .mt:hover b{color:var(--blue)}
.mega .mt em{display:block;margin:5px 0 0;font-family:var(--serif);font-style:normal;
  font-weight:300;font-size:13px;line-height:1.4;color:var(--blue);text-transform:none;
  letter-spacing:normal}

@media (max-width:1100px){
  .mega-in:has(.mega-tiles){grid-template-columns:minmax(0,1.6fr) minmax(0,1fr)}
  .mt-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
}
@media (max-width:760px){
  .mega-in:has(.mega-tiles){grid-template-columns:minmax(0,1fr)}
  .mt-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  /* Four across is unreadable this narrow, and four tiles make a tidy 2x2.
     Restated because :has() outranks the bare class above it. */
  .mt-grid:has(> .mt:nth-child(4):last-child){
    grid-template-columns:repeat(2,minmax(0,1fr))}
}

/* One clan inside the kingdom, not a fourth peer list. */
.mega-aside{border-left:1px solid var(--rule);padding-left:26px}

/* The newest article, with a cover. */
.mega-hero--read{min-width:0}
.mega .mh-read{display:block;padding:0}
/* Capped. The plate holds a 16:10 shape, and once its column went from 275px
   to 421px that came out 263px tall — taller than the article list beside it,
   which made the panel look like it was mostly cover. It crops instead. */
.mh-plate{position:relative;display:block;aspect-ratio:16/10;max-height:168px;
  border-radius:var(--r);overflow:hidden;background:var(--bone);margin-bottom:11px}
.mh-plate img{width:100%;height:100%;object-fit:cover;display:block}
/* A cover drawn for a dark ground needs the dark ground, and wants to be
   seen whole rather than cropped to fill the tile. */
/* Ink is the default because most of these drawings are white line on dark,
   but the ground belongs to the drawing, not to the frame — the goblet was
   made for flare and the parchment for acid. Stated after the default so the
   named ground wins. `--bleed` is for a drawing meant to run to the edges
   rather than sit inside a margin. */
.mh-plate:has(img){background:var(--ink)}
.mh-plate:has(img) img{object-fit:contain;padding:10px}
.mh-plate--lilac:has(img){background:var(--lilac)}
.mh-plate--flare:has(img){background:var(--flare)}
.mh-plate--acid:has(img){background:var(--acid)}
.mh-plate--bleed:has(img) img{object-fit:cover;padding:0}
.mh-plate i{position:absolute;left:9px;top:9px;font-family:var(--mono);font-style:normal;
  font-size:8px;font-weight:500;letter-spacing:.13em;text-transform:uppercase;
  background:var(--ink);color:var(--paper);padding:3px 7px;border-radius:var(--r-pill)}
.mega .mh-read b{display:block;font-size:19px;font-weight:700;letter-spacing:-.022em;line-height:1.15}
.mega .mh-read em{display:block;margin-top:6px;font-family:var(--serif);font-style:normal;
  font-weight:300;font-size:14.5px;line-height:1.5;color:var(--ink-2)}
.mega .mh-read:hover b{color:var(--blue)}
/* the tournament's three pages, under its tile */
.mega .mh-subs{display:flex;flex-wrap:wrap;gap:0 18px;margin-top:12px;
  padding-top:11px;border-top:1px solid var(--rule)}
.mega .mh-subs a{padding:0;font-family:var(--mono);font-size:8.5px;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;color:var(--grey)}
.mega .mh-subs a:hover{color:var(--blue)}
/* meganav:tiles:end */

/* Every column heading takes the same box, linked or not, so the first row
   of each column sits on the same line. A linked heading carries a rule and
   an arrow; a plain one gets their space without their ink. Without this the
   Register's second column of sections started seven pixels above the first,
   and the Workshop's lists started twelve above its tiles. */
.mega h4,.mega .mega-h{display:flex;align-items:center;gap:6px;width:fit-content;
  min-height:13.5px;line-height:13.5px;padding:0 0 4px;margin:0 0 12px;
  border-bottom:1px solid transparent;box-sizing:content-box}
.mega .mega-h{border-bottom-color:var(--rule)}
.mega .mega-h:hover{border-bottom-color:var(--blue)}

/* Cooper Clan is one clan inside the kingdom, set behind a rule rather than
   reading as a fourth peer of Doctrines and The Kingdom. */
.mega .mega-aside{border-left:1px solid var(--rule);padding-left:28px;margin-left:6px}

/* The filled variant, for comparison against the outlined one. Same two
   tokens, inverted: blue ground, bone rule and type. */
.mega-tiles--solid .mt{background:var(--blue);border-color:var(--blue);color:var(--bone)}
.mega-tiles--solid .mt:hover{background:var(--ink);border-color:var(--ink)}
.mega .mega-tiles--solid .mt b,
.mega .mega-tiles--solid .mt:hover b,
.mega .mega-tiles--solid .mt em{color:var(--bone)}
.mega .mega-tiles--solid .mt .mt-i{color:var(--bone)}
.mega .mega-tiles--solid .mt .mt-pills i{color:var(--bone);border-color:rgba(244,241,233,.55)}

/* The mode's objective, stated under the selector. */
.sb-modeaim{margin:9px 0 0;font-size:13px;line-height:1.5;color:var(--ink-2)}
.sb-modeaim b{display:block;font-weight:500;color:var(--ink);margin-bottom:3px}

/* A field whose section heading is already its label. */
.sb-f--bare{margin-top:10px}
