/*
 * THE ONLY STYLESHEET.
 *
 * Derived from Mitigate's frontend/src/styles.css and governed by
 * docs/BRANDBOOK.md in THIS repository — which is Mitigate's brandbook with
 * two deliberate deviations written down in it:
 *
 *   1. There is no violet. In Mitigate `--ai` means "a model produced
 *      this". Nothing in this product is model-produced, so a violet here
 *      would mean nothing, and a colour that means nothing in one product
 *      and something precise in another teaches people it is decoration.
 *      There is no `--ai`, `--ai-dim`, `--ai-line` or `.pill-ai` below and
 *      none may be added.
 *
 *   2. The density is looser. Mitigate is an instrument for somebody
 *      handling other people's worst week. This is a tool a salesperson
 *      uses on a Tuesday: same palette, same surfaces, same restraint,
 *      more air and bigger targets. Body text is 15px, every control is at
 *      least 44px tall, and a screen holds fewer things at once.
 *
 * There is no build step. This file is served as-is, with a hash in its
 * URL, under a Content-Security-Policy that has no `unsafe-inline`. No
 * component may carry a `style=` attribute and no page may carry a
 * `<style>` block, which is why everything a screen needs is here.
 *
 * Raw hex or rgba() below the :root block is a bug.
 */

/* ------------------------------------------------------------------ */
/* 1. Tokens                                                           */
/* ------------------------------------------------------------------ */

:root {
  color-scheme: dark;

  /* Canvas. Deep desaturated navy, never #000: glass needs something with
     colour under it to refract, or a translucent panel reads as grey. */
  --bg-deep: #050810;
  --bg-mid: #080d1a;

  /* Glass, three depths and no fourth. If a fourth is needed the layout
     is too deep. */
  --glass-1: rgba(148, 176, 226, 0.045);
  --glass-2: rgba(148, 176, 226, 0.075);
  --glass-3: rgba(148, 176, 226, 0.11);
  --glass-solid: rgba(9, 14, 26, 0.9);
  --glass-solid-deep: rgba(6, 10, 20, 0.96);

  /* Hairlines. */
  --line: rgba(148, 176, 226, 0.14);
  --line-soft: rgba(148, 176, 226, 0.08);
  --line-strong: rgba(148, 176, 226, 0.22);
  --line-lit: rgba(186, 210, 248, 0.26);

  /* Accent. Cyan is the product and every human action in it. */
  --accent: #38bdf8;
  --accent-bright: #7dd3fc;
  --accent-dim: rgba(56, 189, 248, 0.13);
  --accent-line: rgba(56, 189, 248, 0.34);
  --accent-glow: rgba(56, 189, 248, 0.55);

  /* Semantic tones, each with a fill and a border. */
  --ok: #4ade80;
  --ok-dim: rgba(74, 222, 128, 0.13);
  --ok-line: rgba(74, 222, 128, 0.32);
  --warn: #fbbf24;
  --warn-dim: rgba(251, 191, 36, 0.13);
  --warn-line: rgba(251, 191, 36, 0.32);
  --bad: #f87171;
  --bad-dim: rgba(248, 113, 113, 0.13);
  --bad-line: rgba(248, 113, 113, 0.32);

  /* Text. --fg-3 is labels and meta only, never body copy: it does not
     hold 4.5:1 against glass. */
  --fg: #e8eefb;
  --fg-2: #97a6c2;
  --fg-3: #64748b;

  /* Spacing. 4px base. Proximity carries meaning: the outer gap is
     smaller than the inner gap, at every level. */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 40px;

  /* Radii. A nested surface takes a smaller radius than the one holding
     it: --r-lg panel, --r-md card inside it, --r-sm control inside that. */
  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 20px;

  --blur: blur(14px);

  /* The looser density of this product, as numbers rather than as an
     instinct. See docs/BRANDBOOK.md §1a. */
  --control-height: 44px;
  --page-width: 1120px;
  --reading-width: 62ch;

  --font-sans: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono: "SF Mono", "JetBrains Mono", ui-monospace, "Cascadia Mono", Menlo, Consolas, monospace;
}

/* ------------------------------------------------------------------ */
/* 2. Canvas                                                           */
/* ------------------------------------------------------------------ */

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

html {
  background: var(--bg-deep);
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 400;
  line-height: 1.6;
  color: var(--fg);
  background-color: var(--bg-deep);
  /*
   * Two very large, very soft pools behind everything. In Mitigate one is
   * cyan and the other violet; with violet gone the second pool is a cool
   * slate, so the field still has depth without a hue that means
   * something elsewhere. This is most of what separates "instrument" from
   * "dark web page", and it costs no animation.
   */
  background-image:
    radial-gradient(1100px 700px at 12% -8%, rgba(56, 189, 248, 0.1), transparent 62%),
    radial-gradient(1000px 640px at 92% -12%, rgba(148, 176, 226, 0.07), transparent 60%),
    linear-gradient(180deg, var(--bg-mid), var(--bg-deep) 46%);
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
}

/* The grid. You do not consciously see it, and that is the point. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: 0.03;
  background-image:
    linear-gradient(var(--line-lit) 1px, transparent 1px),
    linear-gradient(90deg, var(--line-lit) 1px, transparent 1px);
  background-size: 56px 56px;
  -webkit-mask-image: linear-gradient(180deg, #000, transparent 70%);
  mask-image: linear-gradient(180deg, #000, transparent 70%);
}

/* ------------------------------------------------------------------ */
/* 3. Typography                                                       */
/* ------------------------------------------------------------------ */

/*
 * TWO WEIGHTS ONLY: 400 AND 500. Anything above 500 anywhere in this file
 * is a bug. Hierarchy is carried by size, colour and space.
 */

h1,
h2,
h3 {
  margin: 0;
  font-weight: 500;
  letter-spacing: -0.015em;
}

.page-title {
  font-size: 34px;
  letter-spacing: -0.028em;
  line-height: 1.2;
}

.page-lede {
  margin: var(--space-3) 0 0;
  max-width: var(--reading-width);
  color: var(--fg-2);
  font-size: 15px;
}

.card-title {
  font-size: 18px;
}

.section-title {
  font-size: 20px;
  letter-spacing: -0.02em;
}

.eyebrow {
  margin: 0 0 var(--space-2);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
}

.meta {
  color: var(--fg-3);
  font-size: 12.5px;
}

.secondary-text {
  color: var(--fg-2);
  font-size: 13.5px;
}

p {
  margin: 0 0 var(--space-3);
  max-width: var(--reading-width);
}

p:last-child {
  margin-bottom: 0;
}

a {
  color: var(--accent-bright);
  text-decoration-color: var(--accent-line);
  text-underline-offset: 3px;
}

a:hover {
  text-decoration-color: var(--accent);
}

/* ------------------------------------------------------------------ */
/* 4. Numerals                                                         */
/* ------------------------------------------------------------------ */

/*
 * EVERY NUMBER A PERSON READS AS A QUANTITY IS MONO, AND EVERY AMOUNT OF
 * MONEY IS A QUANTITY. A wallet balance is a readout, exactly like a stat
 * card in Mitigate: it is the number the whole screen exists to report.
 */

.readout,
.money,
.numeral {
  font-family: var(--font-mono);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.readout {
  display: block;
  font-size: 40px;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--fg);
  text-shadow: 0 0 26px var(--accent-glow);
}

.readout-xl {
  font-size: 64px;
}

.readout-quiet {
  text-shadow: none;
  color: var(--fg-2);
}

.money,
.numeral {
  font-size: 14px;
  color: var(--fg);
}

/* ------------------------------------------------------------------ */
/* 5. Page frame                                                       */
/* ------------------------------------------------------------------ */

.skip-link {
  position: absolute;
  left: var(--space-4);
  top: -60px;
  z-index: 20;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--r-sm);
  background: var(--glass-solid-deep);
  border: 1px solid var(--accent-line);
  color: var(--fg);
  text-decoration: none;
  transition: top 140ms ease;
}

.skip-link:focus-visible {
  top: var(--space-4);
}

.site-header {
  position: relative;
  z-index: 1;
  border-bottom: 1px solid var(--line-soft);
  background: rgba(6, 10, 20, 0.6);
  backdrop-filter: var(--blur);
}

.site-header-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  max-width: var(--page-width);
  margin: 0 auto;
  padding: var(--space-3) var(--space-5);
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--fg);
  text-decoration: none;
  font-size: 15px;
}

.brand-mark {
  display: block;
  width: 26px;
  height: 26px;
}

/*
 * THE WORDMARK ON A SCREEN NOBODY IS SIGNED IN TO.
 *
 * `.brand` is drawn on an <a> when there is a wallet to go back to and on a
 * <span> when there is not — see `wordmark` in views/layout.js. The span
 * needs the same type and the same colour, which it already has, and it
 * must not read as a control: no underline on hover, no pointer.
 *
 * The signed-out header has no navigation between the wordmark and the
 * controls, so `margin-left: auto` on `.site-nav` is not there to push them
 * right. `.site-header-controls` carries it instead, on both headers, which
 * is also what keeps the sign-out in the same place whether or not a
 * language switcher sits beside it.
 */
span.brand {
  cursor: default;
}

.site-header-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  /*
   * BRANDBOOK §4: the outer gap is smaller than the inner one. These are
   * two separate controls that happen to sit together, so the space between
   * them is wider than the space between the three languages inside the
   * switcher — which is what keeps "Español" and "Sign out" from reading as
   * one row of four choices.
   */
  gap: var(--space-4);
  margin-left: auto;
}

/*
 * THE LANGUAGE SWITCHER. A form, three submit buttons, no links.
 *
 * A GET must not change state, so this cannot be three anchors — which is
 * what it was, pointing at a `?lang=` nothing read. See
 * `languageSwitcher` in views/layout.js.
 *
 * The buttons are dressed as the navigation's own pills rather than as
 * buttons, because that is what they are: three ways to say where you are,
 * one of them current. `--space-1` inside against `--space-4` outside is
 * the grouping rule again.
 *
 * ======================================================================
 * THEY RENDERED AS UNSTYLED GREY BOXES, AND `appearance` IS WHY.
 * ======================================================================
 *
 * The product owner opened the portal and found three grey system buttons
 * where three pills should be. §7 of the brandbook warns about exactly this
 * shape of defect — a control that misses its rule "renders as an unstyled
 * grey box. It looks disabled, which is worse than looking wrong" — and the
 * rule was not missing. It was landing and losing.
 *
 * A `<button>` carries `appearance: auto`, which is the browser's own
 * widget. `background: none` is the `background` SHORTHAND: it sets
 * `background-image: none` and resets the other background properties to
 * their initial values, and on a control still painting native chrome that
 * chrome is drawn by the widget rather than by `background-color` — so the
 * grey survives, the border survives, and the padding is the platform's.
 * The `<a class="nav-link">` beside it has no widget, which is why the
 * navigation looked right and the switcher did not.
 *
 * So `appearance: none` first, with the `-webkit-` spelling for the engines
 * that still want it, and then every property this control needs written out
 * rather than assumed: a form control does not inherit `font`, `color`,
 * `line-height` or `letter-spacing` from the page. `background-color`
 * explicitly rather than through the shorthand, so a reader can see that the
 * transparency is deliberate.
 *
 * `margin: 0` on the form for the same class of reason: `<form>` carries a
 * bottom margin in more than one user-agent stylesheet, which is what put
 * the switcher out of line with the sign-out beside it.
 */
.lang-switch {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
  margin: 0;
}

.lang-option {
  -webkit-appearance: none;
  appearance: none;
  display: inline-flex;
  align-items: center;
  min-height: 38px;
  padding: 0 var(--space-3);
  border-radius: 999px;
  border: 1px solid transparent;
  background-color: transparent;
  background-image: none;
  box-shadow: none;
  color: var(--fg-3);
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: inherit;
  text-align: center;
  cursor: pointer;
}

.lang-option:hover {
  background-color: var(--glass-2);
  color: var(--fg);
}

/*
 * NEVER COLOUR ALONE (BRANDBOOK §11). The fill says which language is
 * current to somebody who can see it; `aria-current="true"` on the same
 * button says it to everybody else, and the word on the button says which
 * language it is in the language it names.
 */
.lang-option[aria-current="true"] {
  border-color: var(--accent-line);
  background-color: var(--accent-dim);
  color: var(--accent-bright);
}

.site-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-left: auto;
}

.nav-link {
  display: inline-flex;
  align-items: center;
  min-height: 38px;
  padding: 0 var(--space-3);
  border-radius: 999px;
  border: 1px solid transparent;
  color: var(--fg-2);
  font-size: 14px;
  text-decoration: none;
}

.nav-link:hover {
  background: var(--glass-2);
  color: var(--fg);
}

.nav-link[aria-current="page"] {
  border-color: var(--accent-line);
  background: var(--accent-dim);
  color: var(--accent-bright);
}

.site-main {
  position: relative;
  z-index: 1;
  max-width: var(--page-width);
  margin: 0 auto;
  padding: var(--space-6) var(--space-5) 80px;
}

/*
 * `.site-footer` IS GONE. It had one caller — the language switcher
 * stranded at the bottom of the sign-in screen — and that control is in the
 * header now, on every screen. `page()` in views/layout.js no longer takes
 * a footer at all, so a rule for one would be a place for the next thing
 * that belongs in the chrome to end up instead.
 */

/* A single-card page: sign in, 2FA, accepting an invite, confirming
   something that cannot be undone. One question, centred, more air. */
.narrow-main {
  max-width: 520px;
  padding-top: 72px;
}

/* ------------------------------------------------------------------ */
/* 6. Surfaces                                                         */
/* ------------------------------------------------------------------ */

/*
 * ONE PRIMITIVE. Translucent wash, 1px hairline, and a 1px lit top edge
 * brighter than the border that fades out at both ends. The lit edge is
 * most of what makes it read as glass rather than a box with a border.
 */

.glass {
  position: relative;
  border: 1px solid var(--line);
  background: var(--glass-1);
  border-radius: var(--r-md);
  backdrop-filter: var(--blur);
}

.glass::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  border-radius: inherit;
  background: linear-gradient(90deg, transparent, var(--line-lit) 22%, var(--line-lit) 78%, transparent);
  pointer-events: none;
}

.panel {
  border-radius: var(--r-lg);
  padding: var(--space-5);
}

.card {
  padding: var(--space-4);
}

.card-header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.nested {
  background: var(--glass-2);
  border-radius: var(--r-sm);
}

/* Sections and the gaps between them. Each level is looser than the one
   inside it: --space-3 between rows, --space-5 between cards, --space-6
   between sections. */
.section {
  margin-top: var(--space-6);
}

.section:first-child {
  margin-top: 0;
}

.section-header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.card-grid {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}

.stack {
  display: grid;
  gap: var(--space-5);
}

.stack-tight {
  display: grid;
  gap: var(--space-3);
}

.page-header {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-5);
  margin-bottom: var(--space-6);
}

.page-header-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

/* ------------------------------------------------------------------ */
/* 7. Readout cards                                                    */
/* ------------------------------------------------------------------ */

.stat {
  padding: var(--space-5);
}

.stat-label {
  display: block;
  margin-bottom: var(--space-2);
  color: var(--fg-3);
  font-size: 12.5px;
}

.stat-hint {
  display: block;
  margin-top: var(--space-2);
  color: var(--fg-2);
  font-size: 13.5px;
}

.stat-wide {
  grid-column: 1 / -1;
}

/* ------------------------------------------------------------------ */
/* 8. Buttons — three levels, and only three                           */
/* ------------------------------------------------------------------ */

/*
 * AT MOST ONE PRIMARY PER VIEW. If two actions look primary, neither
 * reads as the obvious next step. A test in views.test.js counts them.
 *
 * Use the exact class names. A <button> with no class renders as an
 * unstyled grey box, which looks disabled — worse than looking wrong.
 */

.primary-button,
.secondary-button,
.danger-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--control-height);
  padding: 0 var(--space-5);
  border-radius: var(--r-sm);
  font-family: inherit;
  font-size: 15px;
  font-weight: 500;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: background 140ms ease, border-color 140ms ease, box-shadow 140ms ease;
}

.primary-button {
  border: 1px solid var(--accent-line);
  background: linear-gradient(180deg, rgba(56, 189, 248, 0.28), rgba(56, 189, 248, 0.14));
  color: var(--fg);
  /* The shadow is the accent colour rather than black. That is what makes
     it glow rather than just sit there. */
  box-shadow: 0 8px 26px -14px var(--accent-glow);
}

.primary-button:hover {
  background: linear-gradient(180deg, rgba(56, 189, 248, 0.36), rgba(56, 189, 248, 0.18));
  border-color: var(--accent);
}

.secondary-button {
  border: 1px solid var(--line);
  background: var(--glass-2);
  color: var(--fg);
}

.secondary-button:hover {
  background: var(--glass-3);
  border-color: var(--line-strong);
}

.danger-button {
  border: 1px solid var(--bad-line);
  background: var(--bad-dim);
  color: var(--bad);
}

.danger-button:hover {
  border-color: var(--bad);
}

.button-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

/* A call to action sits --space-4 from the text that explains it: close
   enough to belong to it, far enough to read as a control. */
.action-under-text {
  margin-top: var(--space-4);
}

.link-button {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent-bright);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ------------------------------------------------------------------ */
/* 9. Pills                                                            */
/* ------------------------------------------------------------------ */

/*
 * Leading dot in currentColor, then the word. The dot carries the tone so
 * the pill stays legible at 11.5px without going bold. Never colour
 * alone: the word is always there.
 */

.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 4px var(--space-3);
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--glass-2);
  color: var(--fg-2);
  font-size: 11.5px;
  font-weight: 500;
  white-space: nowrap;
}

.pill::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: currentColor;
}

.pill-accent {
  border-color: var(--accent-line);
  background: var(--accent-dim);
  color: var(--accent-bright);
}

.pill-good {
  border-color: var(--ok-line);
  background: var(--ok-dim);
  color: var(--ok);
}

.pill-warn {
  border-color: var(--warn-line);
  background: var(--warn-dim);
  color: var(--warn);
}

.pill-bad {
  border-color: var(--bad-line);
  background: var(--bad-dim);
  color: var(--bad);
}

/* Filter pills are links, because there is no client-side JavaScript in
   this product. The current one is marked with aria-current, not by
   colour alone. */
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  /* Larger above than below: the bar and the rows it filters are one
     group, and the group above is a different one. */
  margin: var(--space-6) 0 var(--space-5);
  padding-left: var(--space-3);
  border-left: 1px solid transparent;
}

.filter-bar-filtered {
  border-left-color: var(--accent-line);
}

.filter-pill {
  text-decoration: none;
  min-height: 36px;
  padding: 0 var(--space-4);
}

.filter-pill[aria-current="true"] {
  border-color: var(--accent-line);
  background: var(--accent-dim);
  color: var(--accent-bright);
}

.filter-count {
  font-family: var(--font-mono);
  font-size: 11px;
  color: inherit;
  opacity: 0.75;
}

/* ------------------------------------------------------------------ */
/* 10. Tables                                                          */
/* ------------------------------------------------------------------ */

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

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

caption {
  text-align: left;
  color: var(--fg-3);
  font-size: 12.5px;
  padding-bottom: var(--space-3);
}

th {
  text-align: left;
  font-weight: 500;
  font-size: 12.5px;
  color: var(--fg-3);
  padding: 0 var(--space-4) var(--space-3) 0;
  border-bottom: 1px solid var(--line-soft);
  white-space: nowrap;
}

td {
  padding: var(--space-4) var(--space-4) var(--space-4) 0;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: top;
  color: var(--fg);
}

tbody tr:last-child td {
  border-bottom: 0;
}

th:last-child,
td:last-child {
  padding-right: 0;
}

.numeric {
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

th.numeric {
  text-align: right;
}

.cell-strong {
  color: var(--fg);
}

.cell-sub {
  display: block;
  margin-top: var(--space-1);
  color: var(--fg-3);
  font-size: 12.5px;
}

/* ------------------------------------------------------------------ */
/* 11. Definition lists                                                */
/* ------------------------------------------------------------------ */

.facts {
  display: grid;
  grid-template-columns: minmax(140px, auto) 1fr;
  gap: var(--space-3) var(--space-5);
  margin: 0;
}

.facts dt {
  color: var(--fg-3);
  font-size: 12.5px;
}

.facts dd {
  margin: 0;
  color: var(--fg);
}

/* ------------------------------------------------------------------ */
/* 12. Forms                                                           */
/* ------------------------------------------------------------------ */

.field {
  display: block;
  margin-bottom: var(--space-5);
}

.field:last-child {
  margin-bottom: 0;
}

.field-label {
  display: block;
  margin-bottom: var(--space-2);
  font-size: 13.5px;
  color: var(--fg);
}

.field-hint {
  display: block;
  margin-top: var(--space-2);
  color: var(--fg-2);
  font-size: 13px;
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="number"],
input[type="search"],
input[type="date"],
select,
textarea {
  display: block;
  width: 100%;
  min-height: var(--control-height);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--glass-2);
  color: var(--fg);
  font-family: inherit;
  font-size: 15px;
}

input[type="number"],
input[inputmode="numeric"] {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

textarea {
  min-height: 96px;
  resize: vertical;
  line-height: 1.5;
}

::placeholder {
  color: var(--fg-3);
}

input:focus-visible,
select:focus-visible,
textarea:focus-visible,
a:focus-visible,
button:focus-visible,
summary:focus-visible {
  outline: none;
  border-color: var(--accent-line);
  box-shadow: 0 0 0 3px var(--accent-dim);
}

a:focus-visible,
button:focus-visible {
  border-radius: var(--r-sm);
}

/*
 * THE OPEN HALF OF A SELECT IS NOT OURS.
 *
 * The list a <select> opens is drawn by the operating system and inherits
 * nothing. `color-scheme: dark` alone is not enough — the popup comes up
 * white with our near-white text on it. The background must be OPAQUE:
 * a 90% surface composites against the system's white popup rather than
 * against our canvas, which is how this looks nearly right and stays
 * unreadable. Written on the elements, not on a class, so it covers every
 * select including ones nobody has added yet.
 */
select option,
select optgroup {
  background-color: var(--bg-mid);
  color: var(--fg);
}

select option:disabled {
  color: var(--fg-3);
}

fieldset {
  margin: 0 0 var(--space-5);
  padding: 0;
  border: 0;
}

legend {
  padding: 0;
  margin-bottom: var(--space-3);
  font-size: 13.5px;
  color: var(--fg);
}

.choice-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

.choice {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--control-height);
  padding: 0 var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--glass-2);
  font-size: 14px;
  cursor: pointer;
}

.choice input {
  accent-color: var(--accent);
  width: 16px;
  height: 16px;
}

.form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--line-soft);
}

.inline-form {
  display: inline;
}

/* ------------------------------------------------------------------ */
/* 13. Notices                                                         */
/* ------------------------------------------------------------------ */

/*
 * A refusal belongs beside the thing it refuses and stays until it is
 * fixed. There are no toasts in this product: a toast reports that
 * something happened somewhere else and then leaves, and every action
 * here is a form post that renders its own answer.
 *
 * An empty notice is not a notice. The element is in the DOM from the
 * first paint on some screens and filled in only when something is wrong;
 * :empty keeps it from painting a coloured bar over a page where nothing
 * has happened yet.
 */

.notice {
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: var(--glass-2);
  padding: var(--space-4);
  margin-bottom: var(--space-5);
  color: var(--fg);
  font-size: 14px;
}

.notice:empty {
  display: none;
}

.notice-title {
  display: block;
  margin-bottom: var(--space-2);
  font-weight: 500;
}

.notice-bad {
  border-color: var(--bad-line);
  background: var(--bad-dim);
}

.notice-warn {
  border-color: var(--warn-line);
  background: var(--warn-dim);
}

.notice-good {
  border-color: var(--ok-line);
  background: var(--ok-dim);
}

.notice-accent {
  border-color: var(--accent-line);
  background: var(--accent-dim);
}

/* ------------------------------------------------------------------ */
/* 14. Empty states                                                    */
/* ------------------------------------------------------------------ */

/* An invitation, not an apology. */
.empty-state {
  padding: var(--space-6) var(--space-5);
  text-align: left;
}

.empty-state-title {
  font-size: 18px;
  font-weight: 500;
  margin-bottom: var(--space-3);
}

.empty-state-body {
  color: var(--fg-2);
  max-width: var(--reading-width);
}

/* ------------------------------------------------------------------ */
/* 15. The confirm page                                                */
/* ------------------------------------------------------------------ */

/*
 * THIS PRODUCT HAS NO MODALS, AND THE REASON IS IN THE BRANDBOOK.
 *
 * A modal needs script to open, to close on Escape and to close on a
 * backdrop click, and this product ships no client-side JavaScript. A
 * modal you cannot leave with Escape is worse than no modal. So anything
 * that would be a dialog is its own page, dressed the way §7 dresses a
 * dialog: opaque surface, lit edge, footer rule, confirming action last
 * on the right, the quiet way out to its left. The way out is a real
 * link, and the browser's Back button is the second one.
 */

.confirm-panel {
  background: var(--glass-solid-deep);
  border-radius: var(--r-lg);
  padding: var(--space-5);
}

.confirm-footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--line-soft);
}

/* Cancel sits to the left of the confirming action and is visually quiet.
   Saying no must be as cheap as saying yes. */
.confirm-footer .secondary-button {
  margin-right: auto;
}

/* ------------------------------------------------------------------ */
/* 16. Utilities                                                       */
/* ------------------------------------------------------------------ */

.visually-hidden {
  /* The clip pattern, never display:none — an element hidden with
     display:none leaves the tab order and the accessibility tree. */
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

[hidden] {
  display: none !important;
}

.divider {
  height: 1px;
  margin: var(--space-5) 0;
  background: var(--line-soft);
  border: 0;
}

.wrap-anywhere {
  overflow-wrap: anywhere;
}

@media (max-width: 720px) {
  .site-main {
    padding: var(--space-5) var(--space-4) 64px;
  }

  .site-header-inner {
    padding: var(--space-3) var(--space-4);
  }

  .readout {
    font-size: 34px;
  }

  .readout-xl {
    font-size: 48px;
  }

  .page-title {
    font-size: 28px;
  }

  .facts {
    grid-template-columns: 1fr;
    gap: var(--space-1) 0;
  }

  .facts dd {
    margin-bottom: var(--space-3);
  }
}

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

/* ---- The second-factor QR code. views/qr.js. ---- */

/*
 * The symbol paints its own white background and black modules, in both
 * themes, because a QR drawn in theme colours on the dark theme is one many
 * scanners refuse. So this rule sets no colours at all: it only bounds the
 * size and gives the white square enough padding that the quiet zone is not
 * the only separation from a dark page.
 *
 * `height: auto` overrides the height attribute on the element. Without it a
 * narrow screen scales the width and leaves the height, and the symbol is
 * squashed into a rectangle no scanner can read.
 */
.qr {
  display: block;
  width: 100%;
  max-width: 240px;
  height: auto;
  margin: var(--space-3) 0;
  border-radius: 4px;
}
