/* tokens.css -- the ONE source of BC Academy design tokens.
   Extracted from app.css 2026-08-26. Loaded by frontend/app.html AND,
   via /mobile/theme.css, by every page under mobile/www/.

   Put NOTHING here but font-face declarations and :root custom properties. Layout,
   components and media queries belong in the stylesheet that uses them.
   A second copy of these values is the bug this file exists to retire --
   see the phone's theme.css, which drifted 60 of 73 shared tokens. */

@font-face { font-family: 'TT Directors'; src: url('/static/fonts/TTDirectorsDEMOBL-Regular.ttf') format('truetype'); font-weight: 400 900; font-display: swap; }
@font-face { font-family: 'DIN Next'; src: url('/static/fonts/DINNextCYR-Regular.otf') format('opentype'); font-weight: 400; font-display: swap; }
@font-face { font-family: 'DIN Next'; src: url('/static/fonts/DINNextCYR-Medium.otf') format('opentype'); font-weight: 500; font-display: swap; }
@font-face { font-family: 'DIN Next'; src: url('/static/fonts/DINNextCYR-Bold.otf') format('opentype'); font-weight: 700; font-display: swap; }
@font-face { font-family: 'DIN Next'; src: url('/static/fonts/DINNextCYR-Black.otf') format('opentype'); font-weight: 900; font-display: swap; }

:root {
      /* ── BC Academy brand core ── */
      --brand-yellow: #FCC801;  /* accent only — never body text, never floods */
      --ink:          #1A1A1A;
      --gold-label:   #A8861B;  /* links/ghost text, >=12px bold only */

      /* Legacy aliases — names kept, values remapped to brand roles */
      --navy:   #1A1A1A;
      --blue:   #1A1A1A;
      --accent: #A8861B;
      --light:  #FAF9F5;
      --bg:     #FFFFFF;
      --white:  #ffffff;
      --border: #E6E7E9;
      --text:   #212226;
      --muted:  #6B665A;
      --radius: 14px;
      --primary:       #1A1A1A;
      --primary-light: #FFF7DB;
      --card:          #ffffff;
      --bg-alt:        #FAF9F5;
      --border-subtle: #F2F1EC;
      --border-bottom: #E6E7E9;
      --danger:        #B0164B;
      --success:       #4E7A0E;
      --warning:       #8A6D0B;
      /* ── Identity colour (widget tiles, and anything categorical on white) ──
         READABLE FORMS of the secondary data palette, not new brand colours.
         Same relationship --gold-label #A8861B has to --brand-yellow #FCC801:
         the bright value is the fill, this is the one you can actually see.

         Measured 2026-09-16, which is why these exist at all: of the nine
         --data-N values only --data-9 reaches 4.5:1 on white, and tasks lime
         (1.73) and clubs cyan (1.49) vanish entirely at chip size. That palette
         was built for chart bars sitting against each other, not for marks on
         a white card. Each -ink below clears 4.5:1 on --card and 3:1 on the
         --border bar track; tests/test_widget_identity_colour.py recomputes
         both from these very values, so darkening or brightening one fails the
         build rather than silently shipping an unreadable mark.

         --data-8-ink is terracotta ON PURPOSE. Darkening the coral at full
         saturation gives #EA1900, which is alarm red and would be taken for
         --danger #B0164B on a tile carrying no error.

         -tint is that same colour at 12% over white, precomputed rather than
         color-mix()'d so the chip renders on an older Chromebook too. */
      --data-3-ink:  #697F0A;  --data-3-tint: #EDF0E2;   /* tasks      */
      --data-4-ink:  #03819B;  --data-4-tint: #E1F0F3;   /* clubs      */
      --data-5-ink:  #087CBD;  --data-5-tint: #E1EFF7;   /* attendance */
      --data-6-ink:  #8657F1;  --data-6-tint: #F0EBFD;   /* timetable  */
      --data-7-ink:  #E8006F;  --data-7-tint: #FCE0EE;   /* messages   */
      --data-8-ink:  #C84F41;  --data-8-tint: #F8EAE8;   /* marking    */

      --color-indigo-600: #6B3FD4;
      --color-indigo-50:  #EFE6FE;
      --color-orange-50:  #FFF7DB;

      /* Old navy scale — remapped by role (dark = ink, light = warm) */
      --color-navy-950: #111111;
      --color-navy-900: #1A1A1A;
      --color-navy-800: #212226;
      --color-navy-700: #2A2A2A;
      --color-navy-600: #333333;
      --color-navy-500: #A8861B;
      --color-navy-400: #C0A44D;
      --color-navy-300: #D8C98E;
      --color-navy-200: #E6E7E9;
      --color-navy-100: #F2F1EC;
      --color-navy-50:  #FAF9F5;

      /* Neutral — warm greys */
      --color-gray-900: #212226;
      --color-gray-500: #6B665A;
      --color-gray-400: #9A968C;
      --color-gray-100: #E6E7E9;
      --color-gray-50:  #FAF9F5;
      --color-gray-0:   #ffffff;

      /* Semantic colours — brand chip pairs */
      --color-green-600: #4E7A0E; --color-green-200: #CDE8A8; --color-green-50: #EAF7D9;
      --color-amber-600: #8A6D0B; --color-amber-200: #F0DFA0; --color-amber-50: #FFF3C4;
      --color-red-600:   #B0164B; --color-red-200:   #F6C1D4; --color-red-50:   #FFE1EC;

      /* Surfaces */
      --surface-bg:      #FFFFFF;
      --surface-default: #ffffff;
      --surface-subtle:  #FAF9F5;
      --surface-warm:    #FAF9F5;
      --hero-warm:          #FFFBEF;
      --hero-warm-border:   #F0E9D2;
      --callout-warm:        #FFF7DB;
      --callout-warm-border: #F0DFA0;
      /* The 7-area bar track and the initials disc on the white child card. */
      --card-grad-track: var(--border-subtle);
      /* The calm warm tone for "not observed" on those cards, replacing the
         danger crimson. Brown, not red: it is a prompt, not an error, and it
         clears 7:1 on the white card. */
      --card-status-warm: var(--color-amber-900);

      /* Text */
      --text-primary:   #212226;
      --text-secondary: #6B665A;
      --text-tertiary:  #9A968C;

      /* Interactive */
      --interactive-default: #A8861B;
      --interactive-hover:   #8A6D0B;

      /* Border */
      --border-default: #E6E7E9;
      --divider-warm:   #F2F1EC;
      --border-focus:   #1A1A1A;

      /* Typography */
      --font-sans:    'DIN Next', 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
      --font-display: 'TT Directors', 'DIN Next', sans-serif;

      /* Spacing (4px base) */
      --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px;
      --space-5: 20px; --space-6: 24px;

      /* Radius — brand scale: pill 99 / lg 18 / md 16 / card 14 / control 10 / chip 8 */
      --radius-sm: 8px; --radius-md: 10px; --radius-lg: 14px;
      --radius-xl: 16px; --radius-2xl: 18px; --radius-full: 99px;

      /* Widget tiles only. Deliberately NOT --radius (14px), which is the
         app-wide card radius: an iOS home-screen widget sits near 22-24px on a
         ~170px tile, roughly twice our proportion, and applying that to every
         card in the app is a separate decision nobody has taken. */
      --radius-widget: 22px;

      /* Shadows */
      --shadow-xs:  0 1px 2px rgba(26,26,26,0.04);
      --shadow-sm:  0 4px 14px rgba(26,26,26,0.05);
      --shadow-md:  0 4px 14px rgba(26,26,26,0.05);
      --shadow-lg:  0 18px 46px rgba(26,26,26,0.12);
      --shadow-navy: 0 18px 46px rgba(26,26,26,0.12);

      /* Motion tokens (net-new #15) — CSS transforms/opacity only */
      --motion-fast: 120ms; --motion-base: 180ms; --motion-slow: 260ms;
      --ease-out: cubic-bezier(0.2, 0, 0, 1);
      --transition-fast: all var(--motion-fast) var(--ease-out);
      --transition-base: all var(--motion-base) var(--ease-out);

      /* ── extended token set (names kept) ── */
      --color-gray-950: #111111;
      --color-gray-800: #2A2A2A;
      --color-gray-700: #444444;
      --color-gray-600: #5C5C5C;
      --color-gray-300: #C9C6BE;
      --color-gray-200: #DDDBD4;

      --color-green-900: #33520A; --color-green-700: #4E7A0E;
      --color-green-500: #6FA321; --color-green-100: #EAF7D9;
      --color-amber-900: #5C490A; --color-amber-700: #8A6D0B;
      --color-amber-500: #C6A012; --color-amber-100: #FFF3C4;
      --color-red-900:   #7A0F34; --color-red-700:   #B0164B;
      --color-red-500:   #DB0F59; --color-red-100:   #FFE1EC;
      --color-purple-600: #6B3FD4; --color-purple-100: #EFE6FE; --color-purple-50: #F6F0FF;

      --surface-invert:       #1A1A1A;
      --text-on-invert:       rgba(255,255,255,0.95);
      --text-on-invert-muted: rgba(255,255,255,0.55);
      --interactive-active:   #8A6D0B;
      --interactive-subtle:   #FFF7DB;
      --border-strong:        #DDDBD4;

      /* Status pairs (bg / text / border) — brand chip pairs */
      --status-success-bg:     #EAF7D9;
      --status-success-text:   #4E7A0E;
      --status-success-border: #CDE8A8;
      --status-warning-bg:     #FFF3C4;
      --status-warning-text:   #8A6D0B;
      --status-warning-border: #F0DFA0;
      --status-danger-bg:      #FFE1EC;
      --status-danger-text:    #B0164B;
      --status-danger-border:  #F6C1D4;
      --status-info-bg:        #E3F3FC;
      --status-info-text:      #0A6DA8;
      --status-info-border:    #B5DDF3;

      /* Grade tokens: A=success B=info C=warning D=danger; letters render in TT Directors */
      --grade-a-bg: #EAF7D9; --grade-a-border: #CDE8A8;
      --grade-a-text: #4E7A0E; --grade-a-label: #4E7A0E;
      --grade-b-bg: #E3F3FC; --grade-b-border: #B5DDF3;
      --grade-b-text: #0A6DA8; --grade-b-label: #0A6DA8;
      --grade-c-bg: #FFF3C4; --grade-c-border: #F0DFA0;
      --grade-c-text: #8A6D0B; --grade-c-label: #8A6D0B;
      --grade-d-bg: #FFE1EC; --grade-d-border: #F6C1D4;
      --grade-d-text: #B0164B; --grade-d-label: #B0164B;

      /* Secondary data palette — charts/avatars/subject bars ONLY */
      --data-1: #F9FA54; --data-2: #DFF900; --data-3: #AED311;
      --data-4: #6CE4FC; --data-5: #0A97E5; --data-6: #9065F2;
      --data-7: #FF7DBB; --data-8: #FF7767; --data-9: #DB0F59;

      /* Typography scale */
      --font-mono: 'SF Mono', 'Cascadia Code', 'Fira Code', Consolas, monospace;
      --text-xs: 11px; --text-sm: 12px; --text-base: 13px; --text-md: 14px;
      --text-lg: 16px; --text-xl: 18px; --text-2xl: 23px;  --text-3xl: 27px;
      --weight-normal: 400; --weight-medium: 500; --weight-semibold: 700;
      --weight-bold: 700;   --weight-extrabold: 900;
      --leading-tight: 1.25; --leading-snug: 1.4; --leading-normal: 1.5; --leading-relaxed: 1.65;
      --tracking-wide: 0.04em; --tracking-wider: 0.06em;

      --space-8: 32px; --space-10: 40px; --space-12: 48px;

      --panel-padding-x: 16px; --panel-padding-y: 14px;
      --panel-header-padding: 12px 16px; --sidebar-width: 236px; --sidebar-rail-width: 64px;
      /* The shell's two floating windows sit on this ground with --shell-gap
         between them and the same gap to the viewport edge. Named rather than
         written as a literal because .layout, .sidebar-panel and .main all have
         to agree, and the phone block has to zero it in one place.
         --page-ground is an ALIAS, not a new colour: it points at the existing
         --border-subtle so no hex enters the system for it. */
      --page-ground: var(--border-subtle); --shell-gap: 12px;
      --shell-radius: var(--radius-2xl); --topbar-h: 56px;
      /* Height of the fixed bottom nav below 600px. It was written as the
         literal 60px in three places while the bar MEASURED 64px, so content
         sat 4px under it. One name, so the three cannot drift again. */
      --mobile-nav-h: 64px;

      --shadow-xl:    0 18px 46px rgba(26,26,26,0.12);
      --shadow-2xl:   0 30px 80px rgba(26,26,26,0.25);
      --shadow-focus: 0 0 0 3px rgba(252,200,1,0.35);

      --transition-slow:  all var(--motion-slow) var(--ease-out);
      --transition-color: color var(--motion-fast) var(--ease-out), background-color var(--motion-fast) var(--ease-out), border-color var(--motion-fast) var(--ease-out);

      --z-base: 1; --z-sticky: 10; --z-overlay: 100; --z-modal: 1000; --z-toast: 2000;
    }
