/* ============================================================================
   Felix Ihno - components.css   Direction B "Surveyor"   round 3   @version 2.4.0
   (2.3.0: light bg → near-white low-chroma warm-grey (whiter, desaturated); clay+green reverted to
    original brand values (lighter bg restored the contrast headroom). Contrast re-verified.)
   (2.1.0: color-mix tint/state % → --wash/line/mix/fill tokens; inline line-heights → --lh tokens. All gate-locked.
    2.0.0: scale foundation swapped to Tailwind in tokens.css â type ladder, radii, line-heights.
    Components unchanged (already token-only since 1.5). Identity (warm-clay/Newsreader) intact.)
   (1.5.0 "scale lockdown": EVERY component dimension references a --space/--text token
    â no raw px â¥4px anywhere (only 1/2/3px borders/insets stay raw). Off-grid optical
    values snapped to the 4px grid + unified (one 36px control height). Pairs with the
    exact-1.2 type scale in tokens.css. Both gate-enforced in check.mjs (scale check).
    1.4.0 restraint pass: callout titles â ink, calmer accordion, .fi-prose, softer radii)
   RULE (v1.5, gate-checked): dimensions use var(--space-*); type uses var(--text-*);
   the ONLY raw px permitted are 1/2/3 (borders, hairlines, fine insets/offsets).
   ----------------------------------------------------------------------------
   Shippable component layer. Load order:  @import "tokens.css";  then this file.
   RULES (audited):
     - Colour comes ONLY from tokens via var(--color-*) / var(--viz-*). No raw
       hex anywhere in this file. Tints use color-mix() OF tokens.
     - Real CSS states only: :hover, :active, :focus-visible. No preview attrs.
     - Current/selected = ink text + accent left-bar. Never accent TEXT on an
       accent-soft fill (that pattern is an AA fail).
     - Every pointer target has a >=24x24px hit area (min-height / min-width).
     - Works under [data-theme=dark] + [data-accent=green|oxblood] + @media print
       with zero per-component colour overrides. Hover/active darken or lighten
       automatically by mixing the accent toward --color-text (theme-aware).
   Sections: focus ring / buttons / fields / toggle / card / table / nav /
             badge / callout / spark / skeleton / empty / print.
   ========================================================================== */

/* ---------- shared keyboard focus ring (reuses --color-focus-ring) ---------- */
.fi-btn:focus-visible,
.fi-input:focus-visible,
.fi-select:focus-visible,
.fi-toggle:focus-visible,
.fi-segmented__option:focus-visible,
.fi-chip:focus-visible,
.fi-nav__item:focus-visible,
.fi-iconbtn:focus-visible,
a.fi-link:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  box-shadow: 0 0 0 var(--space-1) var(--color-focus-ring);
  border-radius: var(--radius-sm);
}

/* ================================ Buttons ================================== */
.fi-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5em;
  min-height: var(--space-9); padding: var(--space-2) var(--space-4);
  font: var(--weight-semi) var(--text-xs)/var(--lh-flat) var(--font-ui);
  letter-spacing: .01em;
  color: var(--color-on-accent);
  background: var(--color-accent);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: background var(--motion-fast) var(--ease-out),
              transform var(--motion-fast) var(--ease-out);
}
/* mixing accent toward ink darkens in light, lightens in dark - one rule, both themes */
.fi-btn:hover  { background: color-mix(in srgb, var(--color-accent) var(--mix-hover), var(--color-text)); }
.fi-btn:active { background: color-mix(in srgb, var(--color-accent) var(--mix-active), var(--color-text)); transform: translateY(1px); }
.fi-btn:disabled,
.fi-btn[aria-disabled="true"] { cursor: not-allowed; background: color-mix(in srgb, var(--color-text) 10%, var(--color-surface)); color: var(--color-text-faint); border-color: transparent; transform: none; }

/* secondary: accent outline + accent label on the page (never on a tint) */
.fi-btn--secondary {
  color: var(--color-accent);
  background: var(--color-surface);
  border-color: var(--color-accent);
}
.fi-btn--secondary:hover {
  background: var(--color-surface);
  color: color-mix(in srgb, var(--color-accent) var(--mix-active), var(--color-text));
  border-color: color-mix(in srgb, var(--color-accent) var(--mix-active), var(--color-text));
}
.fi-btn--secondary:active { transform: translateY(1px); }
.fi-btn--secondary:disabled,
.fi-btn--secondary[aria-disabled="true"] { color: var(--color-accent); border-color: var(--color-accent); }

/* ghost: accent label, neutral wash on hover (no accent-on-soft) */
.fi-btn--ghost {
  color: var(--color-accent);
  background: transparent;
  border-color: transparent;
}
.fi-btn--ghost:hover  { background: color-mix(in srgb, var(--color-text) var(--wash-2), transparent); }
.fi-btn--ghost:active { background: color-mix(in srgb, var(--color-text) var(--wash-3), transparent); }

/* compact, square-ish icon button - still >=24x24 */
.fi-iconbtn {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: var(--space-6); min-height: var(--space-6); padding: var(--space-1);
  color: var(--color-text-muted); background: transparent;
  border: none; border-radius: var(--radius-sm); cursor: pointer;
  transition: background var(--motion-fast) var(--ease-out), color var(--motion-fast) var(--ease-out);
}
.fi-iconbtn:hover { background: color-mix(in srgb, var(--color-text) var(--wash-2), transparent); color: var(--color-text); }

/* ================================ Fields =================================== */
.fi-field-label {
  display: block;
  font: var(--weight-semi) var(--text-3xs)/var(--lh-ui) var(--font-ui);
  letter-spacing: .02em; color: var(--color-text-muted);
}
.fi-input,
.fi-select {
  display: block; width: 100%; min-height: var(--space-9); padding: var(--space-2) var(--space-3);
  font: var(--weight-reg) var(--text-xs)/var(--lh-ui) var(--font-ui);
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-sm);
  transition: border-color var(--motion-fast) var(--ease-out);
}
.fi-input::placeholder { color: var(--color-text-faint); }
.fi-input:hover,
.fi-select:hover { border-color: color-mix(in srgb, var(--color-hairline) var(--line-hover), var(--color-text)); }
.fi-input:focus,
.fi-select:focus { outline: none; border-color: var(--color-accent); }
.fi-input:disabled,
.fi-select:disabled { opacity: .5; cursor: not-allowed; }

/* ================================ Toggle =================================== */
.fi-toggle {
  position: relative; display: inline-block;
  width: var(--space-10); min-width: var(--space-10); height: var(--space-6); min-height: var(--space-6);
  padding: 0; border: none; border-radius: 999px; cursor: pointer;
  background: var(--color-hairline);
  transition: background var(--motion-base) var(--ease-out);
}
.fi-toggle::after {
  content: ""; position: absolute; top: 2px; left: 2px;
  width: var(--space-5); height: var(--space-5); border-radius: 50%;
  background: var(--color-surface); box-shadow: var(--shadow-card);
  transition: transform var(--motion-base) var(--ease-out);
}
.fi-toggle[aria-checked="true"] { background: var(--color-accent); }
.fi-toggle[aria-checked="true"]::after { transform: translateX(var(--space-4)); background: var(--color-on-accent); }
.fi-toggle:disabled { opacity: .5; cursor: not-allowed; }

/* ============================ Segmented control =========================== */
/* single-choice-per-row segmented buttons. Selected = INK text + accent under-
   bar (same house rule as nav-current: never accent TEXT on an accent fill).
   Signal variants tint the selected option ok/caution/danger for triage rows
   (keep/revise/drop). Each option carries aria-pressed; JS owns single-select. */
.fi-segmented {
  display: inline-flex; flex: none;
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.fi-segmented__option {
  appearance: none; cursor: pointer;
  min-height: var(--space-9); padding: var(--space-2) var(--space-3);
  font: var(--weight-med) var(--text-xs)/var(--lh-flat) var(--font-ui);
  color: var(--color-text-muted);
  background: var(--color-surface);
  border: none; border-left: 1px solid var(--color-hairline);
  transition: background var(--motion-fast) var(--ease-out),
              color var(--motion-fast) var(--ease-out);
}
.fi-segmented__option:first-child { border-left: none; }
.fi-segmented__option:hover { color: var(--color-text); }
/* default selected: ink text + accent wash + accent under-bar */
.fi-segmented__option[aria-pressed="true"] {
  color: var(--color-text); font-weight: var(--weight-semi);
  background: var(--color-accent-soft);
  box-shadow: inset 0 -2px 0 var(--color-accent);
}
/* signal-tinted selected variants (mix the signal token toward surface â hex-free) */
.fi-segmented__option--ok[aria-pressed="true"] {
  background: color-mix(in srgb, var(--color-signal-ok) var(--fill-soft), var(--color-surface));
  box-shadow: inset 0 -2px 0 var(--color-signal-ok);
}
.fi-segmented__option--caution[aria-pressed="true"] {
  background: color-mix(in srgb, var(--color-signal-caution) var(--fill-soft), var(--color-surface));
  box-shadow: inset 0 -2px 0 var(--color-signal-caution);
}
.fi-segmented__option--danger[aria-pressed="true"] {
  background: color-mix(in srgb, var(--color-signal-danger) var(--fill-soft), var(--color-surface));
  box-shadow: inset 0 -2px 0 var(--color-signal-danger);
}

/* ================================ Chips =================================== */
/* multi-select pills. Selected = accent-soft fill + INK text + accent border
   (mirrors nav-current). aria-pressed=true marks selection; JS toggles it. */
.fi-chip {
  appearance: none; cursor: pointer;
  min-height: var(--space-9); padding: var(--space-2) var(--space-3);
  font: var(--weight-med) var(--text-xs)/var(--lh-flat) var(--font-ui);
  color: var(--color-text-muted);
  background: var(--color-surface);
  border: 1px solid var(--color-hairline);
  border-radius: 999px;
  transition: background var(--motion-fast) var(--ease-out),
              color var(--motion-fast) var(--ease-out),
              border-color var(--motion-fast) var(--ease-out);
}
.fi-chip:hover {
  color: var(--color-text);
  border-color: color-mix(in srgb, var(--color-hairline) var(--line-hover), var(--color-text));
}
.fi-chip[aria-pressed="true"] {
  color: var(--color-text); font-weight: var(--weight-semi);
  background: var(--color-accent-soft);
  border-color: var(--color-accent);
}

/* ================================= Card ==================================== */
/* Doc-tier container: translucent overlay + hairline, NO shadow (same depth-via-
   tint technique as .fi-surface, with the card's roomier --space-6 padding). The
   3% ink wash is computed FROM the page colour so it inherits the warm undertone
   and auto-inverts in dark; a solid fill would carry its own hue and clash. For a
   floating/elevated UI surface (popover, menu) add an explicit box-shadow locally. */
.fi-card {
  background: color-mix(in srgb, var(--color-text) var(--wash-1), transparent);
  border: 1px solid color-mix(in srgb, var(--color-text) var(--line-1), transparent);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
}

/* eyebrow / small-caps label */
.fi-eyebrow {
  font: var(--weight-semi) var(--text-3xs)/var(--lh-flat) var(--font-mono);
  letter-spacing: var(--tracking-eyebrow); text-transform: uppercase;
  color: var(--color-accent);
}

/* ============================== Hairline table ============================= */
.fi-table {
  width: 100%; border-collapse: collapse;
  font: var(--weight-reg) var(--text-2xs)/var(--lh-ui) var(--font-ui);
  color: var(--color-text);
}
.fi-table th {
  text-align: left; padding: 0 0 var(--space-2);
  font: var(--weight-bold) var(--text-3xs)/var(--lh-flat) var(--font-ui);
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--color-text-muted);
  border-bottom: 1px solid var(--color-hairline);
}
.fi-table td { padding: var(--space-3) 0; border-bottom: 1px solid var(--color-hairline); }
.fi-table tr:last-child td { border-bottom: none; }
.fi-table .fi-num { font-variant-numeric: tabular-nums; text-align: right; }
.fi-table--compact th { padding: 0 0 var(--space-1); }
.fi-table--compact td { padding: var(--space-1) 0; }

.fi-num { font-variant-numeric: tabular-nums; }

/* ============================== Nav / shell =============================== */
.fi-nav { display: flex; flex-direction: column; gap: 2px; }
.fi-nav__item {
  display: flex; align-items: center; gap: var(--space-2);
  min-height: var(--space-9); padding: var(--space-2) var(--space-3); width: 100%;
  font: var(--weight-med) var(--text-2xs)/var(--lh-flat) var(--font-ui);
  text-align: left; text-decoration: none; cursor: pointer;
  color: var(--color-text-muted);
  background: transparent; border: none;
  border-radius: var(--radius-sm);
  transition: background var(--motion-fast) var(--ease-out), color var(--motion-fast) var(--ease-out);
}
.fi-nav__item:hover { background: color-mix(in srgb, var(--color-text) var(--wash-2), transparent); color: var(--color-text); }
/* current: INK text + accent left-bar (audit #1 fix - not accent text on soft) */
.fi-nav__item--current {
  color: var(--color-text);
  font-weight: var(--weight-semi);
  background: var(--color-accent-soft);
  box-shadow: inset 2px 0 0 var(--color-accent);
}
.fi-nav__item--current:hover { color: var(--color-text); }

/* ================================ Badge ==================================== */
.fi-badge {
  display: inline-flex; align-items: center; gap: var(--space-1);
  padding: 2px var(--space-2); min-height: var(--space-5);
  font: var(--weight-semi) var(--text-3xs)/var(--lh-ui) var(--font-ui);
  letter-spacing: .04em;
  color: var(--color-text-muted);
  background: var(--color-surface);
  border: 1px solid var(--color-hairline);
  border-radius: 999px;
}
.fi-badge--accent { color: var(--color-accent); border-color: var(--color-accent); background: transparent; }
.fi-badge__dot { width: .5em; height: .5em; border-radius: 50%; background: currentColor; }

/* =============================== Callouts ================================= */
/* default = "note" (neutral). Modifiers set one local var: --fi-sig.            */
.fi-callout {
  display: flex; gap: var(--space-3); align-items: flex-start;
  padding: var(--space-3) var(--space-4);
  color: var(--color-text);
  background: color-mix(in srgb, var(--fi-sig, var(--color-text-muted)) var(--wash-2), var(--color-surface));
  border-left: 3px solid var(--fi-sig, var(--color-text-muted));
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.fi-callout__icon  { flex: none; margin-top: 1px; color: var(--fi-sig, var(--color-text-muted)); }
/* v1.4: title is INK; severity reads via the left-bar + icon colour (matches print). Cuts coloured small-text noise. */
.fi-callout__title { font: var(--weight-semi) var(--text-2xs)/var(--lh-snug) var(--font-ui); color: var(--color-text); }
.fi-callout__body  { margin-top: 1px; font-size: var(--text-2xs); line-height: var(--lh-ui); color: var(--color-text); text-wrap: pretty; }
.fi-callout--info     { --fi-sig: var(--color-signal-info); }
.fi-callout--ok       { --fi-sig: var(--color-signal-ok); }
.fi-callout--tip      { --fi-sig: var(--color-signal-ok); }
.fi-callout--warning  { --fi-sig: var(--color-signal-caution); }
.fi-callout--danger   { --fi-sig: var(--color-signal-danger); }
.fi-callout--question { --fi-sig: var(--color-accent); }

/* =============================== Sparkline ================================ */
.fi-spark { display: block; height: var(--space-6); }
.fi-spark__band  { fill: var(--viz-band); }
.fi-spark__line  { fill: none; stroke: var(--viz-spark); stroke-width: 1.5; }
.fi-spark__point { fill: var(--viz-spark-point); }

/* ============================ Skeleton / loading ========================== */
.fi-skeleton {
  border-radius: var(--radius-sm);
  background: linear-gradient(100deg,
              var(--color-hairline) 30%, var(--color-border) 50%, var(--color-hairline) 70%);
  background-size: 200% 100%;
  animation: fi-shimmer 1.5s linear infinite;
}
.fi-skeleton--text   { height: var(--space-3); }
.fi-skeleton--avatar { width: var(--space-10); height: var(--space-10); border-radius: 50%; }
@media (prefers-reduced-motion: reduce) { .fi-skeleton { animation: none; } }

/* ============================== Empty state ============================== */
.fi-empty { text-align: center; padding: var(--space-8) var(--space-6); }
.fi-empty__icon  { color: var(--color-text-faint); }
.fi-empty__title { margin: var(--space-3) 0 0; font: var(--weight-semi) var(--text-md)/var(--lh-snug) var(--font-heading); color: var(--color-text); text-wrap: balance; }
.fi-empty__body  { margin: var(--space-2) auto 0; max-width: 34ch; font-size: var(--text-2xs); line-height: var(--lh-ui); color: var(--color-text-muted); text-wrap: pretty; }

/* inline text link - colour PLUS underline (colour is never the only cue) */
.fi-link { color: var(--color-accent); text-decoration: underline; text-underline-offset: 2px; }

/* =============================== Accordion =============================== */
/* native <details>/<summary> group. Open item reads active: accent wash + accent chevron. */
.fi-accordion {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.fi-accordion__item { border-bottom: 1px solid var(--color-hairline); }
.fi-accordion__item:last-child { border-bottom: none; }
.fi-accordion__summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  padding: var(--space-4);
  font: var(--weight-semi) var(--text-md)/var(--lh-snug) var(--font-ui);
  color: var(--color-text);
  cursor: pointer; list-style: none; user-select: none;
  transition: background var(--motion-fast) var(--ease-out), color var(--motion-fast) var(--ease-out);
}
.fi-accordion__summary::-webkit-details-marker { display: none; }
.fi-accordion__summary:hover { background: color-mix(in srgb, var(--color-text) var(--wash-2), transparent); }
.fi-accordion__summary:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }
/* v1.4: open state reads via a faint wash + accent left-bar (like nav-current) â not a loud saturated accent fill */
.fi-accordion__item[open] > .fi-accordion__summary {
  background: color-mix(in srgb, var(--color-text) var(--wash-1), transparent);
  box-shadow: inset 2px 0 0 var(--color-accent);
}
/* chevron - optically centered; rotates + turns accent when open */
.fi-accordion__summary::after {
  content: ""; width: .62em; height: .62em; flex: none; margin-top: -.18em;
  border-right: 2px solid var(--color-text-muted);
  border-bottom: 2px solid var(--color-text-muted);
  transform: rotate(45deg);
  transition: transform var(--motion-fast) var(--ease-out), border-color var(--motion-fast) var(--ease-out);
}
.fi-accordion__item[open] > .fi-accordion__summary::after {
  margin-top: .12em; transform: rotate(-135deg); border-color: var(--color-accent);
}
.fi-accordion__body {
  padding: var(--space-2) var(--space-4) var(--space-4);
  font: var(--weight-reg) var(--text-sm)/var(--lh-body) var(--font-ui);
  color: var(--color-text-muted);
  text-wrap: pretty;
}

/* ============================ Surface (glass) ============================= */
/* translucent overlay + hairline, NO shadow - depth via tint, not elevation.   */
/* color-mix toward --color-text auto-inverts in dark; --accent variant = coral. */
.fi-surface {
  padding: var(--space-4);
  background: color-mix(in srgb, var(--color-text) var(--wash-1), transparent);
  border: 1px solid color-mix(in srgb, var(--color-text) var(--line-1), transparent);
  border-radius: var(--radius-lg);
}
.fi-surface--accent {
  background: color-mix(in srgb, var(--color-text) var(--wash-1), transparent);
  border-color: color-mix(in srgb, var(--color-accent) var(--line-2), transparent);
}

/* ============================== Prose (reading anchor) ==================== */
/* v1.4 (P3): a calm, generously-spaced reading column. Gives docs/briefs the
   whitespace + display hierarchy that a kitchen-sink of components lacks. Headings
   balance, body wraps pretty. Wrap article content in .fi-prose. */
.fi-prose {
  max-width: 68ch; margin-inline: auto;
  color: var(--color-text);
  font: var(--weight-reg) var(--text-sm)/var(--lh-body) var(--font-ui);
}
.fi-prose > * + * { margin-top: var(--space-4); }
.fi-prose h1 {
  font: var(--weight-semi) var(--text-3xl)/var(--lh-tight) var(--font-heading);
  letter-spacing: var(--tracking-tight); text-wrap: balance; margin-top: 0;
}
.fi-prose h2 {
  font: var(--weight-semi) var(--text-xl)/var(--lh-snug) var(--font-heading);
  letter-spacing: var(--tracking-tight); text-wrap: balance;
  margin-top: var(--space-12);
}
.fi-prose h3 { font: var(--weight-semi) var(--text-md)/var(--lh-snug) var(--font-heading); margin-top: var(--space-8); }
.fi-prose .fi-lead { font: var(--weight-reg) var(--text-md)/var(--lh-body) var(--font-heading); color: var(--color-text); text-wrap: pretty; }
.fi-prose p { max-width: 64ch; text-wrap: pretty; }
.fi-prose h2 + p, .fi-prose h3 + p { margin-top: var(--space-3); }

/* ================================= Print ================================= */
@media print {
  .fi-skeleton { animation: none; }
  /* reveal collapsed accordion answers on paper; drop the open-item wash */
  .fi-accordion__body { display: block; }
  .fi-accordion__item[open] > .fi-accordion__summary { background: transparent; }
  /* callouts: drop tint, severity reads by left-rule WEIGHT + the icon */
  .fi-callout { background: transparent; border-left-color: var(--color-text); border-left-width: 1px; }
  .fi-callout__icon,
  .fi-callout__title { color: var(--color-text); }
  .fi-callout--info,
  .fi-callout--ok,
  .fi-callout--tip      { border-left-width: 2px; }
  .fi-callout--warning  { border-left-width: 3px; }
  .fi-callout--danger   { border-left-width: var(--space-1); }
}
