/* ============================================================
   SERAC — Shared design tokens
   ============================================================
   Single canonical source for color, spacing, typography, radius and
   shadow tokens shared by the trainer backoffice, trainer login, the
   client app and (going forward) the admin content backoffice. Pair
   this file with `shared/ui-primitives.css`, which defines the
   reusable component classes (buttons, fields, badges, tabs, empty
   states, toasts, modals) built on top of these tokens, and with
   `shared/fonts.css`, which declares the self-hosted @font-face rules
   for the two families referenced below.

   ── Design philosophy (2026-09 "Oysho-style" pass) ─────────────
   SERAC's chrome carries almost no color of its own — ink on neutral
   paper, restrained the way an editorial layout is restrained, so
   that a photograph (an exercise, a trainer's own cover image) is
   always the most saturated thing on the screen. This is deliberate,
   not an aesthetic borrowed for its own sake: a chrome with near-zero
   color has nothing for a per-trainer accent color to clash with. See
   "Ownership" below — this is what makes a future per-trainer accent
   safe to hand over as an open color picker instead of a validated,
   restricted one.

   Interfaces are primarily neutral. Brand accent (--primary) is a
   restrained accent, not the default color of every interaction — it
   is reserved for branding, navigation indicators, links, focus and
   small marker shapes (an active chip's dot, a progress ring, an
   underline). Budget it at roughly 5% of any screen's pixels. It is
   NOT the fill for buttons, avatars, active chips/tabs, selected rows
   or any text/icon that needs guaranteed contrast against it — see
   "Ownership" below for why that restriction is exactly what lets it
   later become an open, per-trainer color choice.

   Selection is a SURFACE, never the accent (Planning D3 / Phase 2.1,
   DS.1 — supersedes the earlier "ink as a border/marker only" rule).
   Anything that means "this one is selected/active" — the selected
   calendar day, the active nav item, a chosen row — sits on a
   surface one step denser than its neighbours (--surface-selected for
   a day/tile, --surface-day for a nav item), optionally with a short
   ink rule (--action) as the one strong mark. Never a brand-colour
   tint, never a thick dark border, never an inverted black block.
   Colour inside content means status (success/warning/danger/attention
   tints) or the brand marker — never generic interaction state.

   Hierarchy comes from typography, spacing and alignment before
   containers, colors or decoration. Then, in this order of "weight":
   spacing → surface → hairline → border → card. A card (bordered,
   on --bg-card) is used only for an independent floating object (a
   list inside an overlay, an invite link); --surface* (filled, no
   border) is the paper a *group with meaning* sits on — the selected
   day's detail, a session block, a notes panel; a hairline separates
   siblings INSIDE a surface or a flat list; plain spacing separates
   sections on the page. See Project/docs/DESIGN_SYSTEM.md.

   Media is never rounded. --radius-media is 0 — a photograph, a hero
   banner, a catalogue tile reads as a straight-edged image, the way a
   printed photograph does. Rounding is spent on controls instead
   (chips, buttons, inputs, cards) via the existing xs/sm/md/lg scale.
   Pills (--radius-full) stay reserved for tags, filters and small
   status/metadata labels — not normal buttons or containers.

   Primary actions (Guardar, Crear, Empezar…) use solid ink
   (--action), not the brand accent — see --action below. The accent
   stays reserved for the cases listed above.

   Shadows are almost never used — only for floating surfaces (modal,
   dropdown, popover). Normal cards/panels/navigation rely on
   surface + border + spacing, not elevation.

   ── Ownership — per-trainer branding ─────────────────────────────
   Branding is a separate semantic layer (--brand-* at the end of :root,
   DS.1) consumed only by what the trainer's CLIENTS see; the trainer
   backoffice always renders the canonical ink-on-paper language and is
   never themed. --primary's --brand-accent indirection predates that
   layer and is kept only so nothing breaks; new work never reads it.
   ── ───────────────────────────────────────────────────────────

   Color values were originally verified byte-for-byte against the
   trainer and admin dashboards' previous local :root blocks before
   extraction, then deliberately adjusted three times since: the 2026-08
   visual refinement pass (neutral scale, brand blue, radius scale),
   the 2026-09 pass (display type, radius-by-role, self-hosted type), and
   the "neutro-teal" scale chosen on device on 2026-09-17, which replaced
   the earlier warm scale on every platform at once. The colour values are a
   cross-platform contract by token name: iOS pins them in
   NewLaifV2Tests/DesignSystem/TokensTests.swift, and a colour changes there
   and here in the same change. See Project/docs/DESIGN_SYSTEM.md.

   The client-facing app (client/user-routine) links this file too
   (shared tokens + shared/ui-primitives.css + shared/fonts.css), then
   layers its own additional app-specific tokens/overrides in its own
   styles.css.

   Apps that use these tokens still keep their own *additional*,
   app-specific tokens (e.g. trainer's --surface-2/--surface-3, admin's
   --draft/--published) declared locally in their own styles.css.
   ============================================================ */

:root {
    /* ── Color — neutral scale ("neutro-teal": near-achromatic, a hair warm
       of pure grey; the only hue is --accent) ── */
    --bg: #fbfbfa;
    --bg-card: #ffffff;
    /* The page is a hair off-white (--bg); cards and floating surfaces are
       pure white, so a card reads as an object on the page without a shadow. */
    --bg-elevated: #ffffff;

    /* The "paper" fill for a block that groups content without being
       an independent floating object — a metadata panel, a selected pill,
       a filter tab's active background. Distinct from --bg-card (a bordered
       card = an object) and reused for hover feedback (--bg-hover) so a
       hovered row settles on the same paper tone as a static block.
       DS.1: aliased to --surface-day (was a near-duplicate #f5f2ea) so the
       whole system has exactly one "content paper" tone. */
    --surface: var(--surface-day);
    --bg-hover: var(--surface);

    /* DS.2A (2026-09) — neutral-scale/role-separation pass, art direction
       review §23: the whole 100→82 L* range used to compress every surface
       (quiet/day/selected) and the hairline into ~11 points, so the
       selected day and a 1px border measured the same lightness (ΔE 3) and
       --surface-quiet was imperceptible against white (ΔE 2.3) — "selected
       states demasiado débiles", "sensación lavada". This border/border-
       strong step and the surface/text steps below it are widened;
       nothing here changes rhythm, spacing or which role uses which
       token, only how far apart the roles actually sit. */
    --border: #e4e4e1;
    /* More definition than --border — table headers, section dividers,
       anywhere a hairline needs to read as structural rather than soft. */
    --border-strong: #c8c8c4;
    /* WEB-ONLY (not in the iOS-pinned table): outline of an interactive control
       (input, select, textarea). #8c8d88 = 3.2:1 on --bg and 3.4:1 on white, the
       WCAG 1.4.11 non-text minimum that --border/--border-strong cannot meet.
       Decorative hairlines and cards keep --border. */
    --border-control: #8c8d88;

    /* ── Semantic text hierarchy (final color/typography pass, art direction
       §23) — five roles, deliberately not five new tokens: --text/
       --text-secondary/--text-light/--text-on-inverse already exist and
       already carry the "primary/secondary/tertiary/inverse" roles below;
       adding --text-primary etc. as aliases would just duplicate them.
       Typography (shared/ui-primitives.css §3 roles, DESIGN_SYSTEM.md) sets
       size/weight — these four tokens are the only place colour is decided.

         text-primary   → --text            titles, item titles, body
         text-secondary → --text-secondary  subtitle, metadata, body-secondary
         text-tertiary  → --text-light      caption / hint / placeholder
         text-disabled  → --text-disabled   disabled controls only (below)
         text-inverse   → --text-on-inverse (declared further down)

       #17140f (the pre-DS.2A ink) read as "pure black" at any real size —
       already softened once to #1c1c1a; this pass softens it again, since
       Carlos's own read was still "demasiado negra, demasiado bold". Body
       text and disabled tone are new deliberate concerns here; --action
       (buttons, filled surfaces) is untouched on purpose — a CTA is allowed
       to read stronger than a paragraph. */
    --text: #1c1c1b;
    --text-secondary: #63645f;
    /* Tertiary: caption / hint / placeholder — sub-4.5:1 by design, never
       body copy and never functional text (labels, counts, dates, status): that
       uses --text-secondary. Pinned by iOS; do not darken here alone. Distinct from --text-disabled (lighter still, below) now
       that disabled state has its own dedicated tone instead of sharing
       this one. */
    --text-light: #8c8d88;
    /* Disabled controls only (new, final pass) — WCAG SC 1.4.3 explicitly
       exempts inactive/disabled UI components from any contrast minimum,
       so this is deliberately lighter than --text-light: a disabled label
       should read as "not available", not merely "quiet". */
    --text-disabled: #b3b4af;

    /* Brand accent — restrained, used for branding, navigation
       indicators, links, focus and small marker shapes only. Not the
       default fill for buttons/avatars/active chips/text (see
       --action below for that, and "Ownership" above for why the
       restriction matters). Indirected through --brand-accent so a
       future per-trainer theme can override one custom property at
       runtime; --brand-accent is intentionally left undeclared here so
       this resolves to the same #2563eb it always has until that
       override exists. */
    --primary: var(--brand-accent, #2563eb);
    --primary-hover: #1d4ed8;

    /* The language's own accent (neutro-teal, 2026-09-17, shared by name with iOS/Android —
       NewLaifV2Tests/DesignSystem/TokensTests.swift is the contract). Spent only on a sanctioned
       marker ("today"); never a title, never a button, never selection. --primary above keeps
       its focus/link role (focus stays blue on every platform, --focus-ring). */
    --accent: #0f766e;
    --accent-fg: #ffffff;

    /* Primary *action* (buttons: Guardar, Crear, Empezar…) — solid ink,
       deliberately distinct from --primary/the brand accent. This is the
       fill `.btn-primary` uses; --primary above stays reserved for
       brand/nav/link/focus/marker usage. Deliberately NOT re-softened
       alongside --text in the final color/typography pass — this is a
       surface/fill role (a button, the active segment, the avatar
       background), out of that pass's scope, and a CTA is allowed to read
       a touch stronger than a paragraph of body text. */
    --action: #1c1c1b;
    --action-hover: #333331;

    --danger: #b53f3f;
    --success: #1e7a45;
    --warning: #c97908;

    /* Phase 2 of TRAINER_UI_UX_MIGRATION_PLAN.md (Planning → D3) — the
       surface roles D3 validated in the prototype. A day WITH training gets
       a paper fill; an empty/rest day sits almost on the page (a
       hairline keeps the week's geometry); the selected day is the one
       strong moment. --surface-inverse is deliberately just --action — the
       "Dark" selection reuses the same ink every primary button already
       uses, not a new color. */
    --surface-day: #f3f3f1;
    --surface-day-hover: #ececea;
    --surface-quiet: #f7f7f5;
    --surface-quiet-line: #e4e4e1;
    /* Chrome (color system simplification pass, 2026-09) — the app's own
       frame (today: the trainer sidebar only), not a content surface at
       all. DS.2A made the sidebar --surface-quiet, which read as "one more
       beige panel" next to a white page; this sits a full step closer to
       --bg than --surface-quiet does, so the shell differentiates itself
       from the page through structure/hairline/navigation, not a color
       block. Never used for a content surface — that's still the day/
       quiet/selected/media roles below. */
    --surface-chrome: #ffffff;
    /* Neutral media container (DS.2A) — a thumbnail/placeholder square is
       content-agnostic chrome, not "paper with content on it"; sharing
       --surface-day with an actual day-with-training/selected-fill role
       made every thumbnail read as one more beige surface instead of a
       plain frame around a photo. One step past --surface-day-hover. */
    --surface-media: #e9e9e6;
    /* The one inverted surface (ink) — a "today" badge, an active segment,
       a primary button. Same value as --action on purpose: DS.1 names the
       role, it does not add a colour. */
    --surface-inverse: var(--action);
    /* This is the "text-inverse" role of the semantic hierarchy declared
       above — kept under its established name rather than duplicated
       under a new one. */
    --text-on-inverse: #ffffff;
    --text-on-inverse-secondary: #a1a19c;

    /* Selected day/tile fill — replaces the old light-blue
       tint (#eef2ff), which had zero real usage left in the trainer app
       after the 2026-09 "Menos Azul" pass; still used by Client's calendar
       "current week" row highlight and session-order badge, which inherit
       this same value with no behavior change beyond the repaint. */
    --surface-selected: #e4e4df;

    /* Status colors used with a glyph + word (never color alone) —
       terracota for "needs attention/in progress", green for completed,
       red for skipped. Ink (--text) covers pending/seen; no token needed. */
    --status-progress: #a5502f;
    --status-done: #1e7a45;
    --status-skipped: #b53f3f;

    /* Restrained status tints for badges/pills — same computed colors
       already used ad hoc across the trainer app (tag-public/-pending/
       -rejected), now named so both apps read from one place instead of
       repeating hex literals. These three are SEMANTIC (success/warning/
       danger) and never follow branding. */
    --success-bg: #dcfce7;
    --success-text: #166534;
    --warning-bg: #fef3c7;
    --warning-text: #92400e;
    --danger-bg: #fee2e2;
    --danger-text: #b91c1c;
    /* "info" and "neutral" are NOT statuses — they label ownership/context
       ("SERAC", "Plantilla", a goal category). DS.1 retargets both onto
       the paper scale (they were a purple and a cool grey, the only
       two chromatic accents left outside the ink-on-paper language). */
    --info-bg: var(--surface-selected);
    --info-text: var(--text);
    --neutral-bg: var(--surface-day);
    --neutral-text: var(--text-secondary);

    --disabled-opacity: 0.5;
    --target-min: 32px;   /* min height of a text-only control (#36); touch grows it to 44 via ::after */
    --focus-ring: 0 0 0 3px rgba(37, 99, 235, 0.28);
    --danger-hover: #9e3434;
    --border-width: 1px;

    /* ── Z-index scale — six named layers instead of raw literals scattered
       1 → 10000 across the codebase. Values match what the app already used
       at each layer (see Project/docs/DESIGN_SYSTEM.md), so adopting this
       scale is zero-diff wherever it replaces a literal. ── */
    --z-base: 1;        /* a small in-place raise above a sibling, e.g. a
                            lightbox's own close/arrow buttons */
    --z-dropdown: 20;   /* an absolutely-positioned menu/popover */
    --z-sticky: 40;     /* a fixed/sticky chrome bar, e.g. the mobile topbar */
    --z-modal: 100;
    --z-toast: 200;
    --z-lightbox: 10000; /* above everything, incl. a modal it was opened from */

    /* ── Motion — two durations, one easing. Most of the app's existing
       transitions already use one of these two values; this just names
       them. Deliberately no --duration-slow: a third tier wasn't worth
       adding for the couple of call sites (e.g. the toast's 0.3s slide)
       that don't cleanly fit either value — those stay as local literals. ── */
    --duration-fast: 150ms;
    --duration-base: 200ms;
    --ease-standard: ease;

    /* ── Line-height — two values; most existing line-heights already
       cluster near one of these. Not a full scale — most body text sets
       its own line-height locally and that's fine (spec: hierarchy comes
       from type/spacing, not from a rigid line-height system). ── */
    --leading-tight: 1.3;
    --leading-normal: 1.5;

    /* Letter-spacing for a small uppercase label (badge, section eyebrow) —
       one value, not a scale; body text never needs tracking. */
    --tracking-wide: 0.03em;
    /* Letter-spacing for a large, bold display heading set in --font-display
       (Archivo) — tightened so big type doesn't look loose. */
    --tracking-tight: -0.02em;

    /* ── Spacing scale (4/8/12/16/24/32/48) ── */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 24px;
    --space-6: 32px;
    --space-7: 48px;

    /* ── Page + rhythm (DS.1) — the frame every screen sits in. The
       trainer's .main and the dev showcase consume these; the client app
       keeps its own narrower frame (a phone-first surface). ── */
    --page-max-width: 1280px;
    --page-gutter: 24px;
    /* Editorial reading measure (Phase 5.1, refined): the shell may be 1280
       wide, a session's blocks/rows/prescriptions are not. Evaluated at the
       shell's actual available width behind the 208px sidebar: 1184 at
       1440 (1000 leaves a deliberate 184px gutter, not a full-bleed table)
       and 1024 at 1280 (the measure simply clamps to the shell there — no
       visible seam). A header keeps the full shell width; the body sits in
       this. */
    --reading-max-width: 1000px;
    --section-gap: var(--space-6);   /* between sections on the page */
    --surface-pad: var(--space-5);   /* inside a surface */
    --row-pad: 14px;                 /* vertical padding of a list row */

    /* ── Radius scale — restrained, no pill-everything.
       small/normal/large only; anything above --radius-md needs a
       real reason (e.g. a floating modal panel). ── */
    --radius-xs: 4px;  /* small — chips, small tags, thumbnails */
    --radius-sm: 6px;  /* normal — buttons, inputs, badges */
    --radius-md: 8px;  /* large — cards, containers, modals, lists */
    --radius-lg: 8px;  /* kept as a distinct name for the couple of
                           call sites that already reference it
                           (.list, .modal-panel) — same value as
                           --radius-md on purpose, containers should
                           rarely exceed 8px */
    --radius-full: 999px; /* true pill — tags, filter chips, small status/
                              progress indicators only, per the radius
                              scale's own doctrine above; never a button
                              or a container */
    /* Photographic/media content — a hero banner, a catalogue tile, an
       exercise thumbnail — is never rounded. Straight edges are what
       make a photo read as content instead of a decorated container;
       rounding stays reserved for controls (above). */
    --radius-media: 0;

    /* ── Typography ──
       Two self-hosted families (shared/fonts.css): Archivo for display/
       heading use (--font-display, weights 600/700/800 only — it is
       never used for running text) and Inter Tight as the interface
       workhorse (--font-sans, weights 400–700 — replaces the former
       system-font stack app-wide so Trainer and Client render the same
       typeface instead of two different ones). Both fall back to the
       system stack if the self-hosted files fail to load. */
    --font-display: 'Archivo', 'Inter Tight', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
    --font-sans: 'Inter Tight', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;

    /* Dense/interface scale — body text, meta, controls. Used as-is by
       the trainer backoffice (a tool, read at a desk) and by secondary
       text everywhere. */
    --text-xs: 11px;   /* small/meta, uppercase labels */
    --text-sm: 12px;   /* meta, hints */
    --text-base: 13px; /* secondary body */
    --text-md: 14px;   /* body, card/item title */
    --text-lg: 16px;   /* section title */
    --text-xl: 20px;   /* page title */
    --text-2xl: 24px;  /* rare, large page heading */

    /* Display scale — set in --font-display, weight 700–800. Used where
       a screen has one clear headline moment: the client's hero-style
       screens (Hoy, invitación, portada de reto) and a big at-a-glance
       number (execution weight/reps, a stat tile). The trainer
       backoffice reaches for --display-sm at most — it stays a dense
       tool, not a consumer surface (see Project/docs/DESIGN_SYSTEM.md,
       "riesgo 2"). */
    --text-3xl: 32px;    /* large stat/number display (e.g. "5,62 km") */
    --display-sm: 28px;  /* section/page display heading, dense contexts */
    --display-md: 40px;  /* client hero headline */
    --display-lg: 52px;  /* rare — full-bleed cover (invite, onboarding) */

    --font-regular: 400;
    --font-medium: 500;
    --font-semibold: 600;
    --font-bold: 700;
    --font-extrabold: 800; /* --font-display only */

    /* ── Shadow — almost none, used only for floating surfaces ── */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);

    /* ── Brand theme layer (DS.1 / plan Phase 0A) — what a trainer's
       CLIENTS will see, never the trainer backoffice. Six semantic tokens;
       the defaults below are the "neutral" palette (= the canonical ink-on-
       paper language), so with no theme applied nothing changes anywhere.
       Consumers: the client app's chrome (Phase 9), never .btn-primary/
       .sr-status/text/typography/spacing here. Palettes live in
       shared/brand-palettes.js (registry only — no selector, no apply
       function yet). Status colours above never follow these. ── */
    --brand-primary: #1c1c1b;
    --brand-secondary: #63645f;
    --brand-background: #fbfbfa;
    --brand-surface: #f3f3f1;
    --brand-on-primary: #ffffff;
    --brand-border: #e4e4e1;
}

@media (max-width: 767px) {
    :root { --page-gutter: 16px; }
}
