/* =============================================================================
   DIRTY REBIRTH — THE WEBSITE, IN THE CYBER IDENTITY  [SITECYBER 2026-10-09]
   ONE design token: ui-identity-2026-10-06-cyber/dr-cyber.json (theme black-site).

   🔴 COLOURS, FACES, SIZES, MOTION ARE var(--dr-*), defined in /dr-tokens.css, which is
      GENERATED by scripts/ui/gen-site-cyber.py. Do not type a hex or a font here; edit the
      JSON and re-run. The old HOARDING names (--dr-slab, --dr-oxide ...) are kept so no page
      breaks; their values are the cyber roles (legacy_palette), the map the game uses too.

   The kit: dark translucent panels with ONE cut corner, a 1 px edge keyline and an inner
   glow; the DEPLOY plate (the theme's deploy gradient, a breathing glow, a glint sweep) for
   the page's one main action; edge buttons that light up on hover; a glowing data line where
   the hazard stripe used to be; the launcher's city plate behind the hero.
   Motion: transform/opacity only (base.rules). Nothing is rounded.

   Served from public/. public/_headers must carry `style-src 'self' 'unsafe-inline'`
   or the browser drops this file and every page renders unstyled.
   ============================================================================= */

/* -----------------------------------------------------------------------------
   FACES — Exo 2 is SERVED; the display face is NOT. (design sweep, 2026-09-18)
   Exo 2 is Natanael Gama's, SIL Open Font License 1.1 — the OFL permits exactly this.
   These two files are the game's own webfonts, byte for byte, and they are bound under
   the SAME aliases the game's type.less uses ('Exo-2', 'Exo-2-light'), so the generated
   token stacks in dr-tokens.css resolve to them with no change to the generator.
   Licence text: public/fonts/OFL.txt — it must travel with the files.
   The display face (DirtyBomb-DDBlack / -NXBlack) is Splash Damage's licence and is NOT
   served: redistribution is the owner's ruling. It stays on the fallback stack.
   Relative URLs on purpose: they resolve against this stylesheet, so they work on the
   worker (/fonts/...) and in a file:// preview alike.
   -------------------------------------------------------------------------- */
@font-face {
	font-family: 'Exo-2';
	src: url(fonts/exo2-medium.woff) format('woff');
	font-weight: 100 900;
	font-style: normal;
	font-display: swap;
}
@font-face {
	font-family: 'Exo-2-light';
	src: url(fonts/exo2-light.woff) format('woff');
	font-weight: 100 900;
	font-style: normal;
	font-display: swap;
}

/* -----------------------------------------------------------------------------
   ROLES — the indirection that makes this responsive without inventing a size.
   A role points at a TOKEN. A narrow viewport re-points the role at a smaller
   token; it never introduces a size of its own. The information floor is
   --dr-type-micro (20px) and no role drops below it.
   -------------------------------------------------------------------------- */
:root {
	--role-title:  var(--dr-type-display);   /* 128 — one per page          */
	--role-h1:     var(--dr-type-h1);        /*  56                          */
	--role-h2:     var(--dr-type-h2);        /*  40                          */
	--role-h3:     var(--dr-type-h3);        /*  32                          */
	--role-value:  var(--dr-type-value);     /*  28                          */
	--role-body:   var(--dr-type-body);      /*  24 — prose                  */
	--role-label:  var(--dr-type-label);     /*  22 — stencil labels         */
	--role-micro:  var(--dr-type-micro);     /*  20 — the floor              */
	--role-spine:  var(--dr-type-spine);     /*  15 — decoration only        */

	--role-ctrl:   var(--dr-control-h-primary);
	--role-ctrl-2: var(--dr-control-h-secondary);
	--gutter:      var(--dr-plate-pad-t);

	/* READING TONES — DERIVED from CHALK, because REBAR cannot carry prose.
	   Measured 2026-09-18 with the WCAG 2.x formula on the token hexes:
	     REBAR on CONCRETE 3.01:1 · REBAR on SLAB 3.71:1   -> fails AA (4.5:1) for body text.
	   (DR-IDENTITY.md §2 states "4.6:1 on CONCRETE" for REBAR; that figure is not what the
	   hexes give. It is what CHALK at ~55% over CONCRETE gives.)
	     --site-prose  CHALK at 72%: 6.8:1 on CONCRETE, 7.9:1 on SLAB   — every paragraph
	     --site-quiet  CHALK at 58%: 5.0:1 on CONCRETE, 5.6:1 on SLAB   — labels that carry
	                 information (a stat caption, a nav item, a hash). REBAR stays for pure
	                 stencil decoration: indices beside a heading, form ties, the spine.
	   rgba() over the token channels, per the identity's alpha rule. */
	--site-prose: rgba(var(--dr-chalk-rgb), .72);
	--site-quiet: rgba(var(--dr-chalk-rgb), .58);
}

/* A console (control panel, account console) is dense by function: it prints machine
   state, not prose. It steps every role down one, and stops at the 20 px floor. */
body.dr-dense {
	--role-title: var(--dr-type-h2);
	--role-h1:    var(--dr-type-h3);
	--role-h2:    var(--dr-type-h3);
	--role-h3:    var(--dr-type-label);
	--role-value: var(--dr-type-micro);
	--role-body:  var(--dr-type-micro);
	--role-label: var(--dr-type-micro);
	--role-micro: var(--dr-type-micro);
}

@media (max-width: 1100px) {
	:root { --role-title: var(--dr-type-h1); --gutter: calc(var(--dr-plate-pad-t) * 0.75); }
}
@media (max-width: 760px) {
	:root {
		--role-title: var(--dr-type-h2);
		--role-h1:    var(--dr-type-h3);
		--role-h2:    var(--dr-type-h3);
		--role-body:  var(--dr-type-micro);
		--role-label: var(--dr-type-micro);
		--gutter:     calc(var(--dr-plate-pad-t) * 0.5);
	}
	body.dr-dense { --role-title: var(--dr-type-h3); }
}

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

html {
	background: var(--dr-slab);
	color-scheme: dark;
	-webkit-text-size-adjust: 100%;
}

body {
	min-height: 100vh;
	background:
		radial-gradient(ellipse 70% 50% at 85% -10%, rgba(var(--dr-edge-rgb), .10), rgba(0, 0, 0, 0) 70%),
		radial-gradient(ellipse 60% 45% at 0% 110%, rgba(var(--dr-deploy-a-rgb), .07), rgba(0, 0, 0, 0) 70%),
		var(--dr-slab);
	background-attachment: fixed;
	color: var(--site-prose);         /* was REBAR: 3.0-3.7:1, below AA for prose. See :root. */
	font-family: var(--dr-face-body);
	font-size: var(--role-body);
	line-height: var(--dr-line-body);
}

::selection { background: var(--dr-oxide); color: var(--dr-slab); }

/* -----------------------------------------------------------------------------
   TYPE
   Display face never below 32. Exo-2-light never below 20. Tracking ceiling .10em.
   The only lowercase on screen is prose.
   -------------------------------------------------------------------------- */
h1, .dr-title {
	font-family: var(--dr-face-display);
	font-size: var(--role-title);
	line-height: var(--dr-line-display);
	letter-spacing: var(--dr-track-display);
	text-transform: uppercase;
	color: var(--dr-chalk);
	text-shadow: 0 0 22px var(--dr-glow);
	font-weight: normal;              /* no bold file ships; synthesised bold smears */
	word-break: break-word;
}

h2 {
	font-family: var(--dr-face-display);
	font-size: var(--role-h2);
	line-height: var(--dr-line-h2);
	letter-spacing: var(--dr-track-h2);
	text-transform: uppercase;
	color: var(--dr-chalk);
	font-weight: normal;
	margin: calc(var(--gutter) * 1.5) 0 var(--gutter);
}

h3 {
	font-family: var(--dr-face-display);
	font-size: var(--role-h3);
	line-height: var(--dr-line-h3);
	letter-spacing: var(--dr-track-h3);
	text-transform: uppercase;
	color: var(--dr-chalk);
	font-weight: normal;
	margin: 0 0 12px;
}

/* THE DISPLAY FACE'S FALLBACK, MADE TO RESOLVE. (design sweep, 2026-09-18 — measured)
   The token stack names 'Bahnschrift SemiBold Condensed' as the head of the fallback, but
   a named instance of a variable system font is not a family name Chromium can match: a
   stack holding only that name fell through to Times. So every page rendered plain
   Bahnschrift at REGULAR width — a wide, light DIN, not the heavy condensed cut intended.
   Asking the family that DOES resolve ('Bahnschrift') for weight 600 + condensed selects
   exactly that instance. font-synthesis:none keeps the rule honest when a real DirtyBomb
   face is present: it ships one weight, and a synthesised bold smears (identity §4). */
h1, h2, h3, .dr-title, .dr-primary, .btn.primary, .dr-secondary, .btn.discord, .dr-display {
	font-weight: 700;
	font-stretch: condensed;
	font-synthesis: none;
}

p { max-width: var(--dr-body-measure); }
p + p, ol + p, p + ol { margin-top: 14px; }

b, strong { color: var(--dr-chalk); font-weight: normal; font-family: var(--dr-face-ui); }
em { font-style: normal; color: var(--dr-chalk); }

/* LABEL — the stencil. Every label, index, rail step, nav item. */
.label, .dr-label, th, summary, .stat .k, .help, .warn, legend {
	font-family: var(--dr-face-ui);
	font-size: var(--role-label);
	line-height: var(--dr-line-label);
	letter-spacing: var(--dr-track-label);
	text-transform: uppercase;
	color: var(--dr-rebar);
}

/* MICRO — sub-lines and machine-adjacent labels. Still at the 20 px floor. */
.dr-micro {
	font-family: var(--dr-face-ui);
	font-size: var(--role-micro);
	letter-spacing: var(--dr-track-micro);
	text-transform: uppercase;
	color: var(--dr-rebar);
}

/* SPINE — the build/version line. Decoration; carries nothing stated elsewhere. */
.dr-spine {
	font-family: var(--dr-face-ui);
	font-size: var(--role-spine);
	letter-spacing: var(--dr-track-spine);
	text-transform: uppercase;
	color: var(--dr-aggregate);
}

/* MACHINE TEXT — pids, ports, uuids, hashes, log tails, command names. The one place
   a fourth face is allowed, because a human has to compare it character by character. */
code, pre, .stat .v, .dl-hash, td.t, .pill, input, select, textarea, kbd {
	font-family: var(--dr-face-mono);
}

a {
	color: var(--dr-chalk);
	text-decoration: none;
	box-shadow: inset 0 -1px 0 0 var(--dr-aggregate);   /* a rule under the word, not an underline */
}
a:hover {                                            /* 0 ms switch — never a transition */
	color: var(--dr-oxide);
	box-shadow: inset 0 -1px 0 0 var(--dr-oxide);
}

code {
	font-size: var(--role-micro);
	color: var(--dr-chalk);
	background: var(--dr-slab);
	box-shadow: inset 0 0 0 var(--dr-keyline-rest) var(--dr-aggregate);
	padding: 2px 7px;
	/* A hostname, a fingerprint or a console command has no spaces, so without this its
	   min-content width IS its full width — which set a grid track to 454 px in a 358 px
	   phone column and pushed the whole page sideways (W4, measured 2026-09-18). */
	overflow-wrap: anywhere;
	-webkit-box-decoration-break: clone;
	box-decoration-break: clone;
}

kbd {
	font-size: var(--role-micro);
	color: var(--dr-chalk);
	background: var(--dr-slab);
	box-shadow: inset 0 0 0 var(--dr-keyline-rest) var(--dr-aggregate),
	            inset 0 -2px 0 0 var(--dr-aggregate);
	padding: 2px 8px;
	white-space: nowrap;
}

pre {
	font-size: var(--role-micro);
	line-height: 1.45;
	color: var(--dr-rebar);
	background: var(--dr-slab);
	box-shadow: inset 0 0 0 var(--dr-keyline-rest) var(--dr-aggregate);
	padding: 12px 14px;
	margin-top: 12px;
	max-height: 260px;
	overflow: auto;
	white-space: pre-wrap;
	word-break: break-word;
}

/* -----------------------------------------------------------------------------
   FOCUS — the locator.
   §3 gives keyboard focus its own signal and nothing else. A 2 px CHALK outline
   held off the box is the web's honest equivalent of the two L-brackets; it is not
   a glow and it is not tinted.
   -------------------------------------------------------------------------- */
:focus { outline: none; }
:focus-visible {
	outline: var(--dr-keyline) solid var(--dr-chalk);
	outline-offset: 3px;
}

/* -----------------------------------------------------------------------------
   LAYOUT
   Asymmetry by rule: left heavy, right light. Rules overshoot their parent.
   -------------------------------------------------------------------------- */
.wrap {
	max-width: 1180px;
	margin: 0 auto;
	padding: var(--gutter) var(--gutter) calc(var(--gutter) * 3);
}
body.dr-dense .wrap { max-width: 1560px; }

.dr-bleed {                      /* a rule that runs off the left screen edge */
	margin-left: calc(var(--gutter) * -1);
	width: calc(100% + var(--gutter) * 2);
}

/* A rule that runs off the LEFT screen edge and stops short of the right.
   Placed as a direct child of <body>, never inside .wrap: that makes it full width with no
   `100vw`, which is the version that adds a horizontal scrollbar the moment a vertical one
   appears, and then breaks every `position: sticky` you try to fix it with. */
.dr-screen-rule, .dr-screen-hazard {
	width: max(55%, calc(100% - var(--dr-body-measure)));
	margin: 0;
}
.dr-screen-rule {
	display: block;
	border: 0;
	height: var(--dr-rule-heavy);
	background: var(--dr-oxide);
	box-shadow: 0 0 14px var(--dr-glow);
}

/* THE RULE — the primary structural element, not the box. */
.dr-rule-12, .dr-rule-6, .dr-rule-1 { border: 0; display: block; }
.dr-rule-12 { height: var(--dr-rule-heavy);   background: var(--dr-oxide); box-shadow: 0 0 14px var(--dr-glow); }
.dr-rule-6  { height: var(--dr-rule-element); background: var(--dr-oxide); }
.dr-rule-6.oxide { background: var(--dr-oxide); }
.dr-rule-1  { height: var(--dr-keyline-rest); background: var(--dr-aggregate); }

/* THE DATA LINE (was the hazard stripe) — a state system, never decoration.
   A thin lit rail with a dash pattern; `.armed` streams one period per --dr-dur-crawl
   (background-position, the one non-transform motion, as before). */
.hazard, .dr-hazard {
	height: var(--dr-hazard-band);
	background-color: rgba(var(--dr-edge-rgb), .16);
	background-image: linear-gradient(90deg, var(--dr-oxide) 0, var(--dr-oxide) 55%, rgba(0, 0, 0, 0) 55%);
	background-size: var(--dr-hazard-period) 100%;
	box-shadow: 0 0 12px var(--dr-glow);
	margin: var(--gutter) 0;
}
.hazard.locked, .dr-hazard.locked { background-image: none; background-color: var(--dr-rebar); box-shadow: none; }
.hazard.armed,  .dr-hazard.armed  {
	animation: dr-crawl var(--dr-dur-crawl) var(--dr-ease-crawl) infinite;
}

@keyframes dr-crawl {
	from { background-position: 0 0; }
	to   { background-position: var(--dr-hazard-period) 0; }
}

/* THE PANEL — a module of the operative OS.
   Translucent dark face, ONE cut corner (base.panel.cut), a 1 px edge keyline with a soft inner
   glow, and a lit bracket on the uncut top-left corner. */
.panel, .dr-plate, .step {
	position: relative;
	background: rgba(var(--dr-concrete-rgb), .86);
	padding: var(--dr-plate-pad-t) var(--dr-plate-pad-r) var(--dr-plate-pad-b) var(--dr-plate-pad-l);
	margin: 14px 0;
	box-shadow: inset 0 0 0 var(--dr-keyline-rest) rgba(var(--dr-edge-rgb), .32),
	            inset 0 0 36px rgba(var(--dr-edge-rgb), .07);
	-webkit-clip-path: polygon(0 0, 100% 0,
		100% calc(100% - var(--dr-chamfer)), calc(100% - var(--dr-chamfer)) 100%, 0 100%);
	clip-path: polygon(0 0, 100% 0,
		100% calc(100% - var(--dr-chamfer)), calc(100% - var(--dr-chamfer)) 100%, 0 100%);
}

/* The lit bracket — top-left, the corner the cut does not take. */
.panel::before, .dr-plate::before, .step::before {
	content: "";
	position: absolute;
	top: 0; left: 0;
	width: var(--dr-tie); height: var(--dr-tie);
	box-shadow: inset var(--dr-keyline) var(--dr-keyline) 0 0 var(--dr-oxide);
	pointer-events: none;
}
/* The cut's own edge: the keyline continues along the diagonal. */
.panel::after, .dr-plate::after, .step::after {
	content: "";
	position: absolute;
	right: 0; bottom: 0;
	width: var(--dr-chamfer); height: var(--dr-chamfer);
	background: linear-gradient(to top left,
		rgba(0, 0, 0, 0) calc(50% - var(--dr-keyline-rest)),
		rgba(var(--dr-edge-rgb), .55) calc(50% - var(--dr-keyline-rest)),
		rgba(var(--dr-edge-rgb), .55) 50%,
		rgba(0, 0, 0, 0) 50%);
	pointer-events: none;
}

/* A plate carrying a warning wears a 6 px OXIDE rule down its cut side, not a tint.
   (`amber` is the legacy class name the panel's JS emits; the colour it once meant
   is retired — see the retired list in dr-tokens.json.) */
.panel.notice, .panel.amber {
	box-shadow: inset var(--dr-rule-element) 0 0 0 var(--dr-accent2), inset 0 0 0 var(--dr-keyline-rest) rgba(var(--dr-edge-rgb), .32);
	padding-left: calc(var(--dr-plate-pad-l) + var(--dr-rule-element));
}
.panel.red {
	box-shadow: inset var(--dr-rule-element) 0 0 0 var(--dr-danger), inset 0 0 0 var(--dr-keyline-rest) rgba(var(--dr-edge-rgb), .32);
	padding-left: calc(var(--dr-plate-pad-l) + var(--dr-rule-element));
}

/* A phone cannot spend 88 px of a 390 px screen on plate padding (it was half the reason
   the transparency plates overflowed). Same token, one step: every side takes pad-b. */
@media (max-width: 760px) {
	.panel, .dr-plate, .step { padding: var(--dr-plate-pad-b); }
	.panel.notice, .panel.amber, .panel.red { padding-left: calc(var(--dr-plate-pad-b) + var(--dr-rule-element)); }
}

.grid2 {
	display: grid;
	/* min(…, 100%): a column narrower than 420 px gets one full-width track instead of a
	   420 px track that overflows it. */
	grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr));
	gap: 14px;
}
.grid2 > * { min-width: 0; }
@media (max-width: 760px) { .grid2 { grid-template-columns: 1fr; } }

.steps {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 14px;
	margin: 14px 0;
}
@media (max-width: 980px) { .steps { grid-template-columns: 1fr; } }

.row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.hide { display: none !important; }
/* [SITECYBER] the HTML `hidden` attribute must win over any display rule (.dr-primary is display:flex, which used to
   override it - both download-panel buttons showed at once). */
[hidden] { display: none !important; }
.muted { color: var(--dr-rebar); }

/* -----------------------------------------------------------------------------
   THE HEADER BAND
   -------------------------------------------------------------------------- */
.topline {
	display: flex;
	justify-content: space-between;
	align-items: flex-start;
	gap: 14px;
	flex-wrap: wrap;
	padding-bottom: 14px;
	margin-bottom: 20px;
	border-bottom: var(--dr-keyline-rest) solid var(--dr-aggregate);
}
.brandrow { display: flex; align-items: baseline; gap: 20px; flex-wrap: wrap; }
.tagline { color: var(--dr-rebar); margin-top: 12px; }

/* -----------------------------------------------------------------------------
   THE MARK — a rectangular stencil tag. Never a pill, never rounded, never tinted
   with a fill. Colour is a 0 ms switch on the text and the keyline together.
   -------------------------------------------------------------------------- */
.chip {
	display: inline-block;
	font-family: var(--dr-face-ui);
	font-size: var(--role-micro);
	line-height: 1;
	letter-spacing: var(--dr-track-micro);
	text-transform: uppercase;
	color: var(--dr-oxide);
	background: var(--dr-slab);
	box-shadow: inset 0 0 0 var(--dr-keyline-rest) var(--dr-oxide);
	padding: 7px 12px;
	white-space: nowrap;
}
.chip.ok  { color: var(--dr-verdigris); box-shadow: inset 0 0 0 var(--dr-keyline-rest) var(--dr-verdigris); }
.chip.bad { color: var(--dr-danger);    box-shadow: inset 0 0 0 var(--dr-keyline-rest) var(--dr-danger); }
.chip.dim { color: var(--dr-rebar);     box-shadow: inset 0 0 0 var(--dr-keyline-rest) var(--dr-aggregate); }

/* -----------------------------------------------------------------------------
   CONTROLS
   48 secondary / utility · 64 primary. Nothing rounded, nothing filled but the one
   accent. Press is a 2 px drop at 0 ms; hover switches the keyline at 0 ms.
   -------------------------------------------------------------------------- */
.btn, .dr-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: var(--role-ctrl-2);
	padding: 0 18px;
	border: 0;
	background: rgba(var(--dr-slab-rgb), .72);
	color: var(--dr-chalk);
	box-shadow: inset 0 0 0 var(--dr-keyline-rest) rgba(var(--dr-edge-rgb), .45);
	transition: box-shadow var(--dr-dur-hover) linear, color var(--dr-dur-hover) linear;
	font-family: var(--dr-face-ui);
	font-weight: 700;
	font-size: var(--role-label);
	letter-spacing: var(--dr-track-label);
	text-transform: uppercase;
	line-height: 1;
	cursor: pointer;
	text-decoration: none;
	-webkit-appearance: none;
	appearance: none;
}
.btn:hover:not(:disabled), .dr-btn:hover:not(:disabled) {
	color: var(--dr-chalk);
	transition: none;                                                     /* hover-in is instant */
	box-shadow: inset 0 0 0 var(--dr-keyline) var(--dr-oxide), inset 0 0 16px rgba(var(--dr-edge-rgb), .28);
}
.btn:active:not(:disabled), .dr-btn:active:not(:disabled) {
	transform: translate3d(0, var(--dr-press), 0);                       /* SETTLE */
}
.btn:disabled, .dr-btn:disabled { opacity: .35; cursor: not-allowed; }

.btn.sm { min-height: calc(var(--dr-control-h-secondary) * 0.75); padding: 0 12px; font-size: var(--role-micro); }

/* Destructive. The one red, used so rarely it always means stop. */
.btn.danger {
	color: var(--dr-danger);
	box-shadow: inset 0 0 0 var(--dr-keyline-rest) var(--dr-danger);
}
.btn.danger:hover:not(:disabled) {
	color: var(--dr-chalk);
	background: var(--dr-danger);
	box-shadow: inset 0 0 0 var(--dr-keyline-rest) var(--dr-danger);
}

/* A quiet inline action. No fill, no keyline, a rule under the word. */
.btn.link {
	min-height: 0;
	padding: 0;
	background: none;
	box-shadow: inset 0 -1px 0 0 var(--dr-aggregate);
	color: var(--dr-rebar);
	font-size: var(--role-micro);
}
.btn.link:hover:not(:disabled) {
	color: var(--dr-chalk);
	box-shadow: inset 0 -1px 0 0 var(--dr-oxide);
}

/* The keyline button — §5's secondary. Display face, no fill. */
.dr-secondary, .btn.discord {
	position: relative;
	min-height: var(--role-ctrl-2);
	padding: 0 24px;
	background: rgba(var(--dr-slab-rgb), .6);
	color: var(--dr-chalk);
	box-shadow: inset 0 0 0 var(--dr-keyline) rgba(var(--dr-edge-rgb), .7);
	transition: box-shadow var(--dr-dur-hover) linear;
	font-family: var(--dr-face-display);
	font-size: var(--role-h3);
	letter-spacing: var(--dr-track-h3);
	text-transform: uppercase;
	-webkit-clip-path: polygon(0 0, calc(100% - var(--dr-chamfer-small)) 0,
		100% var(--dr-chamfer-small), 100% 100%, 0 100%);
	clip-path: polygon(0 0, calc(100% - var(--dr-chamfer-small)) 0,
		100% var(--dr-chamfer-small), 100% 100%, 0 100%);
}
.dr-secondary:hover:not(:disabled), .btn.discord:hover:not(:disabled) {
	color: var(--dr-chalk);
	transition: none;
	box-shadow: inset 0 0 0 var(--dr-keyline-selected) var(--dr-oxide), inset 0 0 22px rgba(var(--dr-edge-rgb), .35);
}
/* THE CUT EDGE. An inset box-shadow keyline follows the BOX, not the clip-path, so the
   12 px chamfer used to have no keyline on its diagonal — the corner read as broken, as if
   the frame had been snapped off. This draws the diagonal: a hard-stop line across the
   corner square, on the inside of the cut, the same thickness as the keyline. It is a
   line, not a wash — two stops at one position, like the select chevron below. */
.dr-secondary::after, .btn.discord::after {
	content: "";
	position: absolute;
	top: 0; right: 0;
	width: var(--dr-chamfer-small);
	height: var(--dr-chamfer-small);
	background: linear-gradient(to top right,
		rgba(0, 0, 0, 0) calc(50% - var(--dr-keyline)),
		rgba(var(--dr-edge-rgb), .7) calc(50% - var(--dr-keyline)),
		rgba(var(--dr-edge-rgb), .7) 50%,
		rgba(0, 0, 0, 0) 50%);
	pointer-events: none;
}
.dr-secondary:hover:not(:disabled)::after, .btn.discord:hover:not(:disabled)::after {
	background: linear-gradient(to top right,
		rgba(0, 0, 0, 0) calc(50% - var(--dr-keyline-selected)),
		var(--dr-oxide) calc(50% - var(--dr-keyline-selected)),
		var(--dr-oxide) 50%,
		rgba(0, 0, 0, 0) 50%);
}

/* -----------------------------------------------------------------------------
   THE ONE MAIN ACTION — the DEPLOY plate (base.components.cta).
   The theme's deploy gradient, white words, a breathing inner glow (opacity), and the
   glint sweep on hover (transform). ONE per container.
   -------------------------------------------------------------------------- */
.dr-primary, .btn.primary {
	position: relative;
	overflow: hidden;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: var(--role-ctrl);
	padding: 0 34px;
	border: 0;
	cursor: pointer;
	text-decoration: none;
	background: linear-gradient(135deg, var(--dr-deploy-a), var(--dr-deploy-b));
	color: var(--dr-deploy-text);
	font-family: var(--dr-face-display);
	font-size: var(--role-h2);
	letter-spacing: .12em;
	text-transform: uppercase;
	line-height: 1;
	text-shadow: 0 0 14px rgba(255, 255, 255, .55);
	box-shadow: inset 0 0 0 var(--dr-keyline-rest) rgba(255, 255, 255, .35),
	            inset 0 1px 0 0 rgba(255, 255, 255, .45);
	-webkit-clip-path: polygon(0 0, 100% 0, 100% 100%,
		var(--dr-chamfer-small) 100%, 0 calc(100% - var(--dr-chamfer-small)));
	clip-path: polygon(0 0, 100% 0, 100% 100%,
		var(--dr-chamfer-small) 100%, 0 calc(100% - var(--dr-chamfer-small)));
}
/* The breathing glow: an inner light layer whose OPACITY pulses (transform/opacity only). */
.dr-primary::before, .btn.primary::before {
	content: "";
	position: absolute;
	inset: 0;
	box-shadow: inset 0 0 26px rgba(255, 255, 255, .45);
	opacity: .25;
	animation: dr-breathe var(--dr-pulse) ease-in-out infinite;
	pointer-events: none;
}
@keyframes dr-breathe { 0%, 100% { opacity: .2; } 50% { opacity: .75; } }
.dr-primary:disabled, .btn.primary:disabled { opacity: .35; cursor: not-allowed; }
.dr-primary:disabled::before, .btn.primary:disabled::before { animation: none; }

/* The glint sweep. transform only — a bar that crosses the face once on hover. */
.dr-primary::after, .btn.primary::after {
	content: "";
	position: absolute;
	top: 0; bottom: 0; left: 0;
	width: 40%;
	background: linear-gradient(105deg,
		rgba(0, 0, 0, 0) 0%,
		rgba(255, 255, 255, .28) 50%,
		rgba(0, 0, 0, 0) 100%);
	transform: translate3d(-260%, 0, 0);
	pointer-events: none;
}
.dr-primary:hover::after, .btn.primary:hover::after {
	animation: dr-sweep var(--dr-dur-slam) var(--dr-ease-arrive) 1 forwards;
}
@keyframes dr-sweep {
	from { transform: translate3d(-260%, 0, 0); }
	to   { transform: translate3d(360%, 0, 0); }
}
.dr-primary:hover, .btn.primary:hover { transform: scale(1.02); }
.dr-primary:active, .btn.primary:active { transform: scale(.99) translate3d(0, var(--dr-press), 0); }

/* Destructive primary: the danger face, CHALK text, and NO band — a stop sign does
   not invite you forward. */
.dr-primary.danger, .btn.primary.danger {
	background: var(--dr-danger);
	color: var(--dr-chalk);
}
.dr-primary.danger::before, .btn.primary.danger::before { animation: none; opacity: 0; }

/* -----------------------------------------------------------------------------
   STENCIL INDEX — `01`, `02 / 05`. Numbers, not adjectives.
   -------------------------------------------------------------------------- */
ol.req { list-style: none; counter-reset: n; margin: 14px 0 4px; }
ol.req li {
	counter-increment: n;
	position: relative;
	padding: 12px 0 12px 62px;
	border-top: var(--dr-keyline-rest) solid var(--dr-aggregate);
	max-width: calc(var(--dr-body-measure) + 62px);
}
ol.req li:first-child { border-top: 0; }
ol.req li::before {
	content: "0" counter(n);
	position: absolute;
	left: 0; top: 14px;
	font-family: var(--dr-face-ui);
	font-size: var(--role-label);
	letter-spacing: var(--dr-track-label);
	color: var(--dr-rebar);            /* §5: a stencil index is REBAR. It counts; it does not signal. */
}

/* -----------------------------------------------------------------------------
   ROWS AND TABLES — 1 px aggregate seams, stencil heads, machine values.
   -------------------------------------------------------------------------- */
.stat {
	display: flex;
	justify-content: space-between;
	gap: 18px;
	padding: 7px 0;
	border-bottom: var(--dr-keyline-rest) solid var(--dr-aggregate);
}
.stat:last-child { border-bottom: none; }
.stat .k { flex: 0 0 auto; }
.stat .v {
	color: var(--dr-chalk);
	font-size: var(--role-value);
	line-height: var(--dr-line-value);
	text-align: right;
	word-break: break-word;
}

.dr-scroll { overflow-x: auto; }

table { width: 100%; border-collapse: collapse; }
th {
	text-align: left;
	font-weight: normal;
	padding: 8px 14px 8px 0;
	border-bottom: var(--dr-keyline) solid var(--dr-aggregate);
	white-space: nowrap;
}
td {
	padding: 9px 14px 9px 0;
	border-bottom: var(--dr-keyline-rest) solid var(--dr-aggregate);
	color: var(--dr-rebar);
	vertical-align: top;
	font-size: var(--role-micro);
}
td.t { color: var(--dr-chalk); }
tr.pick { cursor: pointer; }
tr.pick:hover td { color: var(--dr-chalk); }

details { margin-top: 14px; }
summary { cursor: pointer; list-style: none; }
summary::-webkit-details-marker { display: none; }
summary::before { content: "▸ "; color: var(--dr-rebar); }
details[open] > summary::before { content: "▾ "; }
summary:hover { color: var(--dr-chalk); }

/* -----------------------------------------------------------------------------
   FORMS — a field is a slab cut into the plate. Focus is an OXIDE keyline, switched.
   -------------------------------------------------------------------------- */
input[type=text], input[type=password], input[type=number], input[type=search],
select, textarea {
	width: 100%;
	min-height: var(--role-ctrl-2);
	background: var(--dr-slab);
	border: 0;
	box-shadow: inset 0 0 0 var(--dr-keyline-rest) var(--dr-aggregate);
	color: var(--dr-chalk);
	font-size: var(--role-micro);
	padding: 0 12px;
	-webkit-appearance: none;
	appearance: none;
}
textarea { padding: 10px 12px; }
select {
	/* the native arrow is a rounded web-app tell; a chevron drawn with two hard
	   stops is not, and it needs no image and no third-party asset */
	padding-right: 34px;
	background-image:
		linear-gradient(45deg,  rgba(0, 0, 0, 0) 50%, var(--dr-chalk) 50%),
		linear-gradient(135deg, var(--dr-chalk) 50%, rgba(0, 0, 0, 0) 50%);
	background-size: 7px 7px, 7px 7px;
	background-position: calc(100% - 19px) 50%, calc(100% - 12px) 50%;
	background-repeat: no-repeat;
}
input::placeholder { color: var(--dr-aggregate); }
input:focus, select:focus, textarea:focus {
	outline: none;
	box-shadow: inset 0 0 0 var(--dr-keyline) var(--dr-oxide);
}
input[type=checkbox] {
	width: calc(var(--dr-control-h-secondary) / 2); height: calc(var(--dr-control-h-secondary) / 2); min-height: 0;
	accent-color: var(--dr-oxide);
	cursor: pointer;
}

/* An edited-but-unsaved field wears the signal on its own keyline. */
.dirty input, .dirty select { box-shadow: inset 0 0 0 var(--dr-keyline) var(--dr-oxide); }

.fld {
	display: grid;
	grid-template-columns: minmax(240px, 1.2fr) minmax(180px, 1fr);
	gap: 16px;
	align-items: start;
	padding: 14px 0;
	border-bottom: var(--dr-keyline-rest) solid var(--dr-aggregate);
}
.fld:last-child { border-bottom: none; }
.fld .lab {
	color: var(--dr-chalk);
	font-family: var(--dr-face-ui);
	font-size: var(--role-label);
	letter-spacing: var(--dr-track-label);
	text-transform: uppercase;
}
.fld .help, .help { color: var(--dr-rebar); text-transform: none; letter-spacing: 0;
	font-family: var(--dr-face-body); font-size: var(--role-micro); line-height: 1.4; margin-top: 5px; }
.warn { color: var(--dr-oxide); text-transform: none; letter-spacing: 0;
	font-family: var(--dr-face-body); font-size: var(--role-micro); margin-top: 5px; }

.inline { display: grid; grid-template-columns: 1fr auto auto; gap: 8px; align-items: center; margin-top: 12px; }
.rot { display: grid; grid-template-columns: 1fr 1fr auto; gap: 8px; margin-bottom: 8px; }

/* -----------------------------------------------------------------------------
   TABS — the frame rail. The current step carries a 6 px OXIDE band under it.
   -------------------------------------------------------------------------- */
.tabs { display: flex; gap: 0; flex-wrap: wrap; margin-bottom: 14px;
	border-bottom: var(--dr-keyline-rest) solid var(--dr-aggregate); }
.tab {
	position: relative;
	border: 0;
	background: none;
	cursor: pointer;
	padding: 12px 24px;
	font-family: var(--dr-face-ui);
	font-size: var(--role-label);
	letter-spacing: var(--dr-track-label);
	text-transform: uppercase;
	color: var(--dr-rebar);
}
.tab:hover { color: var(--dr-chalk); }
.tab.on { color: var(--dr-chalk); }
.tab.on::after {
	content: "";
	position: absolute;
	left: 0; right: 0; bottom: calc(var(--dr-keyline-rest) * -1);
	height: var(--dr-rule-element);
	background: var(--dr-oxide);
	transform-origin: left center;
	animation: dr-band var(--dr-dur-lock) var(--dr-ease-arrive) both;
}
@keyframes dr-band { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* -----------------------------------------------------------------------------
   PILL — a granted item. Rectangular, machine-set, with a hard remove control.
   -------------------------------------------------------------------------- */
.pill {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	font-size: var(--role-micro);
	color: var(--dr-chalk);
	background: var(--dr-slab);
	box-shadow: inset 0 0 0 var(--dr-keyline-rest) var(--dr-aggregate);
	padding: 6px 10px;
	margin: 0 6px 6px 0;
}
.pill button {
	background: none; border: 0; cursor: pointer; padding: 0;
	color: var(--dr-danger);
	font-family: var(--dr-face-ui);
	font-size: var(--role-micro);
	line-height: 1;
}
.pill button:hover { color: var(--dr-chalk); }

/* -----------------------------------------------------------------------------
   TOAST — a strip bleeding off the right edge, with a 6 px rule ABOVE the text.
   -------------------------------------------------------------------------- */
.toast {
	position: fixed;
	right: 0; bottom: 40px;
	z-index: 9;
	max-width: min(560px, 92vw);
	background: var(--dr-concrete);
	box-shadow: inset 0 var(--dr-rule-element) 0 0 var(--dr-oxide);
	padding: 22px 26px 18px;
	color: var(--dr-chalk);
	font-size: var(--role-micro);
	animation: dr-slam-right var(--dr-dur-slam) var(--dr-ease-arrive) both;
}
.toast.bad { box-shadow: inset 0 var(--dr-rule-element) 0 0 var(--dr-danger); }
.toast.ok  { box-shadow: inset 0 var(--dr-rule-element) 0 0 var(--dr-verdigris); }

/* -----------------------------------------------------------------------------
   MOTION — SLAM. transform + opacity only, quantised to the 90 ms beat.
   Everything arrives from its own edge, stops dead, and recoils 2-3 px.
   -------------------------------------------------------------------------- */
@keyframes dr-slam-left {
	0%   { transform: translate3d(calc(var(--dr-slam-offset-x) * -1), 0, 0); opacity: 0; }
	40%  { opacity: 1; }
	60%  { transform: translate3d(0, 0, 0); }
	70%  { transform: translate3d(var(--dr-recoil), 0, 0); }
	100% { transform: translate3d(0, 0, 0); }
}
@keyframes dr-slam-right {
	0%   { transform: translate3d(var(--dr-slam-offset-x), 0, 0); opacity: 0; }
	40%  { opacity: 1; }
	60%  { transform: translate3d(0, 0, 0); }
	70%  { transform: translate3d(calc(var(--dr-recoil) * -1), 0, 0); }
	100% { transform: translate3d(0, 0, 0); }
}
@keyframes dr-slam-down {
	0%   { transform: translate3d(0, calc(var(--dr-slam-offset-y) * -1), 0); opacity: 0; }
	40%  { opacity: 1; }
	55%  { transform: translate3d(0, 0, 0); }
	65%  { transform: translate3d(0, var(--dr-press), 0); }
	100% { transform: translate3d(0, 0, 0); }
}
@keyframes dr-slam-up {
	0%   { transform: translate3d(0, var(--dr-slam-offset-y), 0); opacity: 0; }
	40%  { opacity: 1; }
	55%  { transform: translate3d(0, 0, 0); }
	65%  { transform: translate3d(0, calc(var(--dr-press) * -1), 0); }
	100% { transform: translate3d(0, 0, 0); }
}
@keyframes dr-rule-in {
	0%   { transform: translate3d(-100%, 0, 0); }
	70%  { transform: translate3d(0, 0, 0); }
	80%  { transform: translate3d(var(--dr-recoil), 0, 0); }
	100% { transform: translate3d(0, 0, 0); }
}

.dr-in-left  { animation: dr-slam-left  var(--dr-dur-slam) var(--dr-ease-arrive) both; }
.dr-in-right { animation: dr-slam-right var(--dr-dur-slam) var(--dr-ease-arrive) both; }
.dr-in-down  { animation: dr-slam-down  var(--dr-dur-slam) var(--dr-ease-arrive) both; }
.dr-in-up    { animation: dr-slam-up    var(--dr-dur-slam) var(--dr-ease-arrive) both; }
.dr-in-rule  { animation: dr-rule-in    var(--dr-dur-slam) var(--dr-ease-arrive) both; }

.dr-d1 { animation-delay: calc(var(--dr-beat) * 1); }
.dr-d2 { animation-delay: calc(var(--dr-beat) * 2); }
.dr-d3 { animation-delay: calc(var(--dr-beat) * 3); }
.dr-d4 { animation-delay: calc(var(--dr-beat) * 4); }
.dr-d5 { animation-delay: calc(var(--dr-beat) * 5); }
.dr-d6 { animation-delay: calc(var(--dr-beat) * 6); }

/* A row moves 6 px toward the reader on hover, in one beat. Neighbours never move. */
.dr-nudge { transition: transform var(--dr-beat) var(--dr-ease-arrive); }
.dr-nudge:hover { transform: translate3d(var(--dr-rule-element), 0, 0); }

@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after {
		animation-duration: 1ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 1ms !important;
	}
}

/* -----------------------------------------------------------------------------
   FOOTER — the spine.
   -------------------------------------------------------------------------- */
footer {
	margin-top: calc(var(--gutter) * 2);
	padding-top: 18px;
	border-top: var(--dr-keyline-rest) solid var(--dr-aggregate);
	display: flex;
	justify-content: space-between;
	gap: 14px;
	flex-wrap: wrap;
	font-family: var(--dr-face-ui);
	font-size: var(--role-micro);
	letter-spacing: var(--dr-track-micro);
	text-transform: uppercase;
	color: var(--dr-rebar);
}
footer a { color: var(--dr-rebar); box-shadow: none; }
footer a:hover { color: var(--dr-oxide); }

/* =============================================================================
   PUBLIC PAGES — the landing page and the contributors page. (design sweep, 2026-09-18)
   Scoped to body.site: the two operator consoles (admin, accounts) share this file and
   are NOT re-laid-out by anything below.

   The page is built as the identity's own fiction — a HOARDING (§1): a wall of cast
   concrete boards with dark joints and form-tie holes, a title struck by the 12 px rule
   that runs off the left screen edge, and one plate pasted on the wall that carries the
   single action. No art, no photograph, no glow: weight comes from material and type.
   Layout px (frame width, column splits) are layout, not tokens; every colour, face,
   type size, easing and duration is still a var(--dr-*) or derived from one.
   ============================================================================= */
body.site {
	--site-gutter: clamp(16px, 4vw, var(--dr-frame));
	--site-max: 1320px;
	--site-title: var(--dr-type-display);                 /* 128 */
	--site-h2: var(--dr-type-h1);                         /*  56 */
	/* Web prose at 20 below 1600 px: the 24 px body step is sized for a 1920 couch screen.
	   Exo-2-light never goes below 20 (identity §4), so this is the floor, not a new size. */
	--role-body: var(--dr-type-micro);
}
@media (min-width: 1600px) { body.site { --role-body: var(--dr-type-body); } }
@media (max-width: 1100px) { body.site { --site-title: calc(var(--dr-type-display) * .75); } }   /* 96 */
@media (max-width: 760px)  { body.site { --site-title: calc(var(--dr-type-display) * .625);      /* 80 */
                                         --site-h2: var(--dr-type-h2); } }                      /* 40 */

body.site p { max-width: 38em; }

.site-frame {
	width: 100%;
	max-width: calc(var(--site-max) + var(--site-gutter) * 2);
	margin: 0 auto;
	padding-left: var(--site-gutter);
	padding-right: var(--site-gutter);
}

/* Stencil index — `01 / 06`. REBAR: it counts, it does not signal. */
.site-idx {
	font-family: var(--dr-face-ui);
	font-size: var(--role-label);
	line-height: 1;
	letter-spacing: var(--dr-track-label);
	text-transform: uppercase;
	color: var(--dr-rebar);
	white-space: nowrap;
}

/* Skip link — invisible until keyboard focus lands on it. */
.site-skip {
	position: absolute;
	left: var(--site-gutter);
	top: -200px;
	z-index: 20;
	padding: 12px 18px;
	background: var(--dr-chalk);
	color: var(--dr-slab);
	box-shadow: none;
	font-family: var(--dr-face-ui);
	font-size: var(--role-micro);
	letter-spacing: var(--dr-track-micro);
	text-transform: uppercase;
}
.site-skip:focus { top: 12px; color: var(--dr-slab); box-shadow: none; }

/* -----------------------------------------------------------------------------
   THE BAR — wordmark, section rail, one utility control. A 1 px seam under it.
   -------------------------------------------------------------------------- */
.site-bar {
	position: relative;
	z-index: 3;
	background: rgba(var(--dr-slab-rgb), .88);
	box-shadow: inset 0 calc(var(--dr-keyline-rest) * -1) 0 0 rgba(var(--dr-edge-rgb), .45),
	            0 1px 14px rgba(var(--dr-edge-rgb), .12);
}
.site-bar-in {
	display: flex;
	align-items: center;
	gap: 40px;
	min-height: 76px;
}
.site-mark {
	font-family: var(--dr-face-display);
	font-size: var(--dr-type-h3);
	line-height: 1;
	letter-spacing: var(--dr-track-h3);
	text-transform: uppercase;
	color: var(--dr-chalk);
	box-shadow: none;
	white-space: nowrap;
	font-weight: 600; font-stretch: condensed; font-synthesis: none;
}
a.site-mark:hover { color: var(--dr-chalk); box-shadow: none; }
.site-bar .site-mark, .site-foot .site-mark { display: inline-flex; align-items: center; gap: 12px; }
.site-bar .site-mark::before, .site-foot .site-mark::before {
	content: "";
	width: 40px; height: 40px;
	background: url(img/skull-holo.png) center / contain no-repeat;
	flex: none;
}
.site-nav { display: flex; gap: 32px; margin-left: auto; }
.site-nav a {
	font-family: var(--dr-face-ui);
	font-size: var(--role-micro);
	line-height: 1;
	letter-spacing: var(--dr-track-micro);
	text-transform: uppercase;
	color: var(--site-quiet);
	box-shadow: none;
	padding: 28px 0;
	white-space: nowrap;
}
.site-nav a:hover {                                  /* 0 ms switch: text + a lit keyline under it */
	color: var(--dr-chalk);
	box-shadow: inset 0 calc(var(--dr-keyline) * -1) 0 0 var(--dr-oxide);
	text-shadow: 0 0 12px var(--dr-glow);
}
.site-bar .btn { flex: none; }
@media (max-width: 1100px) { .site-nav { display: none; } .site-bar-in > .btn { margin-left: auto; } }
@media (max-width: 760px)  { .site-bar-in { min-height: 64px; gap: 16px; } }

/* -----------------------------------------------------------------------------
   THE HERO GROUND — the launcher's cyber city plate (the same art the launcher opens on),
   darkened on the left where the title sits so every word stays readable.
   -------------------------------------------------------------------------- */
.site-hero {
	position: relative;
	overflow: hidden;
	background:
		linear-gradient(90deg, rgba(var(--dr-slab-rgb), .94) 0%, rgba(var(--dr-slab-rgb), .80) 42%, rgba(var(--dr-slab-rgb), .35) 100%),
		linear-gradient(0deg, rgba(var(--dr-slab-rgb), 1) 0%, rgba(var(--dr-slab-rgb), 0) 30%),
		url(img/plate-cyber.jpg) center 40% / cover no-repeat,
		var(--dr-slab);
	box-shadow: inset 0 calc(var(--dr-keyline-rest) * -1) 0 0 rgba(var(--dr-edge-rgb), .35);
}

.site-hero-in {
	position: relative;
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 500px);
	gap: 64px;
	align-items: center;
	padding-top: 104px;
	padding-bottom: 104px;
}
.site-hero-in > * { min-width: 0; }
.site-hero--page .site-hero-in { grid-template-columns: minmax(0, 1fr); padding-top: 88px; padding-bottom: 72px; }

.site-kicker {
	display: flex;
	flex-wrap: wrap;
	gap: 8px 0;
	margin-bottom: 32px;
	font-family: var(--dr-face-ui);
	font-size: var(--role-label);
	line-height: 1;
	letter-spacing: var(--dr-track-label);
	text-transform: uppercase;
	color: var(--site-quiet);
}
.site-kicker > * + * {                                 /* a seam between the two stencils */
	margin-left: 20px;
	padding-left: 20px;
	box-shadow: inset var(--dr-keyline-rest) 0 0 0 var(--dr-aggregate);
}
.site-kicker a { color: var(--site-quiet); box-shadow: none; }
.site-kicker a:hover { color: var(--dr-chalk); box-shadow: none; }

/* THE TITLE, struck by the 12 px CHALK rule (identity §3.1, §4.2 DISPLAY). The rule runs
   off the LEFT screen edge and overshoots the title's own right edge by one chamfer (32 px,
   inside the identity's 24-40 px overshoot) -- so where it stops is decided by the word it
   underlines, not by a fraction of the screen. That is what the old top bar was missing. */
.site-title {
	position: relative;
	width: -webkit-fit-content;
	width: fit-content;
	max-width: 100%;
	font-size: var(--site-title);
	line-height: var(--dr-line-display);
	margin-bottom: calc(var(--dr-rule-heavy) + 48px);
}
.site-title span { display: block; }
.site-title::after {
	content: "";
	position: absolute;
	left: -100vw;
	right: calc(var(--dr-chamfer) * -1);
	bottom: calc((var(--dr-rule-heavy) + 22px) * -1);
	height: var(--dr-rule-heavy);
	background: var(--dr-oxide);
	box-shadow: 0 0 16px var(--dr-glow);
	animation: dr-rule-in calc(var(--dr-dur-slam) + var(--dr-beat)) var(--dr-ease-arrive) both;
}
.site-title-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px; margin-bottom: 24px; }
.site-lede {
	font-size: var(--dr-type-body);
	line-height: var(--dr-line-body);
	color: rgba(var(--dr-chalk-rgb), .82);
}
body.site p.site-lede { max-width: 30em; }

/* THE SPEC STRIP — numbers, not adjectives (§3). Each figure is stated in the page's own
   copy; this only sets it in the display face. */
.site-stats {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	max-width: 760px;
	margin-top: 48px;
	box-shadow: inset 0 var(--dr-keyline-rest) 0 0 var(--dr-aggregate);
}
.site-stats > div {
	display: flex;
	flex-direction: column-reverse;
	justify-content: flex-end;
	padding: 20px 20px 0 0;
}
.site-stats > div + div {
	padding-left: 20px;
	box-shadow: inset var(--dr-keyline-rest) 0 0 0 var(--dr-aggregate);
}
.site-stats dd {
	font-family: var(--dr-face-display);
	font-size: var(--dr-type-h1);
	line-height: .9;
	letter-spacing: var(--dr-track-h1);
	color: var(--dr-chalk);
	font-weight: 600; font-stretch: condensed; font-synthesis: none;
	white-space: nowrap;
}
.site-stats dd small { font-size: var(--dr-type-h3); margin-left: 4px; color: var(--site-quiet); }
.site-stats dd abbr { text-decoration: none; color: var(--site-quiet); }
.site-stats dt {
	margin-top: 10px;
	font-family: var(--dr-face-ui);
	font-size: var(--role-micro);
	line-height: 1.2;
	letter-spacing: var(--dr-track-micro);
	text-transform: uppercase;
	color: var(--site-quiet);
}

/* -----------------------------------------------------------------------------
   THE DOWNLOAD PLATE — the one action, pasted on the wall.
   -------------------------------------------------------------------------- */
.panel.site-dl {
	margin: 0;
	background-color: rgba(var(--dr-concrete-rgb), .92);
}
.site-dl-head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 16px;
	margin-bottom: 24px;
}
.site-dl-head h2 { margin: 0; font-size: var(--dr-type-h1); line-height: var(--dr-line-h1); }
/* The shared primary is 64 high with a 24 px band inside it, which leaves the 40 px word
   touching the top edge. Here it gets the band's height back on top of the control. */
.site-dl .dr-primary {
	display: flex;
	width: 100%;
	font-size: var(--dr-type-h3);
	letter-spacing: .1em;
	white-space: nowrap;
}
.site-dl .dr-primary + .dr-primary { margin-top: 12px; }

/* LOCKED -- the paused download control. Not a greyed-out button (that reads as broken):
   the identity's own LOCKED state (§3.3) -- SLAB face, AGGREGATE keyline, a static CHALK
   hazard band along the foot, the word PAUSED stencilled on it. Nothing crawls: the band
   only crawls on a control you can press now. */
.site-locked {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	min-height: var(--role-ctrl);
	padding: 10px 20px calc(var(--dr-hazard-band) + 10px) 24px;
	background: rgba(var(--dr-slab-rgb), .8);
	box-shadow: inset 0 0 0 var(--dr-keyline) var(--dr-aggregate);
	cursor: not-allowed;
	-webkit-clip-path: polygon(0 0, 100% 0, 100% 100%,
		var(--dr-chamfer-small) 100%, 0 calc(100% - var(--dr-chamfer-small)));
	clip-path: polygon(0 0, 100% 0, 100% 100%,
		var(--dr-chamfer-small) 100%, 0 calc(100% - var(--dr-chamfer-small)));
}
.site-locked::after {
	content: "";
	position: absolute;
	left: 0; right: 0; bottom: 0;
	height: var(--dr-hazard-band);
	background: var(--dr-rebar);
}
.site-locked-label {
	font-family: var(--dr-face-display);
	white-space: nowrap;
	font-size: calc(var(--dr-type-h3) * .85);
	line-height: 1;
	letter-spacing: var(--dr-track-h3);
	text-transform: uppercase;
	color: var(--site-quiet);
	font-weight: 600; font-stretch: condensed; font-synthesis: none;
}
.site-locked-tag {
	flex: none;
	padding: 7px 10px 6px;
	font-family: var(--dr-face-ui);
	font-size: var(--role-micro);
	line-height: 1;
	letter-spacing: var(--dr-track-micro);
	text-transform: uppercase;
	color: var(--dr-chalk);
	box-shadow: inset 0 0 0 var(--dr-keyline-rest) var(--dr-chalk);
}
/* The status line under it: a 6 px CHALK rail, not an OXIDE sentence (OXIDE on type is
   never a sentence, §4.2 -- and OXIDE on CONCRETE is 3.55:1, below AA). */
.site-status {
	margin: 24px 0;
	padding: 2px 0 2px 24px;
	box-shadow: inset var(--dr-rule-element) 0 0 0 var(--dr-oxide);
}
body.site .site-status p { max-width: none; }
.site-dl-meta {
	margin-top: 28px;
	padding-top: 20px;
	box-shadow: inset 0 var(--dr-keyline-rest) 0 0 var(--dr-aggregate);
}
.dl-meta {
	font-family: var(--dr-face-mono);
	font-size: var(--role-micro);
	line-height: 1.35;
	color: var(--dr-chalk);
}
.dl-hash {
	margin-top: 10px;
	font-size: var(--role-spine);
	line-height: 1.5;
	color: var(--site-quiet);
	word-break: break-all;
}

/* -----------------------------------------------------------------------------
   SECTIONS -- an index, a title, and a 1 px seam running to the frame's edge, so every
   section spans the full measure instead of stopping in a column.
   -------------------------------------------------------------------------- */
.site-sec { padding-top: 112px; }
.site-sec:first-of-type { padding-top: 96px; }
.site-head {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 12px 24px;
	margin-bottom: 32px;
}
.site-head h2 { margin: 0; font-size: var(--site-h2); line-height: var(--dr-line-h1); flex: 0 1 auto; }
.site-head::after {
	content: "";
	flex: 1 1 48px;
	height: var(--dr-keyline-rest);
	background: var(--dr-aggregate);
}
.site-intro { margin-bottom: 28px; }

.site-plate { margin: 0; }
.site-cols {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr));
	gap: 32px 72px;
}
.site-cols > * { min-width: 0; }
.site-cols > [hidden] { display: none; }
.site-cols h3 { margin-bottom: 16px; }
.site-big { font-size: var(--dr-type-body); line-height: var(--dr-line-body); color: rgba(var(--dr-chalk-rgb), .82); }

/* Requirements: intro, the checklist, the consequence, the action. On a wide screen the
   checklist stands in its own column beside the prose; on a phone it reads in order. */
.site-req {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	grid-template-areas: "intro list" "warn list" "act list";
	grid-template-rows: auto auto 1fr;
	column-gap: 72px;
	align-items: start;
}
.site-req .r-intro { grid-area: intro; }
.site-req .req     { grid-area: list; margin: 0; }
.site-req .r-warn  { grid-area: warn; margin-top: 20px; }
.site-req .r-act   { grid-area: act; margin-top: 28px; }
body.site ol.req li {
	max-width: none;
	padding: 20px 0 20px 72px;
	font-size: var(--dr-type-body);
	color: rgba(var(--dr-chalk-rgb), .82);
}
body.site ol.req li::before {
	top: 18px;
	font-family: var(--dr-face-display);
	font-size: var(--dr-type-h3);
	letter-spacing: var(--dr-track-h3);
	color: var(--dr-chalk);
	font-weight: 600; font-stretch: condensed; font-synthesis: none;
}
@media (max-width: 900px) {
	.site-req { grid-template-columns: minmax(0, 1fr); grid-template-areas: "intro" "list" "warn" "act"; }
	.site-req .req { margin-top: 16px; }
}

/* Getting in -- ONE plate, three cells, seamed. A sequence, not three floating cards. */
.site-steps {
	list-style: none;
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--dr-keyline);
	background: var(--dr-aggregate);
	-webkit-clip-path: polygon(0 0, 100% 0,
		100% calc(100% - var(--dr-chamfer)), calc(100% - var(--dr-chamfer)) 100%, 0 100%);
	clip-path: polygon(0 0, 100% 0,
		100% calc(100% - var(--dr-chamfer)), calc(100% - var(--dr-chamfer)) 100%, 0 100%);
}
.site-steps li {
	position: relative;
	min-width: 0;
	padding: 32px 40px 40px;
	background-color: rgba(var(--dr-concrete-rgb), .86);
	box-shadow: inset 0 0 0 var(--dr-keyline-rest) rgba(var(--dr-edge-rgb), .25);
}
.site-step-n {
	display: flex;
	align-items: baseline;
	gap: 14px;
	margin-bottom: 20px;
}
.site-step-n b {
	font-family: var(--dr-face-display);
	font-size: var(--dr-type-h1);
	line-height: .85;
	color: var(--dr-chalk);
	font-weight: 600; font-stretch: condensed; font-synthesis: none;
}
.site-step-n span {
	font-family: var(--dr-face-ui);
	font-size: var(--role-micro);
	letter-spacing: var(--dr-track-micro);
	text-transform: uppercase;
	color: var(--site-quiet);
}
.site-steps li:first-child { box-shadow: inset 0 var(--dr-rule-element) 0 0 var(--dr-oxide); }   /* you start here */
@media (max-width: 980px) { .site-steps { grid-template-columns: minmax(0, 1fr); } }

/* THE DOSSIER -- one plate, one row per claim: the claim on the left, its evidence on the
   right, 1 px seams between. Every claim is a thing you can check, not a wall of cards. */
.site-rows { padding-top: 8px; padding-bottom: 8px; }
.site-row {
	display: grid;
	grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
	gap: 14px 56px;
	padding: 30px 0 32px;
	box-shadow: inset 0 var(--dr-keyline-rest) 0 0 var(--dr-aggregate);
}
.site-row:first-child { box-shadow: none; }
.site-row > * { min-width: 0; }
.site-row-h { display: flex; align-items: baseline; gap: 18px; }
.site-row-h .site-idx { min-width: 2.2em; }
.site-row-h--stack { flex-direction: column; align-items: flex-start; gap: 14px; }
/* A section title that sits in a dossier row: an h2 in the outline, the h3 step on screen. */
.site-h3 {
	margin: 0;
	font-size: var(--role-h3);
	line-height: var(--dr-line-h3);
	letter-spacing: var(--dr-track-h3);
	color: var(--dr-chalk);
}
.site-row-h h3 { margin: 0; }
.site-row-h strong {
	font-size: var(--dr-type-body);
	line-height: 1.25;
	color: var(--dr-chalk);
}
.site-row-b p + p { margin-top: 14px; }
.site-row-b .impact {
	display: block;
	margin-top: 14px;
	padding-left: 18px;
	box-shadow: inset var(--dr-keyline) 0 0 0 var(--dr-aggregate);
	color: var(--site-prose);
}
.site-row-b .impact .label { display: block; margin-bottom: 6px; font-size: var(--role-micro); color: var(--site-quiet); }
@media (max-width: 760px) {
	.site-row { grid-template-columns: minmax(0, 1fr); padding: 22px 0 24px; }
	.site-row-h { gap: 12px; }
}

body.site ul.site-list { list-style: none; margin: 18px 0; }
body.site ul.site-list li {
	position: relative;
	padding: 14px 0 14px 34px;
	box-shadow: inset 0 var(--dr-keyline-rest) 0 0 var(--dr-aggregate);
}
body.site ul.site-list li:first-child { box-shadow: none; }
body.site ul.site-list li::before {                   /* a form-tie square, not a bullet disc */
	content: "";
	position: absolute;
	left: 4px; top: 26px;
	width: var(--dr-tie); height: var(--dr-tie);
	background: var(--dr-chalk);
}

/* -----------------------------------------------------------------------------
   PERSON -- one contributor, on the contributors page.
   -------------------------------------------------------------------------- */
.site-person-head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 10px 24px;
	padding-bottom: 10px;          /* the first row's own top seam is the rule under the head */
}
.site-person + .site-person { margin-top: 24px; }
.site-person-head h2 { margin: 0; font-size: var(--dr-type-h1); line-height: var(--dr-line-h1); text-transform: none; }
.site-person-head .label { color: var(--site-quiet); }
.site-person-head .site-person-link { margin-left: auto; font-size: var(--role-micro); }

/* -----------------------------------------------------------------------------
   FOOTER -- the spine: wordmark, the two links, the affiliation line.
   -------------------------------------------------------------------------- */
body.site footer.site-foot {
	display: block;
	margin-top: 128px;
	padding: 0;
	border-top: 0;
	background: var(--dr-slab);
	box-shadow: inset 0 var(--dr-keyline-rest) 0 0 var(--dr-aggregate);
	font-family: var(--dr-face-ui);
	font-size: var(--role-micro);
	letter-spacing: var(--dr-track-micro);
	text-transform: uppercase;
	color: var(--site-quiet);
}
.site-foot-in {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	align-items: flex-start;
	gap: 24px 48px;
	padding-top: 40px;
	padding-bottom: 48px;
}
.site-foot-brand { display: flex; flex-direction: column; gap: 12px; }
.site-foot-links { display: flex; flex-wrap: wrap; gap: 12px 32px; line-height: 1.4; }
body.site footer.site-foot a { color: var(--site-quiet); box-shadow: none; }
body.site footer.site-foot a.site-mark { color: var(--dr-chalk); }
body.site footer.site-foot a:hover { color: var(--dr-chalk); box-shadow: inset 0 -1px 0 0 var(--dr-chalk); }
body.site .site-foot-note { max-width: 30em; line-height: 1.4; text-transform: none; letter-spacing: 0; font-family: var(--dr-face-body); }

/* -----------------------------------------------------------------------------
   NARROW SCREENS
   -------------------------------------------------------------------------- */
@media (max-width: 1100px) {
	.site-hero-in { grid-template-columns: minmax(0, 1fr); gap: 56px; padding-top: 80px; padding-bottom: 64px; }
	.panel.site-dl { max-width: 640px; }
}
@media (max-width: 760px) {
	.site-hero-in { padding-top: 48px; padding-bottom: 32px; gap: 40px; }
	.site-hero--page .site-hero-in { padding-top: 48px; padding-bottom: 40px; }
	.site-kicker { flex-direction: column; margin-bottom: 24px; }
	.site-kicker > * + * { margin-left: 0; padding-left: 0; box-shadow: none; }
	.site-title { margin-bottom: calc(var(--dr-rule-heavy) + 32px); }
	.site-title::after { bottom: calc((var(--dr-rule-heavy) + 14px) * -1); right: calc(var(--dr-gap-lg) * -1); }
	.site-lede { font-size: var(--role-body); }
	.site-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-top: 36px; box-shadow: none; }
	.site-stats > div, .site-stats > div + div {
		padding: 16px 12px 16px 0;
		box-shadow: inset 0 var(--dr-keyline-rest) 0 0 var(--dr-aggregate);
	}
	.site-stats > div:nth-child(even) {
		padding-left: 16px;
		box-shadow: inset 0 var(--dr-keyline-rest) 0 0 var(--dr-aggregate),
		            inset var(--dr-keyline-rest) 0 0 0 var(--dr-aggregate);
	}
	.site-stats dd { font-size: var(--dr-type-h2); }
	.site-stats dd small { font-size: var(--dr-type-micro); }
	.site-dl-head h2 { font-size: var(--dr-type-h2); }
	.site-locked { padding-left: 16px; padding-right: 12px; }
	.site-dl .dr-primary { padding-left: 12px; padding-right: 12px; }
	.site-sec, .site-sec:first-of-type { padding-top: 72px; }
	.site-head { flex-direction: column; align-items: flex-start; gap: 10px; margin-bottom: 20px; }
	.site-head::after { display: none; }
	.site-req .r-act .btn { width: 100%; padding-top: 10px; padding-bottom: 10px; line-height: .95; text-align: center; }
	.site-big, body.site ol.req li { font-size: var(--role-body); }
	body.site ol.req li { padding-left: 56px; }
	.site-steps li { padding: 24px 24px 28px; }
	.site-step-n b { font-size: var(--dr-type-h2); }
	body.site footer.site-foot { margin-top: 88px; }
}
