/* ==================================================================
 * Sourced — Cobalt & Ivory design tokens
 * ------------------------------------------------------------------
 * CANONICAL SOURCE OF TRUTH for colour, type, spacing, border and
 * ornament values. Prose rules live in
 * sourced-docs/design-inputs/BRAND.md — read that before using these.
 *
 * RULES FOR AGENTS
 *   1. Never hard-code a hex value in a component. Use a token.
 *   2. Never add a token without adding it to BRAND.md too.
 *   3. Contrast ratios in the comments are measured, not guessed.
 *      If you change a value, re-measure before committing.
 *   4. Radius never exceeds 8px. See --radius-max.
 * ================================================================== */

:root {
  /* ---------------------------------------------------------------
   * COBALT — the brand colour. Ramp runs dark (950) to pale (50).
   * 800 is the "field": the app sidebar and footer chrome.
   * 600 is the interactive colour: buttons, links, focus.
   * 500 is decorative only unless contrast is rechecked for the surface.
   * ------------------------------------------------------------- */
  --cobalt-950: #06143a;
  --cobalt-900: #09205f; /* 14.42:1 on --paper — AAA */
  --cobalt-800: #0b2f8f; /* 10.98:1 on --paper — AAA. The field. */
  --cobalt-700: #1643b5; /*  7.97:1 on --paper — AAA. Dark links/chrome. */
  --cobalt-600: #2454d6; /*  6.02:1 on --paper — AA. Interactive. */
  --cobalt-500: #3f6eec; /*  4.29:1 on --paper — large text/decorative only. */
  --cobalt-400: #7193f3; /* decorative only — fails as body text on paper */
  --cobalt-300: #9db4f7; /* 7.45:1 on --cobalt-900 — for text on field */
  --cobalt-200: #c6d3fb; /* 7.76:1 on --cobalt-800 — for text on field */
  --cobalt-100: #e0e7fe;
  --cobalt-50:  #eff4ff;

  /* ---------------------------------------------------------------
   * PAPER — cool ivory. The content surface. Never pure white for
   * marketing; --paper-0 exists only for print/export and dense
   * data surfaces that need maximum legibility.
   * ------------------------------------------------------------- */
  --paper-0: #ffffff;
  --paper:   #f7f9ff; /* default page + card surface */
  --ivory:   #f7f9ff; /* immutable alias of --paper. Exists so .on-field
                         can remap --paper to cobalt while text tokens
                         still reach the original ivory value. Never
                         remap or redefine this one. */
  --paper-2: #eef3fb; /* recessed / alternating rows / app chrome */
  --paper-3: #e2e9f5; /* wells, code blocks, disabled fills */
  --paper-4: #d3ddea; /* heaviest tint, use sparingly */

  /* ---------------------------------------------------------------
   * INK — blue-black text. Deliberately NOT pure black: the whole
   * palette sits in a cool cast and #000 reads as a foreign object.
   * ------------------------------------------------------------- */
  --ink:   #111827; /* 16.85:1 on --paper — AAA. Body + headings.   */
  --ink-2: #334155; /*  9.84:1 on --paper — AAA. Secondary text.    */
  --ink-3: #55637a; /*  5.78:1 on --paper — AA.  Muted / captions.  */
  --ink-4: #7b879a; /*  3.45:1 on --paper — NON-TEXT ONLY.          */
                    /*   Disabled controls, hairline glyphs, icons. */
                    /*   Never use for body copy at any size.       */

  /* ---------------------------------------------------------------
   * RULES & BORDERS
   * --rule / --rule-strong are DECORATIVE hairlines (below 3:1).
   *   Legal for table gridlines and section dividers, where the
   *   boundary is not the only way to perceive the content.
   * --border-input is the INTERACTIVE border. It meets 3:1 and is
   *   required on anything a user must locate to operate:
   *   text inputs, selects, checkboxes, segmented controls.
   * ------------------------------------------------------------- */
  --rule:         #d7dfec; /* 1.27:1 — decorative hairline */
  --rule-strong:  #b8c3d6; /* 1.69:1 — decorative, emphasis */
  --border-input: #6f7f9e; /* 3.83:1 on --paper — meets WCAG 1.4.11 */
  --rule-cobalt:  rgba(36, 84, 214, 0.16); /* cool tint divider */

  /* ---------------------------------------------------------------
   * SEMANTIC — quiet operational inks, not SaaS traffic lights.
   * Success and warning stay cool; error is the only warm interrupt.
   * All ≥5:1 on --paper and --paper-2.
   * ------------------------------------------------------------- */
  --verdigris:      #315f70; /* 6.65:1 — success / passing */
  --verdigris-soft: #e5eef4;
  --ochre:          #59657d; /* 5.57:1 — warning / review / pending */
  --ochre-soft:     #e8edf6;
  --oxide:          #95424b; /* 6.32:1 — error / failed / blocked   */
  --oxide-soft:     #f1e5e8;
  --cobalt-soft:    var(--cobalt-50); /* informational */

  /* ---------------------------------------------------------------
   * TYPOGRAPHY (BRAND v2)
   * --font-sans     Inter Tight. Headlines AND body/UI. Headlines:
   *                 600, tight tracking, sentence case, never caps.
   * --font-mono     JetBrains Mono. Code, data, labels, metrics,
   *                 small uppercase eyebrow/table labels.
   * --font-display  Martian Mono. The wordmark and at most one
   *                 small brand moment per page. Never headlines.
   *
   * There is deliberately NO serif display face. See BRAND.md §3.
   * ------------------------------------------------------------- */
  --font-display: "Martian Mono", "JetBrains Mono", ui-monospace, monospace;
  --font-sans: "Inter Tight", "Inter", ui-sans-serif, system-ui, -apple-system,
    BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono: "JetBrains Mono", "SFMono-Regular", ui-monospace, Consolas,
    "Liberation Mono", monospace;

  /* Display is set tight and in caps; it needs negative tracking at
     large sizes and positive tracking at small sizes. */
  --display-tracking-lg: -0.02em;
  --display-tracking-sm: 0.06em;

  /* Type scale — 1.25 minor third, clamped for fluid sizing. */
  --text-hero:  clamp(34px, 4.5vw, 56px);
  --text-h1:    clamp(28px, 3.4vw, 40px);
  --text-h2:    clamp(23px, 2.4vw, 30px);
  --text-h3:    20px;
  --text-lede:  18px;
  --text-body:  15px;
  --text-sm:    13px;
  --text-xs:    11px;

  /* ---------------------------------------------------------------
   * GEOMETRY — crisp frames, not soft SaaS cards.
   * ------------------------------------------------------------- */
  --radius-max: 8px; /* HARD CEILING. Nothing may exceed this. */
  --radius-lg:  8px; /* modals, hero panels */
  --radius:     4px; /* default: cards, inputs, buttons */
  --radius-sm:  2px; /* chips, tags, swatches */
  --radius-none: 0;  /* engraved plate frames are always square */

  --hairline: 1px;
  --container: 1200px;
  --container-prose: 720px;

  /* Spacing — 4px base. */
  --space-1: 4px;   --space-2: 8px;   --space-3: 12px;
  --space-4: 16px;  --space-5: 24px;  --space-6: 32px;
  --space-7: 48px;  --space-8: 64px;  --space-9: 96px;

  /* ---------------------------------------------------------------
   * ELEVATION — an engraved plate sits ON paper; it does not float.
   * Shadows are tight, cool-tinted and nearly invisible. If a
   * shadow is legible as a shadow, it is too strong.
   * ------------------------------------------------------------- */
  --shadow-plate: 0 1px 0 rgba(9, 32, 95, 0.03),
                  0 12px 32px -26px rgba(9, 32, 95, 0.24);
  --shadow-raised: 0 1px 0 rgba(9, 32, 95, 0.05),
                   0 24px 60px -36px rgba(9, 32, 95, 0.34);

  /* Focus — cobalt halo. Must be visible on paper AND on the field. */
  --focus-ring: 0 0 0 3px rgba(36, 84, 214, 0.3);
  --focus-ring-on-field: 0 0 0 3px rgba(198, 211, 251, 0.55);

  /* ---------------------------------------------------------------
   * ORNAMENT — engraved textures. OFF BY DEFAULT since BRAND v2:
   * zero ornament on standard pages; at most one faint brand moment
   * on rare surfaces (404, empty workspace). See BRAND.md §4.
   * ------------------------------------------------------------- */
  --ornament-hatch:      url("/brand/ornaments/hatch-45.svg");
  --ornament-crosshatch: url("/brand/ornaments/crosshatch.svg");
  --ornament-stipple:    url("/brand/ornaments/stipple.svg");
  --ornament-opacity-faint:  0.06; /* large fills, page washes */
  --ornament-opacity-soft:   0.12; /* panel backgrounds */
  --ornament-opacity-strong: 0.22; /* small accents only */

  --motion-fast: 0.15s ease;
  --motion: 0.24s cubic-bezier(0.2, 0.7, 0.3, 1);
}

/* ==================================================================
 * FIELD CONTEXT
 * Wrap any deep-cobalt section in .on-field. It remaps the text and
 * border tokens so descendant components stay legible without every
 * component needing its own dark-mode branch.
 * ================================================================== */
.on-field {
  /* NOTE: --ink must reference --ivory, not --paper. Custom properties
     declared on the same element see each other's final values, so
     --ink: var(--paper) here would resolve to cobalt-800 and render
     text invisible on the field. */
  --ink: var(--ivory);
  --ink-2: var(--cobalt-200);
  --ink-3: var(--cobalt-300);
  --ink-4: var(--cobalt-400);
  --paper: var(--cobalt-800);
  --paper-2: var(--cobalt-900);
  --paper-3: var(--cobalt-950);
  --rule: rgba(198, 211, 251, 0.22);
  --rule-strong: rgba(198, 211, 251, 0.38);
  --border-input: var(--cobalt-300);
  --focus-ring: var(--focus-ring-on-field);
  background: var(--cobalt-800);
  color: var(--ivory);
}

/* ==================================================================
 * PRIMITIVES
 * The small set of shared classes every surface may rely on.
 * ================================================================== */

/* Engraved divider with a centred fleuron. Marketing sections only —
   the dashboard uses a plain 1px --rule. */
.fleuron-rule {
  display: block;
  width: 100%;
  height: 16px;
  border: 0;
  color: var(--cobalt-700);
  background: center / 320px 16px no-repeat
    url("/brand/ornaments/rule-fleuron.svg");
  opacity: 0.55;
}

/* Engraved plate frame: double rule, square corners. The marketing
   alternative to a rounded card. */
.plate {
  position: relative;
  border: 1px solid var(--cobalt-700);
  border-radius: var(--radius-none);
  background: var(--paper);
  padding: var(--space-6);
}
.plate::after {
  content: "";
  position: absolute;
  inset: 5px;
  border: 1px solid var(--rule-cobalt);
  pointer-events: none;
}

/* A texture wash. Apply to a positioned parent. */
.hatched::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--ornament-crosshatch);
  opacity: var(--ornament-opacity-faint);
  pointer-events: none;
}

/* ==================================================================
 * ACCESSIBILITY FLOOR — non-negotiable.
 * ================================================================== */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--cobalt-600);
  outline-offset: 2px;
  box-shadow: var(--focus-ring);
  border-radius: var(--radius-sm);
}
.on-field
  :where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline-color: var(--cobalt-200);
}

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

/* Ornament is decoration. At high contrast, remove it entirely
   rather than letting it interfere with text. */
@media (prefers-contrast: more) {
  .hatched::before,
  .fleuron-rule {
    display: none;
  }
  :root {
    --rule: var(--border-input);
    --ink-3: var(--ink-2);
  }
}
