/* widgets.css — the larger compound UI pieces used across pages but not
   bound to one. Filter bar + carapace x-ray on listings, KPI tiles, hero
   strip, charts/spec boxes, the lexicon entry, the client-setup partial,
   profile card, registry URL block, error page, and avatar marks. */

/* ---- hero: a subtle cursive loop-chain drawn behind the heading + lede ---- */
.hero { position: relative; }
.hero::before {
  content: "";
  position: absolute;
  z-index: 0;
  left: -1.25rem;
  right: -1.25rem;
  top: 0.2rem;
  height: 120px;
  background: url("/static/brand/flourish.svg") repeat-x left top;
  background-size: auto 92px;
  opacity: 0.09;
  pointer-events: none;
}
.hero > * { position: relative; z-index: 1; }

/* ---- hero-pic: a thematic generative drawing behind a section hero ----
   Each page passes a pic source via {{pic "..."}} into a .hero-pic child;
   the .hero-pic-host modifier on the hero suppresses the flourish so the
   two patterns don't compete. The drawing parks in the right-hand part
   of the strip, with the heading + lede laying over it at full opacity. */
.hero-pic-host { overflow: hidden; }
.hero-pic-host::before { display: none; }
.hero-pic {
  position: absolute;
  top: -0.2rem;
  right: -0.5rem;
  bottom: -0.2rem;
  width: min(420px, 55%);
  z-index: 0;
  opacity: 0.28;
  color: var(--ink);
  pointer-events: none;
}
/* Dark mode reads the brand colours on warm-near-black less luminously
   at the same opacity; lift the hero-pic and splash-pic slightly so the
   sage/lavender/ochre carry behind the headline copy. */
:root[data-theme="dark"] .hero-pic { opacity: 0.42; }
.hero-pic svg {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: contain;
  object-position: right center;
}

/* ---- bandwidth sparkline ----
   One column per month, each carrying its own --bw scalar (0..1) set
   inline by the template. The bar's height is calc(var(--bw) * track),
   so the tallest month tops out and the rest scale proportionally;
   reads as a tiny bar chart without any JS or charting library. */
.bw-spark {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  margin: 0.5rem 0 1rem;
  height: 64px;
}
.bw-spark-col {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  justify-content: flex-end;
  height: 100%;
}
.bw-spark-bar {
  display: block;
  width: 28px;
  background: var(--ink);
  height: calc(var(--bw, 0) * 50px);
  min-height: 1px;
  border-radius: 1px;
}
.bw-spark-label {
  font-variation-settings: var(--mono);
  font-size: 10px;
  color: var(--grey);
  letter-spacing: 0.06em;
}

/* ---- KPI stat boxes ---- */
.kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 1px;
  background: var(--hair);
  border: 1px solid var(--hair);
  margin: 1.5rem 0;
}
.kpi {
  background: var(--paper);
  padding: 0.7rem 0.85rem;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}
.kpi-n { font-size: 1.7rem; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }
.kpi-l { font-variation-settings: var(--mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--grey); }
.kpi-sub { font-variation-settings: var(--mono); font-size: 11px; color: var(--faint); }
/* kpi-cycle: a single ecosystem chip + cycle button that rotates through
   per-ecosystem counts so the KPI stays compact as new ecosystems land.
   The fragment template kpi-packages-chip swaps itself on each ↻ click. */
.kpi-cycle { display: inline-flex; align-items: center; gap: 4px; margin-top: 2px; }
.kpi-chip { font-variation-settings: var(--mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--faint); padding: 1px 5px; border: 1px solid var(--rule); border-radius: 3px; white-space: nowrap; line-height: 1.3; text-decoration: none; }
.kpi-chip strong { color: var(--grey); font-weight: 700; }
a.kpi-chip:hover { background: var(--surface); color: var(--ink); }
.kpi-cycle-btn { font-size: 11px; line-height: 1; padding: 1px 4px; border: 1px solid var(--rule); border-radius: 3px; background: transparent; color: var(--faint); cursor: pointer; min-width: 24px; min-height: 24px; display: inline-flex; align-items: center; justify-content: center; }
.kpi-cycle-btn:hover { color: var(--ink); background: var(--surface); }
.kpi-n .ico { width: 0.72em; height: 0.72em; vertical-align: 0.02em; margin-right: 0.18em; display: inline-block; }
/* Inline pic-rendered glyphs (e.g. the ochre warn triangle on advisory
   KPIs) wrap their SVG in span.ico; size it to the parent box so the
   triangle sits in-line with the count number. */
.kpi-n .ico svg { width: 100%; height: 100%; display: block; }
.kpi-flag { border-left: 2px solid var(--ink); }       /* a flagged problem KPI */
.kpi-flag .kpi-l { color: var(--ink); font-weight: 700; }
a.kpi-link { text-decoration: none; color: inherit; cursor: pointer; }
a.kpi-link:hover { background: var(--surface); }

/* sec-band: a titled section row (security / network / etc.). Each band
   carries a subject-matched pic composition behind its KPIs via an inline
   .sec-band-pic child. Replaces the old repeated-flourish backsplash —
   that look used the same horizontal motif behind every section, which
   read as wallpaper rather than relevance. */
.sec-band { position: relative; margin-top: 1.8rem; }
.sec-band > * { position: relative; z-index: 1; }

/* sec-band-pic: subject-matched inline composition that sits in the gap
   between the previous section and the band's h2 title. Has to be a
   thin horizontal strip (~64px) rather than a full-bleed backsplash —
   the .kpis grid below has a solid paper-coloured background that
   would otherwise hide a behind-the-KPIs composition entirely. Same
   slot the old flourish ::before lived in, but with a per-band pic
   instead of repeated wallpaper. Dimmed so it reads as accent, not
   advertisement. */
.sec-band-pic {
  position: absolute;
  left: -1.25rem;
  right: -1.25rem;
  top: -1.4rem;
  height: 64px;
  z-index: 0;
  opacity: 0.22;
  color: var(--ink);
  pointer-events: none;
  overflow: hidden;
}
:root[data-theme="dark"] .sec-band-pic { opacity: 0.42; }
.sec-band-pic svg {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  object-position: center;
}
.sec-title {
  margin: 0 0 0.2rem;
  font-size: 1.25rem;
  font-weight: 800;
  letter-spacing: 0.01em;
}

/* ---- draftsman charts ---- */
.charts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1.25rem;
  margin: 1.5rem 0;
}
.chartbox { margin: 0; border: 1px solid var(--line); padding: 0.7rem 0.85rem; }
.chartbox figcaption, .chartbox .chartcap {
  display: block;
  font-variation-settings: var(--mono);
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--grey); margin-bottom: 0.5rem;
  padding-bottom: 0.3rem; border-bottom: 1px solid var(--hair);
}
.chart { width: 100%; height: auto; display: block; color: var(--ink); }
.chart .axis { stroke: currentColor; stroke-width: 0.6; }
.chart .grid { stroke: currentColor; stroke-width: 0.6; stroke-dasharray: 2 2; opacity: 0.3; }
.chart .bar  { fill: currentColor; }
.chart .lbl  { fill: currentColor; font-family: ui-monospace, monospace; font-size: 8px; opacity: 0.65; }
.chart .bar-link { cursor: pointer; }
.chart .bar-link:hover .bar { opacity: 0.55; }

/* click-to-cycle pulls chart: the whole control is a <button> styled as a
   chartbox, so reset the native button chrome. */
button.chartbox-cycle {
  width: 100%; display: block; font: inherit; color: inherit;
  text-align: left; background: none; -webkit-appearance: none; appearance: none;
}
.chartbox-cycle { cursor: pointer; }
.chartbox-cycle:hover { border-color: var(--ink); }
.chartbox-cycle:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.chartbox-cycle:hover .chart .bar { opacity: 0.8; }
.chart-cycle { float: right; opacity: 0.55; letter-spacing: 0; text-transform: none; }
.chartbox-cycle:hover .chart-cycle { opacity: 1; }
.chart .bar-link:hover .lbl { opacity: 1; text-decoration: underline; }

/* ---- spec boxes (.grid / .card / .code) ---- */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 1rem;
  margin: 1.5rem 0;
}
.card {
  border: 1px solid var(--ink);
  padding: 0.85rem 0.9rem;
  position: relative;
  background: var(--paper);
}
.card h2 {
  font-size: 0.9rem;
  font-weight: 700;
  margin: 0 0 0.35rem;
  padding-bottom: 0.3rem;
  border-bottom: 1px solid var(--hair);
  text-transform: lowercase;
}
.code, pre.code {
  font-size: 12px;
  border: 1px solid var(--hair);
  padding: 0.5rem 0.6rem;
  overflow-x: auto;
  margin: 0.6rem 0;
  white-space: pre-wrap;
  background: var(--surface);
}

/* ---- filter bar (live-search + select for the row table below) ---- */
.filters {
  display: flex;
  gap: 0.5rem;
  margin: 1.25rem 0 0.5rem;
}
.filters input[type="search"],
.filters select {
  font-family: inherit;
  font-variation-settings: var(--mono);
  font-size: 13px;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--ink);
  padding: 0.3rem 0.5rem;
}
.filters input[type="search"] { flex: 1; }
.filters input[type="search"]:focus,
.filters select:focus { outline: 2px solid var(--ink); outline-offset: -2px; }

/* ---- carapace (inline x-ray on the packages list) ---- */
.cara-toggle { text-align: right; white-space: nowrap; }
button.xray {
  font-family: inherit;
  font-variation-settings: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.04em;
  color: var(--grey);
  background: var(--paper);
  border: 1px solid var(--hair);
  padding: 0 5px;
  cursor: pointer;
}
button.xray:hover { color: var(--paper); background: var(--ink); border-color: var(--ink); }
.carapace-row td { padding: 0; border-bottom: none; }
.carapace-cell:empty { display: none; }
.carapace {
  position: relative;
  margin: 0 0 0.5rem 1.5rem;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--hair);
  border-left: 2px solid var(--ink);
  background: var(--surface);
}
.xray-close {
  position: absolute; top: 0.3rem; right: 0.4rem;
  border: none; background: none; cursor: pointer;
  font-size: 13px; color: var(--grey); line-height: 1;
}
.carapace-sec { margin: 0.15rem 0 0.5rem; }
.carapace-sec:last-child { margin-bottom: 0; }
.carapace-label {
  font-variation-settings: var(--mono);
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--grey);
}
.carapace-list { margin: 0.2rem 0 0; padding-left: 1.1rem; font-size: 12.5px; }
.carapace-list li { margin: 0.1rem 0; }

/* ---- blast-radius summary (sits next to first-sight chips) ---- */
.summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 0.55rem 1.4rem;
  margin: 1rem 0 0.4rem;
  padding: 0.8rem 1rem;
  border: 1px solid var(--hair);
  border-left: 2px solid var(--ink);
  background: var(--surface);
}
.summary div { margin: 0; min-width: 0; } /* let grid cells shrink, not overflow */
.summary dt {
  font-variation-settings: var(--mono);
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--grey);
}
.summary dd { margin: 0.1rem 0 0; font-weight: 600; overflow-wrap: anywhere; }

/* ---- lexicon gloss: a drafted dictionary entry, definition over a caret ---- */
.lexicon {
  margin: 3rem auto 0.5rem;
  max-width: 46ch;
  text-align: center;
  color: var(--grey);
}
.lex-def {
  font-variation-settings: var(--prose);
  font-style: oblique -6deg;
  font-size: 13px;
  line-height: 1.5;
}
.lex-caret {
  height: 9px;
  margin: 0.55rem 0 0.45rem;
  /* Use the caret SVG as a CSS mask, not as a background-image. The
     pic-compiled brand/caret.svg embeds a <style> that hard-codes
     `color:#16160f` (ink) so the file renders correctly in slide
     decks where tokens.css is absent. As a `background-image` that
     baked-in colour leaks through, so in dark mode the carets paint
     near-black on near-black paper and disappear. Masking ignores
     the SVG's own colour and paints whatever `background-color` the
     surrounding theme provides — currentColor flows through cleanly
     in both light and dark. */
  -webkit-mask-image: url("/static/brand/caret.svg");
  -webkit-mask-repeat: space;
  -webkit-mask-size: 24px 9px;
  -webkit-mask-position: center;
  mask-image: url("/static/brand/caret.svg");
  mask-repeat: space;             /* only whole carets; ends never clipped */
  mask-size: 24px 9px;
  mask-position: center;
  background-color: currentColor;
  color: var(--ink);
  opacity: 0.38;
}
.lex-word {
  font-variation-settings: var(--mono);
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
}
.lex-meta { font-weight: 400; color: var(--faint); }

/* ---- client-setup component (point a client at it) ---- */
.setup { border: 1px solid var(--ink); margin: 1.5rem 0; }
.setup-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.4rem 0.7rem;
  background: var(--tag);
  border-bottom: 1px solid var(--ink);
}
.setup-title {
  font-variation-settings: var(--mono);
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em;
  font-weight: 700;
}
.setup-head select {
  font-family: inherit;
  font-variation-settings: var(--mono);
  font-size: 12px;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--ink);
  padding: 0.15rem 0.4rem;
}
.setup-file {
  font-variation-settings: var(--mono);
  font-size: 10.5px; color: var(--grey);
  padding: 0.4rem 0.7rem 0;
}
pre.setup-code {
  margin: 0.5rem 0; padding: 0.6rem 0.75rem;
  background: var(--surface); border: 1px solid var(--hair); border-left: 3px solid var(--ink);
  font-size: 12px; line-height: 1.65;
  white-space: pre-wrap; overflow-wrap: anywhere; /* long URLs wrap instead of overflowing */
}
/* keep the homepage setup snippet inset within its bordered .setup box */
.setup pre.setup-code { margin: 0.3rem 0.7rem 0.7rem; border: none; border-left: none; padding-left: 0; background: none; }

/* ---- profile card (top of /settings/tokens): the user's home on this
   instance — avatar, role/tier chips, organizations. */
/* Align the avatar with the heading row rather than the centre of the
   full block. The .profile-id stack can grow tall (chips + a multi-line
   "look-around" paragraph), so centring leaves the avatar floating in
   the middle, decoupled from the title. flex-start pins it to the top
   edge of the title so the two read as a unit. */
.profile-head { display: flex; align-items: flex-start; gap: 1rem; }
.profile-head h1 { margin: 0 0 .15rem; line-height: 1; }
.profile-avatar {
  width: 56px; height: 56px; border-radius: 50%; object-fit: cover;
  border: 1px solid var(--hair);
  flex: none;
  margin-top: 0.1rem;
}
.profile-id { min-width: 0; }
.org-list { list-style: none; margin: 0.3rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.25rem; }
.org-list li { display: flex; align-items: center; gap: 0.5rem; }
.org-list a { color: var(--ink); text-decoration: none; font-weight: 600; }
.org-list a:hover { text-decoration: underline; }

/* registry URL shown on a hosted repo: compact, selectable, wraps */
code.reg {
  display: block; font-size: 12px; color: var(--ink);
  background: var(--surface); border: 1px solid var(--hair);
  padding: .4rem .6rem; margin: .2rem 0 .45rem;
  overflow-wrap: anywhere; user-select: all; /* one click selects the whole URL */
}

/* ---- avatar: reusable draftsman identity mark (concentric registration ring) ---- */
.avatar {
  flex: none;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border: 1px solid var(--ink);
  border-radius: 50%;
  background: var(--paper);
  font-variation-settings: var(--mono);
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  color: var(--ink);
  vertical-align: middle;
}
.avatar::before {
  content: "";
  position: absolute;
  inset: 2px;
  border: 1px solid var(--hair);
  border-radius: 50%;
}
/* same circle, but the user's actual profile picture when they have one */
.avatar-img {
  flex: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid var(--ink);
  background: var(--paper);
  vertical-align: middle;
}

/* ---- marks & badges (B&W only) ---- */
.badge {
  position: absolute;
  top: 0.7rem; right: 0.7rem;
  font-size: 10px;
  letter-spacing: 0.08em;
  border: 1px solid var(--ink);
  padding: 0 4px;
}
.badge.ok { background: var(--ink); color: var(--paper); }   /* filled = done */
.badge.pending { color: var(--grey); border-color: var(--hair); }

/* ---- themed error page: big wonky face as a centered backdrop ---- */
.error-page {
  position: relative; min-height: 52vh;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 2.5rem 1rem;
}
.error-page .sadface {
  position: absolute; left: 50%; top: 47%; transform: translate(-50%, -50%);
  width: min(78vw, 420px); height: auto;
  /* the SVG is an <img>, so its currentColor is black; dark mode inverts it to
     white via the theme filter above. */
  opacity: 0.14; z-index: 0; pointer-events: none; /* watermark behind the text */
}
.error-page > :not(.sadface) { position: relative; z-index: 1; } /* text overlays the face */
.error-page .error-code {
  font-variation-settings: var(--mono); font-size: 3.4rem; letter-spacing: .05em;
  margin: 0 0 0.4rem; border: none;
}
.error-page .lede { margin: 0 0 0.6rem; }

/* ---- docs grep: a result block, one per matching doc ----------------- */
.docs-hit { margin: 0.6rem 0; }
.docs-hit > summary { cursor: pointer; padding: 0.3rem 0; }
.docs-hit > summary::-webkit-details-marker { color: var(--faint); }
/* docs-hit-section: clickable heading-jump label above each snippet.
   Plain capital-case text with an underline on hover — no glyphs. */
.docs-hit-section {
  display: inline-block;
  font-variation-settings: var(--mono);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--grey);
  text-decoration: none;
  margin: 0.4rem 0 0.2rem;
  padding-bottom: 1px;
  border-bottom: 1px dashed var(--hair);
}
.docs-hit-section:hover { color: var(--ink); border-bottom-style: solid; }
/* docs-hit-snippet: rendered markdown subset of the doc surrounding the
   match. Prose styles inherit from .post-body shape — paragraph spacing,
   list bullets, inline code — so a snippet reads exactly like its
   neighborhood in the full doc. */
.docs-hit-snippet {
  padding: 0.4rem 0.8rem;
  background: var(--surface);
  border-left: 2px solid var(--ink);
  font-variation-settings: var(--prose);
  font-size: 13px;
  line-height: 1.55;
  overflow-x: auto;
}
.docs-hit-snippet > *:first-child { margin-top: 0; }
.docs-hit-snippet > *:last-child  { margin-bottom: 0; }
.docs-hit-snippet code { font-size: 0.9em; background: var(--surface-2); padding: 0 3px; }
.docs-hit-sep { border: none; border-top: 1px dashed var(--hair); margin: 0.7rem 0; }

/* ---- auth pages: sign-in chooser + signup ----------------------------
   Centered narrow card with a small generative mark on top, one form per
   provider, dashed "or" dividers between. Inputs + buttons mirror the
   .field-form convention (paper bg, hair border, hover to ink/paper) so
   the page reads as native chrome rather than a bolt-on landing. */
.auth-shell {
  display: grid;
  place-items: start center;
  padding: 1rem 0 3rem;
}
.auth-card {
  width: 100%;
  max-width: 380px;
  padding: 1.4rem 1.5rem 1.6rem;
  text-align: left;
  background: var(--paper);
  border: 1px solid var(--hair);
}
/* Override the default .panel h1 sizing — the sign-in card is intimate,
   not a section heading. Two-class specificity beats the panel rule. */
.auth-card .auth-title {
  font-size: 1.25rem;
  font-weight: 700;
  margin: 0.1rem 0 0.1rem;
  text-align: center;
  letter-spacing: -0.005em;
  border: none;
}
.auth-mark {
  margin: -0.2rem auto 0.3rem;
  width: 100%;
  max-width: 180px;
  opacity: 0.75;
  color: var(--ink);
}
.auth-mark svg { width: 100%; height: auto; display: block; }
.auth-sub {
  margin: 0 0 0.9rem;
  text-align: center;
  color: var(--grey);
  font-size: 0.85rem;
}
/* trial-terms banner on /start: subtle ochre-tinted box so the 14-day/card line
   reads clearly without shouting. */
.auth-trial {
  margin: 0 auto 0.9rem;
  max-width: 34ch;
  text-align: center;
  font-variation-settings: var(--mono);
  font-size: 0.76rem;
  color: var(--ink);
  border: 1px solid var(--hair);
  border-radius: 3px;
  padding: 0.42rem 0.6rem;
  background: color-mix(in srgb, var(--ochre) 8%, var(--paper));
}
.auth-fineprint { margin: 0 0 1rem; text-align: center; color: var(--faint); font-size: 0.72rem; }
.auth-fineprint a { color: var(--grey); }
.auth-error {
  margin: 0 0 0.8rem;
  padding: 0.45rem 0.6rem;
  border-left: 2px solid var(--ochre);
  background: var(--surface);
  font-size: 0.85rem;
  color: var(--ink);
}
.auth-form { margin: 0; display: block; }
.auth-method-h {
  font-variation-settings: var(--mono);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--grey);
  margin: 0 0 0.55rem;
  font-weight: 600;
  border: none;
}
.auth-field {
  display: block;
  margin: 0 0 0.55rem;
}
.auth-field > span {
  display: block;
  font-size: 12px;
  color: var(--grey);
  margin-bottom: 0.15rem;
}
.auth-field input {
  width: 100%;
  font-family: inherit;
  font-size: 13px;
  padding: 0.35rem 0.55rem;
  background: var(--paper);
  border: 1px solid var(--hair);
  color: var(--ink);
  box-sizing: border-box;
}
.auth-field input:focus { outline: none; border-color: var(--ink); }
.auth-field input:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
/* Match the codebase button convention: monospaced, paper bg, hair border,
   hover swaps to ink/paper. Sits flush with the inputs above it. */
.auth-submit {
  width: 100%;
  margin-top: 0.4rem;
  padding: 0.4rem 0.7rem;
  font-family: inherit;
  font-variation-settings: var(--mono);
  font-size: 12px;
  text-transform: lowercase;
  letter-spacing: 0.02em;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--ink);
  cursor: pointer;
}
.auth-submit:hover { background: var(--ink); color: var(--paper); }
.auth-aside {
  margin: 0.55rem 0 0;
  font-size: 12px;
  color: var(--grey);
  text-align: center;
}
.auth-divider {
  position: relative;
  text-align: center;
  margin: 0.9rem 0 0.8rem;
  color: var(--grey);
  font-variation-settings: var(--mono);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
.auth-divider::before, .auth-divider::after {
  content: "";
  position: absolute; top: 50%;
  width: calc(50% - 1.1rem);
  border-top: 1px dashed var(--hair);
}
.auth-divider::before { left: 0; }
.auth-divider::after  { right: 0; }
.auth-divider > span { background: var(--paper); padding: 0 0.55rem; position: relative; }
.auth-providers { display: flex; flex-direction: column; gap: 0.45rem; }
.auth-provider {
  display: block;
  padding: 0.4rem 0.7rem;
  text-align: center;
  font-family: inherit;
  font-variation-settings: var(--mono);
  font-size: 12px;
  border: 1px solid var(--ink);
  color: var(--ink);
  text-decoration: none;
  background: var(--paper);
}
.auth-provider:hover { background: var(--ink); color: var(--paper); }

/* ---- settings-grid: the admin-settings access ledger ------------------
   A two-column dl: label on the left (fixed), value + inline form + a
   muted description on the right. Sits between a bare list (no chrome,
   hard to scan) and a full table (too much chrome for two keys). */
.settings-grid {
  display: grid;
  grid-template-columns: 10rem 1fr;
  gap: 0.55rem 0.9rem;
  margin: 0.6rem 0 0.9rem;
  align-items: baseline;
}
.settings-grid dt {
  font-variation-settings: var(--mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--grey);
  padding-top: 0.2rem;
}
.settings-grid dd {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem 0.7rem;
}
.settings-grid .settings-desc { color: var(--grey); font-size: 13px; }
.settings-grid .settings-env {
  margin-left: auto;
  color: var(--faint);
  font-size: 12px;
  font-variation-settings: var(--mono);
}
.settings-grid .settings-form {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
}
.settings-grid .settings-form select {
  font-family: inherit; font-size: 13px;
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--hair); background: var(--paper); color: var(--ink);
}
.settings-grid .settings-form select:focus { outline: none; border-color: var(--ink); }
.settings-grid .settings-form select:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
.settings-grid .settings-form select:disabled { color: var(--faint); cursor: not-allowed; }
.settings-grid .settings-form button {
  font-family: inherit; font-variation-settings: var(--mono); font-size: 12px;
  border: 1px solid var(--hair); background: var(--paper); padding: 0.3rem 0.7rem; cursor: pointer;
}
.settings-grid .settings-form button:hover:not(:disabled) {
  background: var(--ink); color: var(--paper); border-color: var(--ink);
}
.settings-grid .settings-form button:disabled { color: var(--faint); cursor: not-allowed; }

/* ---- auth-stance: the "we don't host passwords" note on cloud sign-in
   Slightly more emphasis than .auth-sub — italic, a thin ink rule, so
   the security stance reads as deliberate copy rather than fine print. */
.auth-stance {
  margin: 0 0 1rem;
  padding: 0.5rem 0.7rem;
  border-left: 2px solid var(--sage);
  background: var(--surface);
  text-align: left;
  font-size: 0.82rem;
  font-style: italic;
  color: var(--grey);
}
