/* ==========================================================================
   The standard. Element, shell and component rules for every screen built
   to the approved design standard (WO-26), composed to the locked
   direction of WO-28: the split gate (an ink brand panel beside the form
   on paper) for the unauthenticated sign-in, and the paper console (a
   shelf rail, a strip head, a headline, ruled registers) for everything
   signed in. Written only against the tokens in tokens.css, which a page
   links first; nothing here names a colour, a size or a length of its
   own. Every screen of every application in the repository (the identity
   service and the inventory console) renders with this one file; the one
   coloured thing, a missing tool, is in signal.css, which the inventory
   application alone links after it.

   Organisation, in this order and no other:
     1. Typefaces       IBM Plex Sans 400, 500, 600 and IBM Plex Mono 400, self-hosted
     2. Elements        plain HTML, styled once
     3. Shell           the masthead, the gate, the rail, the phone band and bar, the strip head, the headline
     4. Components      each built once, named with one class prefix

   No shadow. No capitals. Border radius is the one token or nothing.
   Spacing is the seven tokens and nothing else. Content is separated by
   rules and space, never by boxes. Nothing is centred.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Typefaces. Self-hosted from this origin; swap so text is readable
   before they arrive.
   -------------------------------------------------------------------------- */
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 400; font-display: swap; src: url("fonts/IBMPlexSans-Regular.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 500; font-display: swap; src: url("fonts/IBMPlexSans-Medium.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 600; font-display: swap; src: url("fonts/IBMPlexSans-SemiBold.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url("fonts/IBMPlexMono-Regular.woff2") format("woff2"); }

/* --------------------------------------------------------------------------
   2. Elements
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  font-family: var(--sans);
  font-size: 100%;
  line-height: var(--leading-body);
  font-variant-numeric: tabular-nums lining-nums;
  color: var(--ink);
  background: var(--paper);
  -webkit-text-size-adjust: 100%;
  overflow-x: clip;
}

body {
  margin: 0;
  min-height: 100vh;
  font-size: var(--type-body);
  overflow-x: clip;
}

h1, h2, h3 { margin: 0; line-height: var(--leading-heading); font-weight: var(--semibold); }
h1 { font-size: var(--type-title); }
h2 { font-size: var(--type-heading); margin-top: var(--sp-32); margin-bottom: var(--sp-12); }
h3 { font-size: var(--type-body); margin-top: var(--sp-24); margin-bottom: var(--sp-8); }

p { margin: 0 0 var(--sp-12); max-width: var(--measure-text); }
ul, ol { margin: 0 0 var(--sp-12); padding-left: var(--sp-24); }
small, .note, .caption { font-size: var(--type-caption); color: var(--steel); }
.secondary { font-size: var(--type-secondary); font-weight: var(--medium); color: var(--steel); }
strong { font-weight: var(--semibold); }
hr { border: 0; border-top: var(--rule-1) solid var(--hairline); margin: var(--sp-24) 0; }
img, svg { max-width: 100%; height: auto; }

/* Links are underlined in ink and stay ink. */
a { color: var(--ink); text-decoration: underline; text-underline-offset: 0.15em; text-decoration-thickness: var(--rule-1); }
a:hover { text-decoration-thickness: var(--rule-2); }

/* A standalone link a thumb presses (a way back, a next step): full tap height. Links inside running text keep the text's height. */
.tap { display: inline-flex; align-items: center; min-height: var(--tap); }

/* The mono face is for a machine identifier a person reads character by
   character (a tag as printed, a pairing code), and nothing else. */
code, kbd, .mono { font-family: var(--mono); font-weight: var(--regular); }

table { border-collapse: collapse; border-spacing: 0; }
td.num, th.num { text-align: right; }

/* Every interactive element shows where the keyboard is; nothing ever hides it. */
:focus-visible { outline: var(--ring); outline-offset: var(--ring-offset); }
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible, summary:focus-visible, [tabindex]:focus-visible {
  outline: var(--ring);
  outline-offset: var(--ring-offset);
}

/* Motion answers a person or does not happen; and not at all for someone who asked for less. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}

.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --------------------------------------------------------------------------
   3. Shell: masthead, gate, rail, phone band and bar, strip head, headline
   -------------------------------------------------------------------------- */
.shell { display: grid; grid-template-columns: var(--rail) minmax(0, 1fr); min-height: 100vh; }

.skip {
  position: absolute; left: var(--sp-8); top: var(--sp-8); z-index: 3;
  padding: var(--sp-8) var(--sp-12); background: var(--paper); color: var(--ink);
  transform: translateY(-200%);
}
.skip:focus { transform: none; }

/* The masthead: on a page with no rail that is not the gate (a notice, a
   fault, the launcher), the brand block: the mark, the product's name
   over the company's, the same two lines as the rail's brand. A person
   crossing hostnames can see they are still in the same system and whose
   system it is. The mark is ink with its shape cut out in paper; it takes
   no colour of its own. */
.masthead { padding: var(--sp-32) var(--sp-48) var(--sp-24); border-bottom: var(--rule-1) solid var(--hairline); }
.brand { display: flex; align-items: center; gap: var(--sp-12); }
.brand-mark { display: inline-flex; flex: none; color: var(--ink); }
.brand-mark .mark { display: block; width: 1.75rem; height: 1.75rem; }
.mark-cut { fill: var(--paper); }
.brand-text { display: flex; flex-direction: column; gap: var(--sp-4); line-height: var(--leading-heading); }
.masthead-product { font-size: var(--type-heading); font-weight: var(--semibold); color: var(--ink); text-decoration: none; }
.masthead-company { font-size: var(--type-secondary); font-weight: var(--medium); color: var(--steel); }

/* The foot of a page with no rail: the company's name alone, in steel,
   at the bottom of the viewport. Never a hostname, never a version. */
.plain-foot { margin-top: auto; padding: var(--sp-24) var(--sp-48) var(--sp-32); border-top: var(--rule-1) solid var(--hairline); font-size: var(--type-caption); color: var(--steel); }

/* The gate (WO-28): the one screen a person sees signed out, split in
   two. On the left the brand panel, ink with paper text: the company's
   name, the product's name as a wordmark, a ruled list of what the
   register covers, one line at the foot. On the right the form on paper,
   the width of a field group, flush left, its column set at the middle
   of the viewport's height. The panel is the gate's alone: nothing signed
   in is ever dark. On a phone the panel is a band above the form. */
.gate { display: grid; grid-template-columns: var(--gate-panel) minmax(0, 1fr); min-height: 100vh; }
.gate-brand {
  display: flex; flex-direction: column; justify-content: space-between; gap: var(--sp-48);
  padding: var(--sp-48);
  background: var(--ink); color: var(--paper);
}
.gate-company { display: block; font-size: var(--type-secondary); font-weight: var(--medium); color: var(--hairline); }
.gate-product { display: block; margin-top: var(--sp-16); font-size: var(--type-display); font-weight: var(--semibold); line-height: 1; letter-spacing: -0.02em; }
.gate-list { list-style: none; margin: 0; padding: 0; border-top: var(--rule-2) solid var(--paper); }
.gate-list li { padding: var(--sp-16) 0; border-bottom: var(--rule-1) solid var(--steel); font-size: var(--type-body); }
.gate-list li:last-child { border-bottom: 0; }
.gate-foot { margin: 0; font-size: var(--type-caption); color: var(--hairline); }
.gate .content { display: flex; flex-direction: column; justify-content: center; min-height: 100vh; padding: var(--sp-48); }
.gate .screen-head { display: block; min-height: 0; padding: 0; border-bottom: 0; }
.gate .screen-title { font-size: var(--type-headline); font-weight: var(--semibold); }
.gate .screen-intro { margin: var(--sp-12) 0 0; font-size: var(--type-body); color: var(--steel); }
.gate .screen { flex: 0 0 auto; padding: var(--sp-24) 0 0; }
.gate .button-block { min-height: 3.5rem; }

/* The rail: on shelf, the current entry lifted onto paper with the ink
   mark at its left edge. Lookup stands at the top under no heading; the
   work queues under "Work", each with its count in steel; the screens
   under "Screens"; at the foot the company, the person, and Sign out. */
.rail {
  position: sticky; top: 0; align-self: start; height: 100vh;
  display: flex; flex-direction: column;
  background: var(--shelf);
  border-right: var(--rule-1) solid var(--hairline);
  overflow-y: auto;
}
.rail-brand { padding: var(--sp-24) var(--sp-16) var(--sp-16); border-bottom: var(--rule-1) solid var(--hairline); }
.rail-product { display: block; font-size: var(--type-heading); font-weight: var(--semibold); color: var(--ink); text-decoration: none; }
.rail-company { display: block; font-size: var(--type-caption); color: var(--steel); }
.rail-search { display: flex; gap: var(--sp-4); padding: var(--sp-12) var(--sp-16) 0; }
.rail-search .control { flex: 1 1 auto; min-width: 0; }
.rail-search .button { flex: 0 0 auto; padding-left: var(--sp-12); padding-right: var(--sp-12); }
.rail-list { list-style: none; margin: 0; padding: var(--sp-8) 0; }
.rail-group { margin-top: var(--sp-8); padding: var(--sp-12) var(--sp-16) var(--sp-4); border-top: var(--rule-1) solid var(--hairline); font-size: var(--type-caption); color: var(--steel); }
.rail-item {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-8);
  min-height: var(--tap); padding: var(--sp-8) var(--sp-16);
  color: var(--ink); text-decoration: none; font-size: var(--type-secondary); font-weight: var(--regular);
  border-left: var(--rule-2) solid transparent;
}
a.rail-item:hover { background: var(--paper); }
.rail-item.is-current { border-left-color: var(--ink); background: var(--paper); font-weight: var(--semibold); }
.rail-item.is-unbuilt { color: var(--steel); }
.rail-count { font-size: var(--type-caption); font-weight: var(--regular); color: var(--steel); min-width: 1.75rem; text-align: right; }
.rail-count.is-none { color: var(--steel); }
.rail-foot { margin-top: auto; padding: var(--sp-16); border-top: var(--rule-1) solid var(--hairline); font-size: var(--type-caption); }
.rail-tenant { font-weight: var(--medium); color: var(--ink); }
.rail-person { color: var(--steel); }
.rail-apps { list-style: none; margin: var(--sp-8) 0 0; padding: 0; }
.rail-apps li { min-height: var(--tap); display: flex; align-items: center; }
.rail-apps .is-unavailable { color: var(--steel); }
.rail-signout { margin-top: var(--sp-4); }

/* A button drawn as a link: the one control that must be a form (Sign
   out posts) but reads as a word in the rail's foot. */
.button-link {
  display: inline-flex; align-items: center; min-height: var(--tap); padding: 0; margin: 0;
  font: inherit; font-size: var(--type-caption); color: var(--ink);
  background: none; border: 0; text-decoration: underline; text-underline-offset: 0.15em; cursor: pointer;
}
.button-link:hover { text-decoration-thickness: var(--rule-2); }

/* The content column. The head is a strip: the screen's name at body
   weight, the age of the data at its right; under it a screen may state
   its headline, closed by a 2px ink rule; the screen itself; and at the
   bottom, pushed to the foot of the column, one closing sentence over a
   2px rule. */
.content { min-width: 0; display: flex; flex-direction: column; }
.screen-head {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-8) var(--sp-16);
  min-height: 4rem; padding: var(--sp-12) var(--sp-32);
  border-bottom: var(--rule-1) solid var(--hairline);
}
.screen-title { flex: 1 1 auto; min-width: 0; font-size: var(--type-body); font-weight: var(--medium); }
.screen-asof { font-size: var(--type-caption); color: var(--steel); }
/* One sentence under the screen title, in steel, on its own line below everything else in the header. */
.screen-intro { flex: 0 0 100%; max-width: 100%; margin: var(--sp-4) 0 0; font-size: var(--type-secondary); color: var(--steel); }
.screen-intro p { margin: 0; }
.screen-lead {
  display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--sp-16) var(--sp-32);
  padding: var(--sp-24) var(--sp-32);
  border-bottom: var(--rule-2) solid var(--ink);
}
.screen-lead-text { flex: 1 1 24rem; min-width: 0; }
.screen-lead .actions { margin: 0; }
.headline { margin: 0; font-size: var(--type-headline); font-weight: var(--semibold); line-height: var(--leading-heading); max-width: none; }
.headline-note { margin: var(--sp-8) 0 0; font-size: var(--type-body); color: var(--steel); }
.screen { flex: 1 1 auto; padding: var(--sp-24) var(--sp-32) var(--sp-48); }
.screen-foot { margin-top: auto; padding: var(--sp-24) var(--sp-32); border-top: var(--rule-2) solid var(--ink); font-size: var(--type-secondary); color: var(--steel); }
.screen-foot p { margin: 0; }
/* With no rail the masthead carries the rule; the title takes real air
   under it and the screen a wider gutter, so the page reads as a
   composed notice rather than a form under a heading. */
.plain .content { min-height: 100vh; }
.plain .screen-head { display: block; min-height: 0; border-bottom: 0; padding: var(--sp-48) var(--sp-48) 0; }
.plain .screen-title { font-size: var(--type-title); font-weight: var(--semibold); }
.plain .screen { flex: 0 0 auto; padding: var(--sp-24) var(--sp-48) var(--sp-48); }

/* The phone band (the brand and the menu), the phone bar and the phone
   menu exist only on a phone. */
.bar, .menu { display: none; }

@media (max-width: 44.9375rem) {
  .shell { display: block; }
  .rail { display: none; }
  .shell .content { padding-bottom: var(--bar); }
  .masthead { padding: var(--sp-24) var(--sp-16) var(--sp-16); }
  .screen-head { min-height: 0; padding: var(--sp-12) var(--sp-16); }
  .screen-lead { padding: var(--sp-16); }
  .headline { font-size: var(--type-title); }
  .screen { padding: var(--sp-16) var(--sp-16) var(--sp-32); }
  .screen-foot { padding: var(--sp-16); }
  .plain .screen-head { padding: var(--sp-32) var(--sp-16) 0; }
  .plain .screen { padding: var(--sp-16) var(--sp-16) var(--sp-32); }
  .plain-foot { padding: var(--sp-16) var(--sp-16) var(--sp-24); }
  .gate { display: block; }
  .gate-brand { min-height: 16.25rem; gap: var(--sp-16); padding: var(--sp-24) var(--sp-16); }
  .gate-product { font-size: var(--type-display-phone); }
  .gate-list { display: none; }
  .gate .content { min-height: 0; justify-content: flex-start; padding: var(--sp-24) var(--sp-16) var(--sp-32); }
  .bar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 2;
    display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
    height: var(--bar);
    background: var(--shelf); border-top: var(--rule-1) solid var(--hairline);
  }
  /* Every entry's label sits on one baseline at the bottom; a queue's count stands above its label. */
  .bar-item {
    display: flex; flex-direction: column; align-items: flex-start; justify-content: flex-end; gap: var(--sp-4);
    min-height: var(--tap); padding: var(--sp-4) var(--sp-8) var(--sp-8);
    color: var(--ink); text-decoration: none; font-size: var(--type-caption); line-height: var(--leading-heading);
    border-top: var(--rule-2) solid transparent;
  }
  .bar-item.is-current { border-top-color: var(--ink); background: var(--paper); font-weight: var(--semibold); }
  .bar-item.is-unbuilt { color: var(--steel); }
  .bar-count { font-size: var(--type-body); font-weight: var(--semibold); }
  .bar-count.is-none { font-weight: var(--regular); color: var(--steel); }
  /* The band: the brand at the left, the word Menu at the right; the whole band is the disclosure. */
  .menu { display: block; background: var(--shelf); border-bottom: var(--rule-1) solid var(--hairline); }
  .menu > summary {
    list-style: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: var(--sp-16);
    min-height: var(--tap); padding: var(--sp-12) var(--sp-16);
  }
  .menu > summary::-webkit-details-marker { display: none; }
  .band-brand { display: flex; flex-direction: column; min-width: 0; }
  .band-product { font-size: var(--type-heading); font-weight: var(--semibold); line-height: var(--leading-heading); }
  .band-company { font-size: var(--type-caption); color: var(--steel); }
  .band-menu { flex: none; font-weight: var(--medium); text-decoration: underline; text-underline-offset: 0.15em; }
  .menu[open] > summary .band-menu { font-weight: var(--semibold); }
  .menu .rail-search { border-top: var(--rule-1) solid var(--hairline); padding: var(--sp-12) var(--sp-16); }
  .menu .rail-list { border-top: var(--rule-1) solid var(--hairline); }
  .menu .rail-search + .rail-list { border-top: 0; }
  .menu .rail-foot { margin-top: 0; }
}

/* --------------------------------------------------------------------------
   4. Components
   -------------------------------------------------------------------------- */

/* Age indicator: the age in words over a short bar, always both. The
   ramp is achromatic: the bar fills with ink in proportion to the age and
   the words gain weight with it (recent regular, aging medium, stale
   semibold). Never confirmed is its own state, not the far end of the
   ramp: an empty dashed bar and the words in steel. On a phone the words
   and the bar sit side by side. */
.age { display: inline-flex; flex-direction: column-reverse; align-items: flex-start; gap: var(--sp-8); white-space: nowrap; font-size: var(--type-secondary); }
.age-bar { display: block; width: 7.5rem; height: var(--sp-4); background: var(--hairline); }
.age-fill { display: block; height: 100%; width: var(--age-fill, 0%); background: var(--ink); }
.age-words { color: var(--ink); }
.age-aging .age-words { font-weight: var(--medium); }
.age-stale .age-words { font-weight: var(--semibold); }
.age-never .age-words { color: var(--steel); }
.age-never .age-bar { background: transparent; border: var(--rule-1) dashed var(--steel); }
.age-never .age-fill { display: none; }
.age-lead { font-size: var(--type-heading); }
.age-lead .age-bar { width: 11.25rem; }
td .age { font-size: var(--type-secondary); }
@media (max-width: 44.9375rem) {
  .age { flex-direction: row-reverse; align-items: center; gap: var(--sp-12); }
  .age-bar { width: 5rem; }
}

/* Data table, the register: dense, ruled, aligned. The header row is
   steel captions over a 1px ink rule; rows are parted by hairlines; a
   group row (a site over its warehouses) is the one filled surface.
   Scrolls inside its own box, never the page. */
.table-wrap { position: relative; overflow-x: auto; max-width: 100%; margin: 0 0 var(--sp-16); }
.data { width: 100%; font-size: var(--type-secondary); }
.data th, .data td { padding: var(--sp-12); text-align: left; vertical-align: top; border-bottom: var(--rule-1) solid var(--hairline); }
.data th:first-child, .data td:first-child { padding-left: 0; }
.data thead th { padding-top: 0; padding-bottom: var(--sp-8); font-size: var(--type-caption); font-weight: var(--regular); color: var(--steel); border-bottom: var(--rule-1) solid var(--ink); white-space: nowrap; }
.data tbody tr:hover { background: var(--shelf); }
.data td.num, .data th.num { text-align: right; }
.data td.secondary { color: var(--steel); font-weight: var(--regular); }
.data .cell-lead { font-size: var(--type-body); }
.data .sub { display: block; font-size: var(--type-caption); color: var(--steel); }
.data .over { display: block; margin-bottom: var(--sp-4); font-size: var(--type-caption); color: var(--steel); }
.data .cell-actions { white-space: nowrap; }
.data .cell-actions form { display: inline-block; margin: 0; }
.data tr.is-empty td { color: var(--steel); }
.data tr.is-group td { background: var(--shelf); padding-top: var(--sp-16); padding-bottom: var(--sp-16); }
.data tr.is-group td:first-child { padding-left: var(--sp-12); }
.data tr.is-group .row-link { font-weight: var(--semibold); }
.indent { display: inline-block; padding-left: var(--sp-24); border-left: var(--rule-1) solid var(--hairline); }
.indent .sub { padding-left: 0; }
.sort { color: var(--steel); text-decoration: none; display: inline-flex; align-items: center; gap: var(--sp-4); }
.sort:hover { text-decoration: underline; }
.sort-mark { font-size: var(--type-caption); }
.sort.is-active { color: var(--ink); font-weight: var(--semibold); }
th.num .sort { justify-content: flex-end; width: 100%; }
@media (max-width: 44.9375rem) {
  .data { font-size: var(--type-body); }
  .data th, .data td { padding: var(--sp-8) var(--sp-12); }
  /* Stacked: each row becomes a block a thumb can read top to bottom.
     Cells carry their column name in data-label. */
  .data-stack, .data-stack tbody, .data-stack tr, .data-stack td { display: block; }
  .data-stack thead { display: none; }
  .data-stack tr { padding: var(--sp-8) 0; border-bottom: var(--rule-1) solid var(--hairline); }
  .data-stack tbody tr:last-child { border-bottom: 0; }
  .data-stack td, .data-stack td.num { text-align: left; border-bottom: 0; padding: var(--sp-4) 0; }
  .data-stack td[data-label]::before { content: attr(data-label); display: block; font-size: var(--type-caption); color: var(--steel); }
  .data-stack td.cell-lead { font-size: var(--type-heading); }
  .data-stack tr.is-group td { padding: var(--sp-4) var(--sp-12); }
  .data-stack tr.is-group { padding: var(--sp-8) 0; }
  .data-stack .indent { padding-left: 0; border-left: 0; }
  .data-stack td .age { font-size: var(--type-body); }
  .data-stack tr.is-empty td { padding: var(--sp-8) 0; }
}

/* Row link: the leading cell of a row that opens a record. */
.row-link { font-weight: var(--medium); text-decoration: none; }
.row-link:hover { text-decoration: underline; }
@media (max-width: 44.9375rem) {
  .data-stack .row-link { display: inline-flex; align-items: center; min-height: var(--tap); }
}

/* The trail: each ancestor of a record, root first, as a link. */
.crumbs ol { list-style: none; display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4) 0; margin: 0 0 var(--sp-12); padding: 0; font-size: var(--type-secondary); }
.crumbs li { display: inline-flex; align-items: center; min-height: var(--tap); }
.crumbs li + li::before { content: "\203A"; padding: 0 var(--sp-8); color: var(--steel); }
.crumbs li[aria-current] { font-weight: var(--medium); }

/* Messages: what happened and what to do, in ink, between two rules.
   Never coloured. The mark is not drawn: an icon appears only where it
   replaces a word that would otherwise repeat in every row. */
.message { padding: var(--sp-12) 0; margin: 0 0 var(--sp-16); border-top: var(--rule-1) solid var(--hairline); border-bottom: var(--rule-1) solid var(--hairline); max-width: var(--measure-text); }
.message-mark { display: none; }
.message-title { display: block; font-weight: var(--semibold); }
.message p:last-child { margin-bottom: 0; }

/* Empty state: one sentence of what is so, one of what to do, the way
   forward as a button. No illustration. */
.empty { padding: var(--sp-16) 0; border-top: var(--rule-1) solid var(--hairline); max-width: var(--measure-text); }
.empty p { margin-bottom: var(--sp-12); }
.empty-title { font-size: var(--type-heading); font-weight: var(--semibold); line-height: var(--leading-heading); }
.empty .button { margin-top: var(--sp-4); }
.empty .actions { margin: var(--sp-4) 0 0; }
.empty .actions .button { margin-top: 0; }

/* Forms. One column, left aligned, the width of a field group. Controls
   are bordered in ink on paper. */
.form { max-width: var(--measure-form); }
.field { display: block; margin: 0 0 var(--sp-16); }
.field-label { display: block; font-size: var(--type-secondary); font-weight: var(--medium); color: var(--steel); margin-bottom: var(--sp-4); }
.field-label .optional { font-weight: var(--regular); }
.field-help { display: block; font-size: var(--type-caption); color: var(--steel); margin-top: var(--sp-4); }
.field-error { display: block; font-size: var(--type-secondary); font-weight: var(--medium); color: var(--ink); margin-top: var(--sp-4); padding-top: var(--sp-4); border-top: var(--rule-1) solid var(--hairline); }
.field.has-error .control { border-width: var(--rule-2); }
.control {
  display: block; width: 100%; min-height: var(--tap);
  padding: var(--sp-8) var(--sp-12);
  font: inherit; font-size: var(--type-body); color: var(--ink);
  background: var(--paper); border: var(--rule-1) solid var(--ink); border-radius: var(--radius);
}
.control::placeholder { color: var(--steel); opacity: 1; }
.control:disabled { color: var(--steel); background: var(--shelf); border-color: var(--hairline); }
select.control { padding-right: var(--sp-24); }
textarea.control { min-height: calc(var(--tap) * 2); resize: vertical; }
.field-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: 0 var(--sp-12); }
.check { display: flex; align-items: center; gap: var(--sp-8); min-height: var(--tap); cursor: pointer; }
.check input { width: 1.5rem; height: 1.5rem; margin: 0; accent-color: var(--ink); }
.check-group { margin: 0 0 var(--sp-12); }
.disclosure { margin: 0 0 var(--sp-16); border-top: var(--rule-1) solid var(--hairline); }
.disclosure > summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: var(--sp-8); min-height: var(--tap); font-weight: var(--medium); }
.disclosure > summary::-webkit-details-marker { display: none; }
.disclosure > summary::before { content: "+"; display: inline-block; width: 1em; text-align: center; color: var(--steel); }
.disclosure[open] > summary::before { content: "\2212"; }
.disclosure-body { padding: var(--sp-8) 0 var(--sp-4); }
.actions { display: flex; flex-wrap: wrap; gap: var(--sp-8) var(--sp-12); align-items: center; margin: var(--sp-24) 0 0; }
.actions form { margin: 0; }
/* The actions that close a record: over a 2px ink rule at the foot of the screen. */
.actions-foot { margin-top: var(--sp-32); padding-top: var(--sp-24); border-top: var(--rule-2) solid var(--ink); }

/* The search: one wide control and its button, side by side, under a
   headline; the one place a control stands taller than the tap height. */
.search { display: flex; flex-wrap: wrap; align-items: stretch; gap: var(--sp-12); max-width: var(--measure-text); margin: var(--sp-16) 0 0; }
.search .field { flex: 1 1 16rem; margin: 0; }
.search .control { min-height: 3rem; }
.search .button { flex: 0 0 auto; min-height: 3rem; }
.search-hint { margin: var(--sp-8) 0 0; font-size: var(--type-caption); color: var(--steel); }

/* Buttons. The primary is solid ink with paper text; the secondary is ink
   on paper with an ink border. Both keep their name through a flow. */
.button {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-8);
  min-height: var(--tap); padding: var(--sp-8) var(--sp-16);
  font: inherit; font-size: var(--type-body); font-weight: var(--medium); line-height: var(--leading-heading); text-decoration: none; text-align: center;
  color: var(--ink); background: var(--paper);
  border: var(--rule-1) solid var(--ink); border-radius: var(--radius);
  cursor: pointer;
}
.button-primary { color: var(--paper); background: var(--ink); border-color: var(--ink); }
.button-secondary:hover, .button-danger:hover { background: var(--shelf); }
.button:disabled, .button[aria-disabled="true"] { color: var(--steel); background: var(--shelf); border-color: var(--hairline); cursor: not-allowed; }
.button-block { display: flex; width: 100%; }
.button-small { padding: var(--sp-4) var(--sp-12); font-size: var(--type-secondary); }
summary.button { list-style: none; }
summary.button::-webkit-details-marker { display: none; }

/* Confirmation for a destructive action: opens in place, asks in words,
   repeats the verb on the confirming control, which is the panel's primary. */
.confirm { display: inline-block; }
.confirm-panel { margin-top: var(--sp-8); padding: var(--sp-12) 0; border-top: var(--rule-1) solid var(--hairline); border-bottom: var(--rule-1) solid var(--hairline); max-width: var(--measure-text); }
.confirm-panel p { margin-bottom: var(--sp-12); }
.confirm-panel .actions { margin-top: 0; }
.confirm-panel .button-danger, .confirm-panel .button-primary { color: var(--paper); background: var(--ink); border-color: var(--ink); }
.confirm[open] > summary.button { background: var(--shelf); }
td .confirm-panel { min-width: 16rem; white-space: normal; }

/* Pagination. */
.pagination { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-8) var(--sp-16); margin: var(--sp-12) 0 0; font-size: var(--type-secondary); }
.pagination-range { color: var(--steel); }

/* Filter bar: a row of fields above a table, closed by a rule. */
.filters { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--sp-8) var(--sp-12); padding: 0 0 var(--sp-16); margin: 0 0 var(--sp-16); border-bottom: var(--rule-1) solid var(--hairline); }
.filters .field { margin: 0; flex: 1 1 12rem; max-width: var(--measure-form); }
.filters .actions { margin: 0; }

/* Detail panel: one record's full state, as a ruled list. */
.detail { margin: 0 0 var(--sp-24); }
.detail-title { margin: 0; padding: 0 0 var(--sp-8); font-size: var(--type-heading); font-weight: var(--semibold); border-bottom: var(--rule-1) solid var(--hairline); }
.detail dl { display: grid; grid-template-columns: minmax(8rem, 14rem) minmax(0, 1fr); margin: 0; }
.detail dt { padding: var(--sp-8) var(--sp-12) var(--sp-8) 0; color: var(--steel); font-size: var(--type-secondary); font-weight: var(--medium); border-bottom: var(--rule-1) solid var(--hairline); }
.detail dd { margin: 0; padding: var(--sp-8) 0; border-bottom: var(--rule-1) solid var(--hairline); min-width: 0; overflow-wrap: anywhere; }
.detail-lead { font-size: var(--type-heading); font-weight: var(--medium); }
@media (max-width: 44.9375rem) {
  .detail dl { grid-template-columns: 1fr; }
  .detail dt { padding-bottom: 0; border-bottom: 0; }
}

/* The hero of a record: the tag, the name at headline size, one line of
   what it is; beside it the status, stated in words at its left rule.
   Closed by a 2px ink rule. */
.hero { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--sp-24) var(--sp-48); padding: var(--sp-32) var(--sp-32) var(--sp-24); border-bottom: var(--rule-2) solid var(--ink); }
.hero-text { flex: 1 1 24rem; min-width: 0; }
.hero-tag { display: block; margin-bottom: var(--sp-8); font-size: var(--type-secondary); color: var(--steel); }
.hero-title { margin: 0; font-size: var(--type-headline); font-weight: var(--semibold); line-height: var(--leading-heading); }
.hero-sub { margin: var(--sp-8) 0 0; font-size: var(--type-body); color: var(--steel); }
.status { flex: 0 1 20rem; min-width: 0; padding-left: var(--sp-24); border-left: var(--rule-2) solid var(--ink); }
.status-label { display: block; font-size: var(--type-caption); color: var(--steel); }
.status-value { display: block; margin-top: var(--sp-4); font-size: var(--type-headline); font-weight: var(--semibold); line-height: var(--leading-heading); }
.status-note { margin: var(--sp-8) 0 0; font-size: var(--type-secondary); max-width: none; }
@media (max-width: 44.9375rem) {
  .hero { padding: var(--sp-16); gap: var(--sp-16); }
  .hero-title { font-size: var(--type-title); }
  .status { flex: 1 1 100%; padding-left: var(--sp-16); }
  .status-value { font-size: var(--type-title); }
}

/* Facts: a row of cells parted by hairlines, each a label over a value
   over a note. The leading facts of a record: where, how old, when. */
.facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); margin: 0 0 var(--sp-24); border-bottom: var(--rule-1) solid var(--hairline); }
.fact { min-width: 0; padding: var(--sp-24) var(--sp-24) var(--sp-24) 0; border-right: var(--rule-1) solid var(--hairline); }
.fact + .fact { padding-left: var(--sp-24); }
.fact:last-child { border-right: 0; }
.fact-label { display: block; margin-bottom: var(--sp-8); font-size: var(--type-caption); color: var(--steel); }
.fact-value { display: block; font-size: var(--type-heading); font-weight: var(--medium); line-height: var(--leading-heading); overflow-wrap: anywhere; }
.fact-note { display: block; margin-top: var(--sp-4); font-size: var(--type-secondary); color: var(--steel); }
@media (max-width: 44.9375rem) {
  .facts { grid-template-columns: 1fr; }
  .fact { padding: var(--sp-16) 0; border-right: 0; border-bottom: var(--rule-1) solid var(--hairline); }
  .fact + .fact { padding-left: 0; }
  .fact:last-child { border-bottom: 0; }
}

/* A state stated in words. The level adds weight, never a colour: good and
   warn are medium, bad is semibold, quiet is steel at regular. A missing
   tool (state-missing) is the one exception, in signal.css. */
.state { font-weight: var(--medium); }
.state-bad { font-weight: var(--semibold); }
.state-quiet { color: var(--steel); font-weight: var(--regular); }

/* A machine identifier read character by character, set large: a pairing
   code, a tag as it is printed on a label. Left aligned between two rules. */
.number-big { font-family: var(--mono); font-weight: var(--regular); font-size: var(--type-title); }
.code-block { padding: var(--sp-24) 0; margin: 0 0 var(--sp-16); border-top: var(--rule-1) solid var(--hairline); border-bottom: var(--rule-1) solid var(--hairline); max-width: var(--measure-text); }
.code-block .number-big { display: block; }
.qr { display: block; margin: var(--sp-16) 0; max-width: 18rem; }

/* Panel: a group of controls or a summary, between two rules. */
.panel { padding: var(--sp-16) 0; margin: 0 0 var(--sp-16); border-top: var(--rule-1) solid var(--hairline); border-bottom: var(--rule-1) solid var(--hairline); }
.panel > h2:first-child, .panel > h3:first-child { margin-top: 0; }
.panel-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap: var(--sp-16); }

/* Sign-in: a left-aligned column the width of a field group. Not a card.
   The field group opens under a 2px ink rule; the primary action is the
   column's full width; the one note about accounts and resets stands
   off from it under a hairline. */
.signin { max-width: var(--measure-form); }
.signin .form { padding-top: var(--sp-24); border-top: var(--rule-2) solid var(--ink); }
.signin .actions { margin-top: var(--sp-8); }
.signin .note { margin: var(--sp-24) 0 0; padding-top: var(--sp-24); border-top: var(--rule-1) solid var(--hairline); font-size: var(--type-secondary); }

/* Launcher: the applications a person can use, as a ruled list. */
.launcher { list-style: none; margin: 0 0 var(--sp-16); padding: 0; max-width: var(--measure-text); border-top: var(--rule-1) solid var(--hairline); }
.launcher li { border-bottom: var(--rule-1) solid var(--hairline); }
.launcher-app { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-12); min-height: var(--tap); padding: var(--sp-12) 0; text-decoration: none; color: var(--ink); font-weight: var(--medium); }
a.launcher-app:hover { background: var(--shelf); }
.launcher-app.is-unavailable { color: var(--steel); font-weight: var(--regular); }
.launcher-go { font-weight: var(--semibold); text-decoration: underline; }
