/*
 * Katern — reader-facing design tokens
 *
 * app.katern.app only. The back office is vendored Tabler with its own
 * defaults; the edition is print typography for e-ink. Three systems, on
 * purpose. The only thing shared across all three is the name and wordmark.
 *
 * Foundation: Tabler (MIT, already vendored). These tokens are the layer
 * that makes the reader app a different product on the same framework —
 * palette, typeface, navigation shape.
 *
 * Direction approved 2026-10-12 against six real screens. Reference for the
 * register: the Vuexy admin template — roomy, cards, vertical sidebar,
 * colour present. Reference only, never its code: that is a paid ThemeForest
 * licence plus Bootstrap and a stack of JS libraries, and a commercial
 * template licence inside the product is a due-diligence question for a
 * business built to be sold.
 *
 * Rules, enforced by the guard test (see docs/design/reader-ui.md):
 *   - Reader-facing CSS and templates use these variables, mapped onto
 *     Tabler's own. Never a literal colour, font, size or tracking.
 *   - Every token is declared on bare :root below. A token that exists only
 *     inside a media query or a [data-theme] block is the classic
 *     unreadable-page bug.
 *   - Fonts are self-hosted from apps/web/static/web/vendor/, digests
 *     pinned. No third-party host, ever — the rule is about REQUESTS.
 */

:root {
  color-scheme: light;

  /* ---- ground and ink. Grey page, white cards: the dashboard pattern the
   *      approved reference uses. Deliberately NOT paper-coloured — a warm
   *      ground is what made the first attempt read as a newspaper. */
  --k-page:    #eef1f5;  /* the page behind everything */
  --k-card:    #ffffff;  /* cards, fields, the sidebar */
  --k-sunken:  #f6f8fa;  /* "what that means" panels only */
  --k-ink:     #1c2434;  /* headings, body */
  --k-ink-2:   #51586b;  /* secondary copy */
  --k-ink-3:   #656b7d;  /* labels, help text, meta
                          * CONTRAST RISK: this is the token that was wrong
                          * in the rejected attempt, for the same reason —
                          * it is specified for 14px text, where contrast
                          * matters most. Measured 2026-10-12: the specified
                          * #7c8396 was 3.79:1 on card, 3.34:1 on page.
                          * Now 4.69 page / 5.31 card / 4.99 sunken. The
                          * margin over 4.5 is DELIBERATE: #676e80 was the
                          * smallest passing value at 4.5004:1 on page, and
                          * a value four ten-thousandths above its floor
                          * turns the build red on any cosmetic change to
                          * the page colour. Do not "optimise" it back. */
  --k-line:    #dde2ea;  /* card borders and separators. Decoration, not a
                          * control boundary: outside WCAG 1.4.11, so it may
                          * stay faint. Never a field border; that is the
                          * next token. */
  --k-line-control: #878787;  /* field, select and textarea borders. A control
                          * boundary, so 3:1 on card and page: 3.59 / 3.17.
                          * Neutral on purpose. The smallest passing grey,
                          * #8b8b8b, sits at 3.007 on page; the margin is
                          * the same headroom rule as --k-ink-3. Visible
                          * field borders make the forms look heavier than
                          * the mockup, and that is CORRECT: the rejected
                          * attempt was rejected partly for being too faint.
                          * Do not lighten it to match --k-line. */

  /* ---- the brand. One accent, deep teal. Actions and links only; never a
   *      state. Chosen 2026-10-12 over deep navy and dusty blue-grey. */
  --k-accent:      #11606b;
  --k-accent-ink:  #ffffff;  /* text on --k-accent */
  --k-accent-soft: #e2f0f1;  /* the active navigation item */
  --k-accent-line: #b6d6d9;  /* accent-tinted rules */

  /* ---- states. Separate from the accent, always paired with text.
   *      --k-ok sits near 122deg; the accent near 187deg. That separation is
   *      deliberate: the first green (#1f7a4d, ~150deg) was close enough to
   *      the accent that an 8px dot beside a teal button muddled on scan.
   *      Guarded by a minimum hue distance, not by remembering. */
  --k-ok:    #2f7d32;
  --k-warn:  #96650a;
  --k-fail:  #a32d26;
  --k-focus: #11606b;

  /* ---- type. Source Sans 3 (OFL, self-hosted). The back office runs on
   *      Tabler 1.5.0's default, a system font stack; Source Sans 3 gives
   *      the reader app a face of its own. */
  --k-font: "Source Sans 3", system-ui, -apple-system, "Segoe UI", sans-serif;
  --k-mono: ui-monospace, SFMono-Regular, Menlo, monospace;

  --k-size-hero:  1.8125rem; /* 29px - the one number on a screen */
  --k-size-title: 1.5625rem; /* 25px - screen title */
  --k-size-lead:  1.1875rem; /* 19px - the value in a "what that means" panel */
  --k-size-card:  1.0625rem; /* 17px - card heading */
  --k-size-body:  1rem;      /* 16px - running text, controls, nav */
  --k-size-label: 0.9375rem; /* 15px - field labels, buttons */
  --k-size-help:  0.875rem;  /* 14px - help text, meta lines */
  --k-size-chip:  0.84375rem;/* 13.5px - state chips */

  --k-weight-normal: 400;
  --k-weight-medium: 500;
  --k-weight-bold:   600;  /* the heaviest weight in the app. There is no 700. */

  --k-leading-tight: 1.25;
  --k-leading-body:  1.6;

  --k-tracking-hero:  -0.02em;
  --k-tracking-title: -0.015em;
  --k-tracking-card:  -0.01em;

  /* ---- measure. Running text capped, including on a wide screen. */
  --k-measure: 70ch;

  /* ---- space. Roomy by decision: the rejected attempt was rejected for
   *      being compact, and card padding is where that is felt. */
  --k-space-1: 0.1875rem;
  --k-space-2: 0.375rem;
  --k-space-3: 0.625rem;
  --k-space-4: 0.875rem;
  --k-space-5: 1.25rem;   /* card padding */
  --k-space-6: 1.75rem;   /* main-panel padding */
  --k-space-7: 2.25rem;

  /* ---- shape */
  --k-radius-card: 10px;
  --k-radius-ctl:  8px;
  --k-radius-sm:   7px;
  --k-shadow: 0 1px 2px rgba(28, 36, 52, 0.06), 0 4px 12px rgba(28, 36, 52, 0.05);
  --k-border: 1px;
  --k-focus-width: 2px;
  --k-focus-offset: 1px;

  --k-sidebar: 236px;
}

/* Dark, for viewers whose OS asks for it and who have not chosen light.
   Only tokens are redefined here — never a component rule.
   Dark --k-ink-3 was specified as #848c9e: 4.32:1 on sunken. #8c94a5 gives
   4.78 sunken / 5.22 card / 5.83 page, with the same deliberate headroom as
   the light value (#888fa1 passed at 4.50, the same knife edge).
   Dark --k-line-control: smallest passing grey #6c6c6c was 3.03 on card;
   #6f6f6f gives 3.17 card / 3.54 page. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --k-page:   #15181f;
    --k-card:   #1e222c;
    --k-sunken: #242934;
    --k-ink:    #eef1f6;
    --k-ink-2:  #b4bbcb;
    --k-ink-3:  #8c94a5;
    --k-line:   #2e3440;
    --k-line-control: #6f6f6f;

    --k-accent:      #6fc0c8;
    --k-accent-ink:  #0c2124;
    --k-accent-soft: #1c3034;
    --k-accent-line: #2d4a4f;

    --k-ok:    #63bd68;
    --k-warn:  #d8a93f;
    --k-fail:  #e58b80;
    --k-focus: #6fc0c8;

    --k-shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 4px 14px rgba(0, 0, 0, 0.25);
  }
}

/* Dark, chosen explicitly. Same values; this block is what makes a toggle
   win over the OS preference in both directions. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --k-page:   #15181f;
  --k-card:   #1e222c;
  --k-sunken: #242934;
  --k-ink:    #eef1f6;
  --k-ink-2:  #b4bbcb;
  --k-ink-3:  #8c94a5;
  --k-line:   #2e3440;
  --k-line-control: #6f6f6f;

  --k-accent:      #6fc0c8;
  --k-accent-ink:  #0c2124;
  --k-accent-soft: #1c3034;
  --k-accent-line: #2d4a4f;

  --k-ok:    #63bd68;
  --k-warn:  #d8a93f;
  --k-fail:  #e58b80;
  --k-focus: #6fc0c8;

  --k-shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 4px 14px rgba(0, 0, 0, 0.25);
}

/* The page must paint its own ground. */
body {
  background: var(--k-page);
  color: var(--k-ink);
  font-family: var(--k-font);
  font-size: var(--k-size-body);
  line-height: var(--k-leading-body);
}

/* Keyboard focus is not optional on a surface made of forms. */
:where(a, button, input, select, textarea, summary):focus-visible {
  outline: var(--k-focus-width) solid var(--k-focus);
  outline-offset: var(--k-focus-offset);
}

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