﻿/* ===========================================================================
   Teleseminar — brand foundation
   ---------------------------------------------------------------------------
   Single source of truth for the 2026 identity: the five brand colours, Plus
   Jakarta Sans, and the two inverted visual modes (public / learning
   environment). Every other stylesheet — components.css first — consumes the
   custom properties defined here and never a raw hex. Loads after main.css
   and responsive.css so it can set the identity those two no longer own;
   components.css loads after this file and builds on it.

   No !important anywhere in this file: specificity is kept low on purpose so
   nothing below ever needs one to win.
   =========================================================================== */

:root {
    /* --- Brand constants — the five colours in the brand manual, never
       redefined per mode. Everything else on this page is derived from
       these five, either directly or through color-mix(). --------------- */
    --ts-blue: #18206F;
    --ts-blue-rgb: 24, 32, 111;
    --ts-periwinkle: #C8D7FC;
    --ts-periwinkle-rgb: 200, 215, 252;
    --ts-lavender: #E8EEFF;
    --ts-white: #FFFFFF;
    --ts-yellow: #FAA916;
    --ts-yellow-rgb: 250, 169, 22;

    /* Shades/tints derived from the constants above — never a new hue. */
    --ts-blue-dark: color-mix(in srgb, var(--ts-blue) 85%, black);      /* hover/active on Blue */
    --ts-blue-darker: color-mix(in srgb, var(--ts-blue) 70%, black);    /* pressed state */
    --ts-yellow-dark: color-mix(in srgb, var(--ts-yellow) 85%, black);  /* hover/active on Yellow */
    /* The two "lighter navy" panel tones the learning-environment screenshot shows
       nested on the Blue page background: the outer panel, then a slightly lighter
       tile tone nested inside it. */
    --ts-blue-panel: color-mix(in srgb, var(--ts-blue) 88%, white);
    --ts-blue-tile: color-mix(in srgb, var(--ts-blue) 78%, white);
    --ts-blue-rule: color-mix(in srgb, var(--ts-blue) 88%, white);      /* subtle separator on Blue */

    /* --- State & feedback colours ----------------------------------------
       The one exception to the five-colour rule (see docs/RESTYLING.md):
       green and red carry meaning the user cannot get any other way, so they
       survive the restyle. Each gets one value per mode — a colour that reads
       on a white progress ring is not the one that reads as text on Blue. */
    --ts-green: #1c7c4a;        /* public/light mode */
    --ts-green-on-blue: #58ce95; /* learn mode: lightened to stay legible on Blue */
    --ts-green-rgb: 28, 124, 74;
    --ts-red: #b3261e;          /* public/light mode; standardised value, see RESTYLING.md */
    --ts-red-on-blue: #f2867e;  /* learn mode: lightened to stay legible on Blue */
    --ts-red-rgb: 179, 38, 30;

    /* --- Typography --------------------------------------------------- */
    --ts-font: "Plus Jakarta Sans", "Segoe UI Variable Display", "Segoe UI",
               system-ui, -apple-system, "Inter", "Noto Sans", sans-serif;
    --ts-weight-body: 600;   /* SemiBold — the manual's body copy is SemiBold, not Regular */
    --ts-weight-heading: 700; /* Bold — section headings, sub-headings, buttons, nav */
    --ts-weight-display: 800; /* ExtraBold — page titles / hero headlines */
    --ts-tracking-tight: -0.02em; /* large headings are set tight, per the manual */

    /* --- Spacing scale (teleseminar.css naming) ------------------------ */
    --ts-space-2xs: 0.25rem;
    --ts-space-xs: 0.5rem;
    --ts-space-sm: 0.75rem;
    --ts-space-md: 1rem;
    --ts-space-lg: 1.5rem;
    --ts-space-xl: 2.5rem;
    --ts-space-2xl: 4rem;
    --ts-gutter: clamp(1rem, 4vw, 50px);

    /* Same scale, account.css's numbered naming — aliased so its ~700 lines
       of selectors do not need to be touched to consume the brand scale. */
    --ts-space-1: var(--ts-space-2xs);
    --ts-space-2: var(--ts-space-xs);
    --ts-space-3: var(--ts-space-md);
    --ts-space-4: var(--ts-space-lg);
    --ts-space-5: var(--ts-space-xl);

    /* --- Radius / shadow — one scale, replacing the two different ones
       teleseminar.css and account.css each declared under the same names. */
    --ts-radius: 0.55rem;
    --ts-radius-lg: 1rem;
    --ts-shadow-sm: 0 1px 2px rgb(var(--ts-blue-rgb) / 6%), 0 1px 3px rgb(var(--ts-blue-rgb) / 8%);
    --ts-shadow: 0 2px 10px rgb(var(--ts-blue-rgb) / 8%);
    --ts-shadow-md: 0 2px 4px rgb(var(--ts-blue-rgb) / 6%), 0 6px 16px rgb(var(--ts-blue-rgb) / 10%);
    --ts-shadow-raised: 0 8px 28px rgb(var(--ts-blue-rgb) / 14%);
    --ts-shadow-lg: 0 4px 8px rgb(var(--ts-blue-rgb) / 7%), 0 16px 40px rgb(var(--ts-blue-rgb) / 14%);

    --ts-ease: cubic-bezier(0.2, 0, 0.15, 1);
    --ts-transition: 0.18s var(--ts-ease);

    /* --- Focus ring — 3px Yellow, 2px offset, visible on both backgrounds. */
    --ts-focus-ring: 3px solid var(--ts-yellow-dark);
    --ts-focus-offset: 2px;
    --ts-focus: 0 0 0 3px rgb(var(--ts-yellow-rgb) / 45%);
}

/* ===========================================================================
   Mode tokens
   ---------------------------------------------------------------------------
   Same semantic names, inverted values. Everything in components.css (and
   main.css/responsive.css, once neutralised) reads these — never a raw hex —
   so tuning either mode in phase 2 means changing values here, not hunting
   selectors.

   Hard rule kept in both blocks: text inside a White surface is always Blue.
   --ts-surface / --ts-on-surface are paired and never redefined against each
   other.
   =========================================================================== */

.ts-mode-public {
    --ts-bg: var(--ts-white);
    --ts-bg-alt: var(--ts-lavender);
    --ts-surface: var(--ts-white);
    --ts-surface-alt: var(--ts-lavender);
    --ts-on-surface: var(--ts-blue);
    --ts-text: var(--ts-blue);
    --ts-text-muted: rgb(var(--ts-blue-rgb) / 70%);

    /* Blue lightened towards the page, for the second line of a two-line entry:
       a secondary detail that has to stay readable, not a disabled one. 5.6:1 on
       White, so it passes AA for body text.

       color-mix() and not rgb(var(--ts-blue-rgb) / 70%), which is what the line
       above tries and what does not work: --ts-blue-rgb is comma-separated
       ("24, 32, 111"), and the slash form of rgb() takes space-separated
       channels, so that declaration is invalid and drops. --ts-text-muted has no
       value at all on a light background because of it. Left in place here
       rather than fixed in passing: it is redefined further down for the blue
       background, where it does resolve, and untangling which of the two every
       reader of it wants is its own change. */
    --ts-ink-muted: color-mix(in srgb, var(--ts-blue) 70%, var(--ts-white));

    --ts-border: var(--ts-periwinkle);
    --ts-border-strong: var(--ts-blue);
    --ts-accent: var(--ts-yellow);
    --ts-on-accent: var(--ts-blue);
    --ts-rule: var(--ts-periwinkle);

    --ts-feedback-success: var(--ts-green);
    --ts-feedback-success-bg: color-mix(in srgb, var(--ts-green) 12%, white);
    --ts-feedback-success-border: color-mix(in srgb, var(--ts-green) 30%, white);
    --ts-feedback-error: var(--ts-red);
    --ts-feedback-error-bg: color-mix(in srgb, var(--ts-red) 6%, white);
    --ts-feedback-error-border: color-mix(in srgb, var(--ts-red) 22%, white);
    --ts-feedback-warning: var(--ts-yellow-dark);
    --ts-feedback-warning-bg: color-mix(in srgb, var(--ts-yellow) 14%, white);
    --ts-feedback-info: var(--ts-blue);
    --ts-feedback-info-bg: var(--ts-lavender);

    --ts-state-todo: var(--ts-blue);
    --ts-state-open: var(--ts-periwinkle);
    --ts-state-active: var(--ts-yellow);
    --ts-state-done: var(--ts-green);
}

.ts-mode-learn {
    --ts-bg: var(--ts-blue);
    --ts-bg-alt: var(--ts-blue-panel);
    --ts-surface: var(--ts-white);
    --ts-surface-alt: var(--ts-blue-tile);
    --ts-on-surface: var(--ts-blue);
    --ts-text: var(--ts-white);
    --ts-text-muted: var(--ts-periwinkle);
    --ts-border: var(--ts-blue-rule);
    --ts-border-strong: var(--ts-periwinkle);
    --ts-accent: var(--ts-yellow);
    --ts-on-accent: var(--ts-blue);
    --ts-rule: var(--ts-blue-rule);

    --ts-feedback-success: var(--ts-green-on-blue);
    /* rgba(x, y, z, a) and not rgb(x y z / a%): the channel tokens are comma-separated
       ("28, 124, 74"), and mixing that legacy form with the modern slash syntax is invalid CSS —
       the declaration is dropped and everything reading the token falls back to nothing. The two
       tints below are load-bearing now: the catalogue card takes its state colour from them. */
    --ts-feedback-success-bg: rgba(var(--ts-green-rgb), 0.18);
    --ts-feedback-success-border: transparent;
    --ts-feedback-error: var(--ts-red-on-blue);
    --ts-feedback-error-bg: rgb(var(--ts-red-rgb) / 20%);
    --ts-feedback-error-border: transparent;
    --ts-feedback-warning: var(--ts-yellow);
    --ts-feedback-warning-bg: rgba(var(--ts-yellow-rgb), 0.18);
    --ts-feedback-info: var(--ts-periwinkle);
    --ts-feedback-info-bg: var(--ts-blue-panel);

    --ts-state-todo: var(--ts-periwinkle);
    --ts-state-open: var(--ts-periwinkle);
    --ts-state-active: var(--ts-yellow);
    --ts-state-done: var(--ts-green-on-blue);
}

/* Body background/text flip with the mode; every other surface is a token. */
.ts-mode-public,
.ts-mode-learn {
    background-color: var(--ts-bg);
    /*color: var(--ts-text);*/
}

/* ===========================================================================
   Fonts — self-hosted Plus Jakarta Sans
   ---------------------------------------------------------------------------
   Replaces the @import in main.css, which fetched only these same three
   weights from Google's CDN inside a stylesheet loaded eleventh — blocking
   render and forcing the browser to synthesise any other weight requested.
   =========================================================================== */

@font-face {
    font-family: "Plus Jakarta Sans";
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("/fonts/plus-jakarta-sans/plus-jakarta-sans-v12-latin-600.woff2") format("woff2");
}

@font-face {
    font-family: "Plus Jakarta Sans";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("/fonts/plus-jakarta-sans/plus-jakarta-sans-v12-latin-700.woff2") format("woff2");
}

@font-face {
    font-family: "Plus Jakarta Sans";
    font-style: normal;
    font-weight: 800;
    font-display: swap;
    src: url("/fonts/plus-jakarta-sans/plus-jakarta-sans-v12-latin-800.woff2") format("woff2");
}

body {
    font-family: var(--ts-font);
    font-weight: var(--ts-weight-body);
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
    font-weight: var(--ts-weight-heading);
}

h1, .h1, .display-1, .display-2 {
    font-weight: var(--ts-weight-display);
    letter-spacing: var(--ts-tracking-tight);
}

/* The manual does not license 300/400/500 anywhere in the identity. */
body, p, span, div, li, td, th, label, input, select, textarea, button {
    font-weight: var(--ts-weight-body);
}

/* ===========================================================================
   Bootstrap variable overrides
   ---------------------------------------------------------------------------
   So Bootstrap's own components (buttons, forms, alerts, pagination) inherit
   the brand instead of being restyled one class at a time.
   =========================================================================== */

:root {
    --bs-font-sans-serif: var(--ts-font);
    --bs-border-radius: var(--ts-radius);
    --bs-border-radius-lg: var(--ts-radius-lg);
    --bs-primary: var(--ts-blue);
    --bs-primary-rgb: var(--ts-blue-rgb);
    --bs-success: var(--ts-green);
    --bs-danger: var(--ts-red);
    --bs-warning: var(--ts-yellow);
}

.ts-mode-public {
    --bs-body-color: var(--ts-blue);
    --bs-body-bg: var(--ts-white);
    --bs-link-color: var(--ts-blue);
    --bs-link-hover-color: var(--ts-blue-dark);
    --bs-border-color: var(--ts-periwinkle);
}

.ts-mode-learn {
    --bs-body-color: var(--ts-white);
    --bs-body-bg: var(--ts-blue);
    --bs-link-color: var(--ts-white);
    --bs-link-hover-color: var(--ts-periwinkle);
    --bs-border-color: var(--ts-blue-rule);
}

/* prefers-reduced-motion is already handled in components.css; nothing to
   duplicate here — this file sets tokens, not component behaviour. */
