/* FCS.Blazor — the shared theme token layer.
 *
 * Every FCS.Blazor control paints from the --fcs-* tokens below instead of naming colours itself, so
 * one definition decides how all of them follow the host's light/dark toggle. Before this existed
 * each control carried its own copy of the same dark palette as literals (#0d1117, #161b22,
 * #2b3742, #e7ecef, #9db2c8 …), which is why they all looked right in the Gallery — permanently
 * dark — and wrong on a light page.
 *
 * HOSTS MUST LINK THIS SHEET, and link it before their own, exactly as with fcs-splitview.css:
 *   <link href="_content/FCS.Blazor.Shared/fcs-theme.css" rel="stylesheet" />
 * Without it the tokens are undefined and controls fall back to their unstyled colours. A host with
 * its own palette overrides these properties on :root rather than editing each control's sheet.
 *
 * ── Why the tokens are mixed rather than taken straight from Radzen ────────────────────────────────
 *
 * Only a few Radzen custom properties actually invert between `standard` and `standard-dark`.
 * Measured on FCSSite 2026-08-31 (dark -> light):
 *
 *   --rz-base-background-color   #242527 -> #ffffff     inverts
 *   --rz-text-color              #eaebec -> #4f4f50     inverts
 *   --rz-text-secondary-color    #c9cacd -> #707072     inverts
 *   --rz-text-tertiary-color     #b0b2b5 -> #8d8e90     inverts
 *   --rz-base-100/200/300/400    #eaebec/#e1e2e3/#c9cacd/#b0b2b5 -> #f4f5f9/#e9eaed/#e0e1e4/#c9cacd
 *
 * The base ramp *changes*, but every value is a light grey in BOTH themes — so a border or surface
 * painted with --rz-base-300 stays near-white on a dark page. That is a real bug and not a subtle
 * one: it rendered a rgb(201,202,205) border around the IRC client on a #242527 background.
 * **Never paint with --rz-base-N00.**
 *
 * --rz-border-normal does invert correctly (#4f5154 -> #e9eaed) but it is a border SHORTHAND
 * (`width style colour`), not a colour. `border: var(--rz-border-normal)` is valid;
 * `1px solid var(--rz-border-normal)` expands to `1px solid 1px solid #hex` and the border silently
 * vanishes. Since it cannot be used for anything but a whole border, the border colour here is
 * derived instead, so the same value is available to outlines, dividers and box-shadows.
 *
 * The derivation is a mix of the two properties that do invert. The same formula is direction-correct
 * in both themes without a second rule: `color-mix(bg 94%, text)` is *lighter* than the page in dark
 * and *darker* than the page in light, because it always walks from the page colour toward the ink.
 * That is the whole reason one token layer can serve both themes.
 *
 * Accents come from Radzen's semantic colours, which are theme-independent by design and carry
 * their own contrast guarantees. */

:root {
  /* ── surfaces, in stacking order ───────────────────────────────────────────────────────────────── */
  /* The page itself. */
  --fcs-surface: var(--rz-base-background-color, #0d1117);
  /* A well *below* the page: transcripts, logs, code blocks. */
  --fcs-surface-sunken: color-mix(in srgb, var(--rz-base-background-color, #0d1117) 97%, var(--rz-text-color, #e7ecef));
  /* A panel *above* the page: head bars, cards, sidebars. */
  --fcs-surface-raised: color-mix(in srgb, var(--rz-base-background-color, #161b22) 94%, var(--rz-text-color, #e7ecef));
  /* Pointer feedback and the selected row. */
  --fcs-surface-hover: color-mix(in srgb, var(--rz-base-background-color, #1a222b) 90%, var(--rz-text-color, #e7ecef));
  --fcs-surface-active: color-mix(in srgb, var(--rz-base-background-color, #24303c) 84%, var(--rz-text-color, #e7ecef));

  /* ── lines ─────────────────────────────────────────────────────────────────────────────────────── */
  /* The frame of a control, against the page. */
  --fcs-border: color-mix(in srgb, var(--rz-base-background-color, #2b3742) 82%, var(--rz-text-color, #e7ecef));
  /* A divider *inside* a control, which should read as quieter than its frame. */
  --fcs-border-subtle: color-mix(in srgb, var(--rz-base-background-color, #232c36) 89%, var(--rz-text-color, #e7ecef));

  /* ── ink, brightest to faintest ────────────────────────────────────────────────────────────────── */
  --fcs-fg: var(--rz-text-color, #e7ecef);
  --fcs-fg-muted: var(--rz-text-secondary-color, #c6d2dd);
  /* Not --rz-text-tertiary-color: measured at 3.28:1 on the light theme's white, under the 4.5:1
     floor for body text. Mixing from --rz-text-color instead keeps a fixed *proportion* of ink, so
     both themes land in the same place — measured 4.7:1 light / 8.6:1 dark. */
  --fcs-fg-subtle: color-mix(in srgb, var(--rz-text-color, #9db2c8) 86%, var(--rz-base-background-color, #0d1117));
  /* Timestamps and other text that must recede without disappearing; same derivation, one step further. */
  --fcs-fg-faint: color-mix(in srgb, var(--rz-text-color, #5d6b78) 78%, var(--rz-base-background-color, #0d1117));

  /* ── semantic accents ──────────────────────────────────────────────────────────────────────────── */
  /* Fills, borders and icons — use these where the colour is a shape, not a word. */
  --fcs-accent: var(--rz-primary, #4c8eda);
  --fcs-on-accent: var(--rz-primary-contrast-color, #fff);
  --fcs-danger: var(--rz-danger, #e06c75);
  --fcs-warning: var(--rz-warning, #e5a04c);
  --fcs-info: var(--rz-info, #56b6c2);
  --fcs-success: var(--rz-success, #3fa7a0);

  /* ── the same accents as TEXT ──────────────────────────────────────────────────────────────────────
   * Radzen's semantic colours are picked to be legible as a fill with white on top, not as words on
   * the page, and several fail badly when used directly for text: --rz-info (#12a4f5) measures
   * 2.74:1 on the light theme's white, against a 4.5:1 floor. Mixing toward the theme's own text
   * colour keeps the hue recognisable while restoring contrast, and — as with the surfaces — the one
   * formula is direction-correct in both themes, darkening on light and lightening on dark.
   * **Use -ink whenever a semantic colour is the colour of a word.** */
  --fcs-accent-ink: color-mix(in srgb, var(--rz-primary, #4c8eda) 50%, var(--rz-text-color, #e7ecef));
  --fcs-danger-ink: color-mix(in srgb, var(--rz-danger, #e06c75) 50%, var(--rz-text-color, #e7ecef));
  --fcs-warning-ink: color-mix(in srgb, var(--rz-warning, #e5a04c) 50%, var(--rz-text-color, #e7ecef));
  --fcs-info-ink: color-mix(in srgb, var(--rz-info, #56b6c2) 50%, var(--rz-text-color, #e7ecef));
  --fcs-success-ink: color-mix(in srgb, var(--rz-success, #3fa7a0) 50%, var(--rz-text-color, #e7ecef));
  /* A wash of an accent behind text — the mix keeps it subtle on a light page and visible on a dark
     one, where a flat rgba() would wash out. */
  --fcs-warning-wash: color-mix(in srgb, var(--rz-warning, #e5a04c) 18%, var(--rz-base-background-color, #0d1117));
  --fcs-accent-wash: color-mix(in srgb, var(--rz-primary, #4c8eda) 16%, var(--rz-base-background-color, #0d1117));
  --fcs-danger-wash: color-mix(in srgb, var(--rz-danger, #e06c75) 16%, var(--rz-base-background-color, #0d1117));
  --fcs-success-wash: color-mix(in srgb, var(--rz-success, #3fa7a0) 16%, var(--rz-base-background-color, #0d1117));

  /* ── paper: a surface the *content* fixes, not the theme ───────────────────────────────────────────
   * Some controls render content that carries its own assumption of a light background and cannot be
   * inverted: a Graphviz SVG draws black edges and labels, and a rendered Typst page is a sheet of
   * paper. Following the page into dark mode would make the graph invisible and the document wrong.
   * These stay light in both themes deliberately — use them so that intent is legible, rather than
   * leaving a bare #fff that reads like an oversight. Chrome *around* the paper still uses the
   * ordinary surface tokens. (FCS.Blazor.Ghostty is the same idea in the other direction: an ANSI
   * palette is only meaningful on dark, so it pins its own surface in fcs-ghostty.css.) */
  --fcs-paper: #ffffff;
  --fcs-paper-sunken: #eef1f4;
  --fcs-on-paper: #111418;
  --fcs-on-paper-muted: #4a5560;
  --fcs-paper-border: #b8c2cc;

  /* ── shape and type ────────────────────────────────────────────────────────────────────────────── */
  --fcs-radius: var(--rz-border-radius, 8px);
  --fcs-radius-sm: calc(var(--fcs-radius) * 0.75);
  --fcs-font: var(--rz-text-font-family, Inter, ui-sans-serif, system-ui, sans-serif);
  --fcs-font-mono: "JetBrains Mono", "Cascadia Mono", SFMono-Regular, Menlo, Consolas, monospace;
}

/* ---------------------------------------------------------------- FcsTagCloud
 * Sizes only; the link colour is the host's primary, and a host with an accent of its own
 * overrides `.fcs-tag-cloud a` under its own class (the blog does). */
.fcs-tag-cloud {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.45rem;
}

.fcs-tag-cloud a {
  color: var(--rz-primary);
  line-height: 1.08;
  text-decoration: none;
}

.fcs-tag-cloud .fcs-tag-level-1 { font-size: 0.78rem; }
.fcs-tag-cloud .fcs-tag-level-2 { font-size: 0.92rem; }
.fcs-tag-cloud .fcs-tag-level-3 { font-size: 1.08rem; }
.fcs-tag-cloud .fcs-tag-level-4 { font-size: 1.3rem; }
.fcs-tag-cloud .fcs-tag-level-5 { font-size: 1.62rem; }

.fcs-tag-cloud a:hover,
.fcs-tag-cloud a:focus-visible,
.fcs-tag-cloud a.active {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
