/*
 * base.css, the shared ground of every component in 06_COMPONENTS.
 * Unforged house identity 3.0.0 Broadside, 2026-08-22. Owner: Andreas.
 *
 * Linked after 02_TOKENS/fonts.css and 02_TOKENS/tokens.css, before demo.css and any
 * component.css. Every value is a token (var(--u-*)) or one of the literals the contract
 * permits (06_COMPONENTS/CONTRACT.md, "Values"): 0, 100%, auto, currentColor, transparent,
 * a unitless number where no token applies. No hex, no px, no rem, no duration.
 *
 * In order: 1 reset, 2 the grounds (four aliases, three wrappers), 3 body, 4 element defaults
 * the identity has a rule for, 5 the focus ring, 6 selection, 7 utilities.
 */

/* ------------------------------------------------------------------ 1 reset */
*, *::before, *::after { box-sizing: border-box; margin: 0; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
img { display: block; max-width: 100%; height: auto; }
table { border-collapse: collapse; border-spacing: 0; }
[hidden] { display: none; }

/* ------------------------------------------------------------ 2 the grounds */
/* Four aliases, not tokens. Each holds exactly one token per ground, so a component reads the
   ink of the ground it sits on (color: var(--u-ground-ink)) and the ground wrapper, not the
   component, decides which token that is. Paper is the default on :root; .u-ground-paper
   restates it for a paper block inside a flood. */
:root, .u-ground-paper {
  --u-ground-ink: var(--u-color-ink-primary);
  --u-ground-ink-secondary: var(--u-color-ink-secondary);
  --u-ground-ink-faint: var(--u-color-ink-faint);
  --u-ground-rule: var(--u-color-rule-paper);
}
.u-ground-paper {
  background-color: var(--u-color-ground-paper);
  color: var(--u-ground-ink);
}
/* The flood: the ink at full coverage. Inverse ink set, rule.flood for every hairline in it.
   A place on the page, at most two per surface, never a theme (two-grounds.md). */
.u-ground-flood {
  --u-ground-ink: var(--u-color-ink-inverse);
  --u-ground-ink-secondary: var(--u-color-ink-inverse-secondary);
  --u-ground-ink-faint: var(--u-color-ink-inverse-faint);
  --u-ground-rule: var(--u-color-rule-flood);
  background-color: var(--u-color-ground-flood);
  color: var(--u-ground-ink);
}
/* The raised step: element backgrounds only (a zebra row, a quote figure, a notice, a span),
   never the ground of a section. The ink set stays paper's (ink.primary 14.96:1, secondary
   7.16:1, faint 4.51:1); a hairline inside it takes rule.axis, because rule.paper measures
   1.196:1 there (colour.md section 3). */
.u-ground-raised {
  --u-ground-rule: var(--u-color-rule-axis);
  background-color: var(--u-color-ground-paper-raised);
}

/* ------------------------------------------------------------------- 3 body */
/* Paper carries ink in the text voice at the body step on the body line box, the vertical unit
   of the page (26px at 390, 28px at 1280, one space.para). Weight 400 is documentation in
   tokens.json, not a token, so it is written here as the number it is. */
body {
  background-color: var(--u-color-ground-paper);
  color: var(--u-ground-ink);
  font-family: var(--u-font-text);
  font-weight: 400;
  font-size: var(--u-size-body);
  line-height: var(--u-leading-body);
  /* The two reading measures resolved here, at the body size, and inherited as absolute lengths
     (registered in section 7): 56ch and 40ch are the 538 / 570px and 384 / 407px of tokens
     measure.* only when ch is the body's zero. */
  --u-measure-prose-body: var(--u-measure-prose);
  --u-measure-narrow-body: var(--u-measure-narrow);
}

/* -------------------------------------------------------- 4 element defaults */
/* A heading carries no size of its own: the type atom sets the step. A UA heading size is a
   value that is not a token reaching a pixel. */
h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; line-height: inherit; }
/* No italic file is hosted and no monospace token exists (typography.md section 6): emphasis
   and a client literal are Barlow 500, a code span is the sentence voice, and the browser
   synthesises nothing. */
em, i, cite, dfn, q, var, address { font-style: normal; }
em, i, strong, b, dfn { font-weight: 500; }
code, kbd, samp, pre, tt { font-family: inherit; font-size: inherit; }
/* The only step under body in sentence case is the caption; the UA "smaller" is not a token. */
small { font-size: var(--u-size-caption); line-height: var(--u-leading-caption); }
/* A mark is a highlight on the raised step; the UA yellow is not a token. The acid highlight
   behind a client's own words is a bounded field of its own (colour.md section 4). */
mark { background-color: var(--u-color-ground-paper-raised); color: inherit; }
/* A link is the ground's ink until the link atom says blue; the UA blue is not a token. */
a { color: inherit; }
/* A form control starts in the page's voice and the ground's ink, squared, inside a hairline
   drawn in currentColor; the input, select, textarea and action atoms paint the rest. The UA
   grey face, the UA white field and the UA system font are values that are not tokens. */
button, input, select, textarea {
  font: inherit;
  letter-spacing: inherit;
  color: inherit;
  background-color: transparent;
  border: var(--u-line-hairline) solid currentColor;
  border-radius: var(--u-radius-none);
}
button { border: 0; padding: 0; }
/* The target floor (WCAG 2.5.8; the contract asks 44 by 44 css px): every control is at least
   space.block tall, 52px at 390 and 56 at 1280, the two line box height the input, select,
   textarea, button and action atoms already set through their padding, so the floor changes
   nothing there and catches a bare control a surface writes without an atom (the a11y review
   2026-08-22 measured the reset button at 28px and the reset input at 32px). The checkbox and
   the radio are excluded by construction: their control is a space.para square and the label
   row around them is the target. */
button, input:not([type="checkbox"]):not([type="radio"]), select, textarea { min-block-size: var(--u-space-block); }
::placeholder { color: var(--u-ground-ink-faint); opacity: 1; }
/* A horizontal rule is the hairline of the ground it sits on. */
hr { border: 0; border-block-start: var(--u-line-hairline) solid var(--u-ground-rule); }

/* -------------------------------------------------------------- 5 focus ring */
/* Two rings, each line.edge thick, adjacent: an ink core that follows the element's edge (a
   flat box-shadow, zero blur, zero offset) and a paper halo outside it (the outline, offset
   by one core). 16.50:1 against each other, so the indicator carries its own edge whatever is
   behind it, and at least one ring clears 3:1 on every ground in the file: the tokens line.edge
   role, the construction 04_PROOF/identity.html renders, the two ring rule of the v2 package.
   The one box-shadow in the library, and it is a ring, not a shadow. Never transitioned
   (motion.state is 0ms and focus is instant by rule), never removed: outline-none is banned.
   One bare pseudo-class, so it carries real specificity and no :where() can lose it. */
:focus-visible {
  outline: var(--u-line-edge) solid var(--u-color-ground-paper);
  outline-offset: var(--u-line-edge);
  box-shadow: 0 0 0 var(--u-line-edge) var(--u-color-ink-primary);
}

/* -------------------------------------------------------------- 6 selection */
/* Selected text is paper on ink; on the flood, ink on paper. One pigment, inverted. */
::selection { background-color: var(--u-color-ink-primary); color: var(--u-color-ground-paper); }
.u-ground-flood ::selection,
.u-ground-flood::selection { background-color: var(--u-color-ground-paper); color: var(--u-color-ink-primary); }

/* -------------------------------------------------------------- 7 utilities */
/* The two reading measures (tokens measure.prose, measure.narrow) as column widths. The ch unit
   is the advance of the figure zero at the element's own font size: 56ch is 570px at the body
   step, 1149px at the head step and 1953px at the title step (measured in Chromium at 1280,
   craft review 2026-08-22, REVIEW-craft.md). So the two measures are registered as lengths,
   resolved once on body (section 3) and inherited: a head, a title or a flush block that asks
   for the prose measure gets the body's 538 / 570px, not 56 of its own zeros. The token stays
   the one place the value lives; these two are aliases of it, like the ground aliases of
   section 2. initial-value 0 is the contract's permitted literal; body overrides it on every
   page. */
@property --u-measure-prose-body { syntax: "<length>"; inherits: true; initial-value: 0; }
@property --u-measure-narrow-body { syntax: "<length>"; inherits: true; initial-value: 0; }
.u-measure { max-width: var(--u-measure-prose-body); }
.u-measure-narrow { max-width: var(--u-measure-narrow-body); }
/* The stack: one space token between children, block flow untouched (a block still fills the
   column, an inline block keeps its width). Default one line box, space.para; the modifiers
   name the other steps. A child's own margin-block-start, set later in the cascade, wins. */
.u-stack > * + * { margin-block-start: var(--u-space-para); }
.u-stack--row > * + * { margin-block-start: var(--u-space-row); }
.u-stack--block > * + * { margin-block-start: var(--u-space-block); }
.u-stack--section > * + * { margin-block-start: var(--u-space-section); }
.u-stack--plate > * + * { margin-block-start: var(--u-space-plate); }
/* Real text for assistive technology beside a visual device (the flush block's SVG lines, an
   icon's name). One hairline square, clipped: the contract's only permitted 1px. */
.u-visually-hidden {
  position: absolute;
  width: var(--u-line-hairline);
  height: var(--u-line-hairline);
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
/* The skip link (WCAG 2.4.1, bypass blocks), the device 04_PROOF/identity.html renders as .skip:
   the first link on a surface that opens with the nav organism. At rest it is the visually hidden
   square above (a hairline, clipped), so it paints nothing wherever the header sits; on :focus it
   is an ink block with a paper label in the action's geometry (label step on the body line box,
   space.row and space.para of padding, 52 / 56px tall) at the top start corner of its containing
   block, the nav (position: relative there). :focus, not :focus-visible, so a screen reader user
   who lands on it by a click sees it too. The ring of section 5 applies on top. */
.u-skip {
  position: absolute;
  inset-inline-start: var(--u-space-page);
  top: 0;
  z-index: 1;
  width: var(--u-line-hairline);
  height: var(--u-line-hairline);
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  background-color: var(--u-color-action-primary);
  color: var(--u-color-action-ink);
  font-family: var(--u-font-display2);
  font-weight: 600;
  font-size: var(--u-size-label);
  line-height: var(--u-leading-body);
  letter-spacing: var(--u-tracking-label);
  text-transform: uppercase;
  text-decoration: none;
}
.u-skip:focus {
  width: auto;
  height: auto;
  overflow: visible;
  clip-path: none;
  padding: var(--u-space-row) var(--u-space-para);
}
