/* inwx-dns-proxy admin console.
   Direction: Swiss grid discipline with a terminal's respect for machine data.
   Prose is set in a humanist sans; anything a machine produced — addresses,
   FQDNs, credentials, audit lines — is monospace, so the eye can tell what is
   a label from what is a value without reading either. */

:root {
  color-scheme: light dark;

  --paper: oklch(98.4% 0.004 85);
  --paper-raised: oklch(100% 0 0);
  --paper-sunken: oklch(95.8% 0.006 85);
  --ink: oklch(21% 0.012 265);
  --ink-soft: oklch(46% 0.014 265);
  --ink-faint: oklch(62% 0.012 265);
  --rule: oklch(88% 0.008 265);
  --rule-strong: oklch(78% 0.01 265);

  --accent: oklch(48% 0.16 258);
  --accent-ink: oklch(99% 0 0);
  --accent-soft: oklch(94% 0.04 258);

  --slot: oklch(62% 0.15 72);
  --pending: oklch(54% 0.17 300);
  --active: oklch(52% 0.14 155);
  --revoked: oklch(60% 0.01 265);
  --danger: oklch(52% 0.2 25);
  --danger-soft: oklch(95% 0.03 25);
  --warn-soft: oklch(96% 0.045 85);

  --sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", "Fira Mono", Menlo, Consolas, monospace;

  --text-micro: 0.6875rem;
  --text-small: 0.8125rem;
  --text-base: 0.9375rem;
  --text-lead: clamp(1.05rem, 0.98rem + 0.3vw, 1.25rem);
  --text-section: clamp(1.5rem, 1.2rem + 1.1vw, 2.1rem);
  --text-display: clamp(1.9rem, 1.4rem + 2.2vw, 3rem);

  --space-hair: 0.25rem;
  --space-tight: 0.5rem;
  --space: 1rem;
  --space-wide: 1.75rem;
  --space-section: clamp(2.75rem, 2rem + 3vw, 4.5rem);

  /* One measure and one gutter, shared by the masthead and the content, so the
     rule under the header ends where the content ends instead of running past
     it into the margin. */
  --measure: 1500px;
  --gutter: clamp(1rem, 4vw, 3.5rem);

  --z-masthead: 20;
  --z-hint: 60;

  --radius: 3px;
  --radius-lg: 6px;
  --shadow-raised: 0 1px 2px oklch(20% 0.02 265 / 0.06), 0 8px 24px -12px oklch(20% 0.02 265 / 0.28);
  --duration: 140ms;
  --ease: cubic-bezier(0.2, 0, 0.13, 1);
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper: oklch(17.5% 0.012 265);
    --paper-raised: oklch(21.5% 0.014 265);
    --paper-sunken: oklch(14.5% 0.012 265);
    --ink: oklch(94% 0.006 265);
    --ink-soft: oklch(74% 0.012 265);
    --ink-faint: oklch(58% 0.012 265);
    --rule: oklch(30% 0.014 265);
    --rule-strong: oklch(40% 0.016 265);

    --accent: oklch(72% 0.14 258);
    --accent-ink: oklch(16% 0.02 265);
    --accent-soft: oklch(28% 0.06 258);

    --slot: oklch(76% 0.14 72);
    --pending: oklch(74% 0.14 300);
    --active: oklch(74% 0.14 155);
    --revoked: oklch(58% 0.01 265);
    --danger: oklch(70% 0.17 25);
    --danger-soft: oklch(28% 0.07 25);
    --warn-soft: oklch(28% 0.06 85);

    --shadow-raised: 0 1px 2px oklch(0% 0 0 / 0.4), 0 10px 28px -14px oklch(0% 0 0 / 0.7);
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--text-base);
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
}

a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { text-decoration-thickness: 2px; }

/* ---------- masthead ---------- */

/* It stays put: the audit table at the bottom of the page is long, and the
   refresh state and the manual are the two things you want reachable from
   anywhere in it. Kept to two short rows for that reason — a sticky header that
   eats a third of the viewport is worse than no sticky header. */
.masthead {
  position: sticky;
  top: 0;
  z-index: var(--z-masthead);
  background: var(--paper);
  border-bottom: 1px solid var(--rule-strong);
  box-shadow: 0 1px 0 var(--paper), 0 6px 16px -14px oklch(20% 0.02 265 / 0.5);
}

.masthead__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-tight) var(--space-wide);
  max-width: var(--measure);
  padding: var(--space) var(--gutter) var(--space-tight);
}

.masthead__id {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-tight);
  min-width: 0;
}

.masthead__mark {
  font-family: var(--mono);
  font-size: var(--text-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.masthead__mark::after {
  content: "/";
  margin-left: var(--space-tight);
  color: var(--rule-strong);
}

.masthead h1 {
  margin: 0;
  font-size: clamp(1.2rem, 1.02rem + 0.6vw, 1.7rem);
  font-weight: 620;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.masthead__tools {
  display: flex;
  align-items: center;
  gap: var(--space-tight);
  margin-left: auto;
}

.tool {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  padding: 3px 9px;
  border: 1px solid var(--rule-strong);
  border-radius: 100px;
  background: var(--paper-raised);
  color: var(--ink-soft);
  font-family: var(--mono);
  font-size: var(--text-micro);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: color var(--duration) var(--ease), border-color var(--duration) var(--ease), background var(--duration) var(--ease);
}

.tool:hover { color: var(--ink); border-color: var(--ink-soft); text-decoration: none; }
/* Drawn rather than typed: the obvious ⟳ codepoint is missing from enough font
   stacks to render as a tofu box on a perfectly ordinary machine. */
.tool__glyph { width: 0.95em; height: 0.95em; display: block; }
button.tool:hover .tool__glyph { rotate: 90deg; transition: rotate 240ms var(--ease); }

.tool__state {
  font-family: var(--mono);
  font-size: var(--text-micro);
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  min-width: 7ch;
}

/* The facts strip: configuration you cannot change from here, and counts.
   Deliberately quiet — it is context, not a control. */
.masthead__facts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-hair) var(--space);
  max-width: var(--measure);
  padding: 0 var(--gutter) var(--space-tight);
  font-family: var(--mono);
  font-size: var(--text-micro);
  color: var(--ink-faint);
}

.fact { display: inline-flex; align-items: baseline; gap: 0.45em; }
.fact__key { letter-spacing: 0.1em; text-transform: uppercase; }
.fact b { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }

/* Anchors from the manual must not land under the sticky header. */
.section, .topic-block { scroll-margin-top: 8rem; }

/* ---------- layout ---------- */

main {
  padding: 0 var(--gutter) var(--space-section);
  max-width: var(--measure);
}

.section { padding-top: var(--space-section); }

.section__head {
  display: flex;
  align-items: baseline;
  gap: var(--space);
  padding-bottom: var(--space-tight);
  border-bottom: 1px solid var(--rule-strong);
}

.section__index {
  font-family: var(--mono);
  font-size: var(--text-small);
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}

.section__title {
  margin: 0;
  font-size: var(--text-section);
  font-weight: 600;
  letter-spacing: -0.02em;
}

.section__count {
  margin-left: auto;
  font-family: var(--mono);
  font-size: var(--text-small);
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}

.section__note {
  margin: var(--space-tight) 0 0;
  max-width: 68ch;
  color: var(--ink-soft);
  font-size: var(--text-small);
}

.empty {
  margin: var(--space) 0 0;
  padding: var(--space) 0;
  color: var(--ink-faint);
  font-size: var(--text-small);
  font-style: italic;
}

/* ---------- notices ---------- */

.notice {
  margin-top: var(--space-wide);
  padding: var(--space) var(--space);
  border-left: 3px solid var(--accent);
  background: var(--accent-soft);
  border-radius: 0 var(--radius) var(--radius) 0;
  font-size: var(--text-small);
}

.notice--error { border-left-color: var(--danger); background: var(--danger-soft); }
.notice--warn { border-left-color: var(--slot); background: var(--warn-soft); }
.notice ul { margin: 0; padding-left: 1.1rem; }
.notice li + li { margin-top: var(--space-hair); }

/* ---------- client records ---------- */

.stack { display: grid; gap: var(--space); margin-top: var(--space-wide); }

.record {
  position: relative;
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-left: 4px solid var(--status, var(--rule-strong));
  border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
  padding: var(--space) var(--space-wide) var(--space) var(--space);
  transition: box-shadow var(--duration) var(--ease), border-color var(--duration) var(--ease);
}

.record:hover { box-shadow: var(--shadow-raised); border-color: var(--rule-strong); }
.record--slot { --status: var(--slot); }
.record--pending { --status: var(--pending); }
.record--active { --status: var(--active); }
.record--revoked { --status: var(--revoked); opacity: 0.82; }

.record__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-tight) var(--space);
}

.record__name {
  margin: 0;
  font-family: var(--mono);
  font-size: var(--text-lead);
  font-weight: 600;
  letter-spacing: -0.01em;
  word-break: break-all;
}

.record__status {
  font-family: var(--mono);
  font-size: var(--text-micro);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--status, var(--ink-soft));
}

.record__seen {
  margin-left: auto;
  font-size: var(--text-small);
  color: var(--ink-faint);
}

.badges { display: flex; flex-wrap: wrap; gap: var(--space-hair); margin-top: var(--space-tight); }

.badge {
  font-family: var(--mono);
  font-size: var(--text-micro);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 2px 6px;
  border-radius: var(--radius);
  border: 1px solid currentColor;
  cursor: help;
}

.badge--danger { color: var(--danger); }
.badge--warn { color: var(--slot); }
.badge--info { color: var(--ink-faint); }

/* dense key/value grid for machine data */
.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: var(--space-tight) var(--space);
  margin: var(--space) 0 0;
  padding-top: var(--space);
  border-top: 1px solid var(--rule);
}

.facts > div { min-width: 0; }

.facts dt {
  font-size: var(--text-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.facts dd {
  margin: 2px 0 0;
  font-family: var(--mono);
  font-size: var(--text-small);
  overflow-wrap: anywhere;
}

.facts dd.is-empty { color: var(--ink-faint); font-style: italic; }

.stats {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space);
  margin-top: var(--space);
  padding-top: var(--space-tight);
  border-top: 1px dashed var(--rule);
  font-family: var(--mono);
  font-size: var(--text-micro);
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

.stats b { color: var(--ink); font-weight: 600; }

/* ---------- claims ---------- */

.claims { display: grid; gap: var(--space-tight); margin-top: var(--space-wide); }

.claim {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-tight) var(--space);
  padding: var(--space-tight) var(--space);
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-left: 4px solid var(--pending);
  border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
}

.claim--bind { border-left-color: var(--slot); }
.claim__ip { font-family: var(--mono); font-weight: 600; }
.claim__meta { font-size: var(--text-small); color: var(--ink-soft); }
.claim__actions { margin-left: auto; display: flex; gap: var(--space-tight); }

/* ---------- forms & actions ---------- */

.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-tight);
  margin-top: var(--space);
  padding-top: var(--space-tight);
  border-top: 1px solid var(--rule);
}

.inline-form { display: flex; align-items: center; gap: var(--space-hair); }

button, .button {
  font: inherit;
  font-size: var(--text-small);
  font-weight: 550;
  padding: 0.4rem 0.85rem;
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius);
  background: var(--paper);
  color: var(--ink);
  cursor: pointer;
  transition: background var(--duration) var(--ease), border-color var(--duration) var(--ease),
    color var(--duration) var(--ease), transform var(--duration) var(--ease);
}

button:hover { border-color: var(--ink-soft); background: var(--paper-sunken); }
button:active { transform: translateY(1px); }
button:focus-visible, input:focus-visible, textarea:focus-visible, summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

button.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
button.primary:hover { filter: brightness(1.08); background: var(--accent); }
button.destructive { color: var(--danger); border-color: color-mix(in oklch, var(--danger) 45%, transparent); }
button.destructive:hover { background: var(--danger-soft); border-color: var(--danger); }

input[type="text"], input[type="number"], input[type="password"], textarea {
  font-family: var(--mono);
  font-size: var(--text-small);
  color: var(--ink);
  background: var(--paper-sunken);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius);
  padding: 0.38rem 0.5rem;
  width: 100%;
}

textarea { resize: vertical; min-height: 4.5rem; line-height: 1.45; }

.field { display: grid; gap: var(--space-hair); }
.field > span {
  font-size: var(--text-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.field small { color: var(--ink-faint); font-size: var(--text-micro); }

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

.field--narrow { max-width: 11rem; }

details.panel {
  margin-top: var(--space);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  background: var(--paper-sunken);
}

details.panel > summary {
  cursor: pointer;
  padding: 0.55rem var(--space);
  font-size: var(--text-small);
  font-weight: 550;
  list-style: none;
  display: flex;
  align-items: center;
  gap: var(--space-tight);
}

details.panel > summary::-webkit-details-marker { display: none; }
details.panel > summary::before { content: "+"; font-family: var(--mono); color: var(--accent); }
details.panel[open] > summary::before { content: "−"; }
details.panel > summary:hover { color: var(--accent); }

.panel__body {
  display: grid;
  gap: var(--space);
  padding: 0 var(--space) var(--space);
  border-top: 1px solid var(--rule);
  padding-top: var(--space);
}

details.panel--feature {
  background: var(--paper-raised);
  border-color: var(--rule-strong);
  box-shadow: var(--shadow-raised);
}

/* ---------- credential reveal ---------- */

.reveal {
  max-width: 46rem;
  margin: var(--space-section) auto;
  padding: 0 var(--space);
}

.reveal__card {
  background: var(--paper-raised);
  border: 1px solid var(--rule-strong);
  border-top: 4px solid var(--slot);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-raised);
  padding: var(--space-wide);
}

.reveal h1 { margin: 0 0 var(--space-tight); font-size: var(--text-section); letter-spacing: -0.02em; }
.reveal p { color: var(--ink-soft); margin-top: 0; }

.secret { display: grid; gap: var(--space-hair); margin-top: var(--space); }
.secret__row { display: flex; gap: var(--space-tight); align-items: stretch; }
.secret__row input { font-size: var(--text-base); letter-spacing: 0.01em; }
.secret__row button { white-space: nowrap; }
.copied { color: var(--active); font-size: var(--text-micro); min-height: 1rem; }

/* ---------- audit ---------- */

.audit {
  margin-top: var(--space-wide);
  overflow-x: auto;
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  background: var(--paper-raised);
}

.audit table { border-collapse: collapse; width: 100%; font-family: var(--mono); font-size: var(--text-micro); }
.audit th {
  text-align: left;
  padding: 0.5rem 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  border-bottom: 1px solid var(--rule);
  white-space: nowrap;
  background: var(--paper-sunken);
  position: sticky;
  top: 0;
}
.audit td { padding: 0.4rem 0.7rem; border-bottom: 1px solid var(--rule); vertical-align: top; }
.audit tr:last-child td { border-bottom: none; }
.audit tr:hover td { background: var(--paper-sunken); }
.audit .r-allow { color: var(--active); }
.audit .r-deny { color: var(--danger); }
.audit .r-rate_limited, .audit .r-error { color: var(--slot); }
.audit .detail { color: var(--ink-soft); min-width: 22rem; }

/* ---------- misc ---------- */

.tags { display: flex; flex-wrap: wrap; gap: var(--space-hair); margin-top: var(--space-tight); }
.tag {
  font-family: var(--mono);
  font-size: var(--text-micro);
  padding: 2px 6px;
  border-radius: var(--radius);
  background: var(--paper-sunken);
  border: 1px solid var(--rule);
}

.footnote {
  margin-top: var(--space-section);
  padding-top: var(--space);
  border-top: 1px solid var(--rule);
  color: var(--ink-faint);
  font-size: var(--text-micro);
  max-width: 78ch;
}

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 1ms !important; }
}

/* A refused edit must not look like an accepted one. */
details.panel--rejected {
  border-color: var(--danger);
  box-shadow: 0 0 0 1px color-mix(in oklch, var(--danger) 35%, transparent);
}

details.panel--rejected > summary { color: var(--danger); font-weight: 650; }
details.panel--rejected > summary::before { color: var(--danger); }

.field-error {
  margin: var(--space-hair) 0 0;
  padding: var(--space-tight);
  border-left: 3px solid var(--danger);
  background: var(--danger-soft);
  border-radius: 0 var(--radius) var(--radius) 0;
  color: var(--ink);
  font-size: var(--text-small);
  overflow-wrap: anywhere;
}

/* ---------- help page ---------- */

.prose { max-width: 78ch; }
.prose p { color: var(--ink-soft); }
.prose strong, .prose th { color: var(--ink); }
.prose code {
  font-family: var(--mono);
  font-size: 0.92em;
  padding: 1px 4px;
  border-radius: var(--radius);
  background: var(--paper-sunken);
  border: 1px solid var(--rule);
}

.steps { margin: var(--space) 0 0; padding-left: 1.3rem; color: var(--ink-soft); }
.steps li { margin-bottom: var(--space-tight); }
.prose ul { color: var(--ink-soft); padding-left: 1.3rem; }
.prose li { margin-bottom: var(--space-hair); }

.ref {
  width: 100%;
  border-collapse: collapse;
  margin-top: var(--space);
  font-size: var(--text-small);
}
.ref th {
  text-align: left;
  vertical-align: top;
  white-space: nowrap;
  padding: var(--space-tight) var(--space) var(--space-tight) 0;
  border-bottom: 1px solid var(--rule);
  font-family: var(--mono);
  font-weight: 600;
}
.ref td {
  vertical-align: top;
  padding: var(--space-tight) 0;
  border-bottom: 1px solid var(--rule);
  color: var(--ink-soft);
}

.note-inline {
  margin-top: var(--space);
  padding-left: var(--space);
  border-left: 2px solid var(--rule-strong);
  font-size: var(--text-small);
}

.code {
  margin-top: var(--space);
  padding: var(--space);
  background: var(--paper-sunken);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  font-family: var(--mono);
  font-size: var(--text-small);
  overflow-x: auto;
}

/* A focused element must never be hidden by an auto-refresh countdown. */
#refresh-state { font-variant-numeric: tabular-nums; }


/* ---------- hover help ---------- */

/* A "?" beside the thing it explains, opening a panel on hover and closing when
   the pointer leaves. No JavaScript is involved: the panel is a child of the
   trigger's wrapper, so :hover on the wrapper covers both, and the pointer can
   travel from one to the other without crossing dead space. That also makes it
   work with the dashboard's auto-refresh, which cannot know about a state the
   page never stores.
   The trigger is a real button so the same panel opens on keyboard focus and on
   tap — hover alone would leave both out. */
.hint {
  position: relative;
  display: inline-flex;
  vertical-align: middle;
  margin-left: 0.4em;
}

.hint__trigger {
  display: inline-grid;
  place-items: center;
  width: 1.25em;
  height: 1.25em;
  padding: 0;
  border: 1px solid var(--rule-strong);
  border-radius: 50%;
  background: transparent;
  color: var(--ink-faint);
  font-family: var(--mono);
  font-size: var(--text-micro);
  line-height: 1;
  cursor: help;
  transition: color var(--duration) var(--ease), background var(--duration) var(--ease), border-color var(--duration) var(--ease);
}

.hint:hover > .hint__trigger,
.hint__trigger:focus-visible {
  color: var(--accent-ink);
  background: var(--accent);
  border-color: var(--accent);
}

.hint__panel {
  position: absolute;
  top: 100%;
  /* Anchored to the trigger's left edge rather than centred on it: triggers sit
     at the start of the thing they annotate, so this keeps the panel inside the
     content column without measuring anything. --hint-shift is the correction
     app.js applies for the few that would still cross a viewport edge; without
     JavaScript it stays 0 and the panel is merely off-centre, never broken. */
  left: 0;
  /* The gap between trigger and card is padding on the panel, not margin, so it
     stays inside the hover area: a real gap would close the panel mid-travel. */
  padding-top: 9px;
  width: min(30rem, calc(100vw - 2rem));
  z-index: var(--z-hint);
  opacity: 0;
  visibility: hidden;
  /* The panel's transform carries placement ONLY, and is never transitioned: a
     transitioned property does not settle while the element is hidden, so the
     correction would sit pending until the first hover and the panel would open
     in the wrong place. The opening motion lives on the card instead. */
  transform: translateX(var(--hint-shift, 0px));
  transition:
    opacity var(--duration) var(--ease),
    visibility 0s linear var(--duration);
}

.hint:hover > .hint__panel,
.hint:focus-within > .hint__panel {
  opacity: 1;
  visibility: visible;
  /* A short opening delay so panels do not flash while the pointer crosses the
     page; closing is immediate, as asked. */
  transition-delay: 90ms, 0s;
}

.hint__card {
  display: block;
  position: relative;
  transform: translateY(-4px);
  transition: transform var(--duration) var(--ease) 90ms;
  max-height: min(70vh, 34rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--space) var(--space) var(--space-tight);
  background: var(--paper-raised);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-lg);
  box-shadow: 0 2px 4px oklch(20% 0.02 265 / 0.08), 0 18px 44px -20px oklch(20% 0.02 265 / 0.45);
  /* It can sit inside a heading, a badge or a label, every one of which sets
     type it must not inherit. */
  font-family: var(--sans);
  font-size: var(--text-small);
  font-weight: 400;
  font-style: normal;
  line-height: 1.5;
  letter-spacing: normal;
  text-transform: none;
  text-align: left;
  color: var(--ink-soft);
  white-space: normal;
}

.hint:hover > .hint__panel > .hint__card,
.hint:focus-within > .hint__panel > .hint__card { transform: none; }

.hint__card--terse {
  width: max-content;
  max-width: min(26rem, calc(100vw - 2rem));
  padding: var(--space-tight) var(--space);
}

.hint__title {
  margin: 0 0 var(--space-tight);
  padding-bottom: var(--space-hair);
  border-bottom: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: var(--text-micro);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.hint__card > p:first-of-type { margin-top: 0; }
.hint__card p { margin: 0 0 var(--space-tight); }
.hint__card strong { color: var(--ink); }
.hint__card .ref { margin-top: var(--space-tight); }
.hint__card .steps { margin-top: 0; }
.hint__card .code { font-size: var(--text-micro); }

.hint__more {
  display: inline-block;
  margin-top: var(--space-tight);
  font-family: var(--mono);
  font-size: var(--text-micro);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* Panels near the right edge open leftwards; nothing else can flip on its own
   without measuring, and these are the only triggers that live there. */
.masthead__tools .hint__panel {
  left: auto;
  right: 0;
}

.badge .hint { margin-left: 0.35em; }
.badge .hint__trigger { border-color: currentColor; opacity: 0.55; }
.badge .hint:hover > .hint__trigger { opacity: 1; }

.section__head .hint { align-self: center; }

/* Small screens have no hover and no room to anchor: the panel becomes a sheet
   pinned to the bottom, opened by tapping the trigger (which focuses it). */
@media (max-width: 720px) {
  .hint__panel {
    position: fixed;
    inset: auto var(--space) var(--space) var(--space);
    top: auto;
    width: auto;
    transform: none;
    padding-top: 0;
  }
  .hint:hover > .hint__panel > .hint__card,
.hint:focus-within > .hint__panel > .hint__card { transform: none; }

.hint__card--terse { width: auto; max-width: none; }
}

@media (prefers-reduced-motion: reduce) {
  .hint__panel { transition: opacity 1ms, visibility 1ms; }
  .hint__card { transform: none; transition: none; }
  .hint:hover > .hint__panel, .hint:focus-within > .hint__panel { transition-delay: 0s; }
}

/* The decorative twin of a trigger, for prose that refers to it. */
.hint-glyph {
  display: inline-grid;
  place-items: center;
  width: 1.25em;
  height: 1.25em;
  border: 1px solid var(--rule-strong);
  border-radius: 50%;
  font-family: var(--mono);
  font-size: 0.8em;
  color: var(--ink-faint);
}

/* ---------- the manual ---------- */

.lede {
  max-width: 68ch;
  margin: var(--space-wide) 0 0;
  font-size: var(--text-lead);
  color: var(--ink-soft);
}

/* Separators are borders on the cells, not gaps showing a coloured backdrop:
   the last row is rarely full, and a gap would paint the empty cells. */
.toc {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  margin-top: var(--space-wide);
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.toc__item {
  display: flex;
  align-items: baseline;
  gap: var(--space-tight);
  padding: var(--space-tight) var(--space);
  border-right: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  color: var(--ink);
  text-decoration: none;
  transition: background var(--duration) var(--ease), color var(--duration) var(--ease);
}

.toc__item:hover { background: var(--accent-soft); color: var(--accent); }
.toc__num { font-family: var(--mono); font-size: var(--text-micro); color: var(--ink-faint); }
.toc__title { font-size: var(--text-small); }

.topic { max-width: 74ch; margin-top: var(--space); color: var(--ink-soft); }
.topic > p:first-child { margin-top: 0; }
.topic p { margin: 0 0 var(--space); }
.topic strong { color: var(--ink); }
.topic .ref { max-width: 74ch; }

.topic__see {
  margin-top: var(--space);
  font-size: var(--text-small);
  color: var(--ink-faint);
}

.manual .section { padding-top: var(--space-wide); }

/* A scope claim for a zone apex grants that zone's wildcard certificate. It is
   deliberately not styled like the row above it: this is the one claim where a
   reflexive click has zone-wide consequences. */
.claim--apex {
  border-left: 3px solid var(--danger);
  background: var(--danger-soft);
}
.claim--apex .claim__ip { color: var(--danger); }

/* ---------- sign in ---------- */

/* Deliberately unlike the console behind it: one card, one job, no chrome to
   suggest anything here is browsable before you are in. */
.signin__frame {
  display: grid;
  place-items: center;
  min-height: 100svh;
  padding: var(--space-wide) var(--gutter);
  max-width: none;
}

.signin__card {
  width: min(26rem, 100%);
  padding: var(--space-wide);
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-top: 3px solid var(--accent);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-raised);
}

.signin__title {
  margin: var(--space-hair) 0 var(--space-tight);
  font-size: clamp(1.4rem, 1.2rem + 0.8vw, 1.9rem);
  font-weight: 620;
  letter-spacing: -0.02em;
}

.signin__note {
  margin: 0 0 var(--space-wide);
  font-size: var(--text-small);
  color: var(--ink-soft);
}

.signin__card .field { margin-bottom: var(--space); }
.signin__card .field--narrow { max-width: 11rem; }
.signin__card .actions { margin-top: var(--space-wide); }
.signin__card .primary { width: 100%; justify-content: center; }
.signin__card .notice { margin-top: 0; margin-bottom: var(--space); }

.signin__foot {
  margin: var(--space-wide) auto 0;
  max-width: 26rem;
  font-size: var(--text-micro);
  color: var(--ink-faint);
  text-align: center;
}
