/* ============================================================
   PHONLAB — Design Tokens
   Single source of truth for all theme values.
   Applied via data-theme attribute on <body>.
   Default: dark-glass
   ============================================================ */

/* 2026-09-03 (Joe, repeated feedback across multiple sessions: "the font
   is not legible against the black background... NOT MUTED, so white
   against the black"). --text-secondary/--text-muted/--text-label in
   both dark themes below were sitting at 0.38-0.60 opacity -- legible in
   isolation but not against a genuinely dark UI, and this had already
   been nudged once before (see dashboardLegibility.css's own 2026-07-18
   header comment, itself only reaching 0.55-0.62 and asking for further
   eyeballing that evidently never resolved it). Raised decisively rather
   than nudged again: secondary text is now 0.85 (was 0.60), muted/label
   text 0.68 (was 0.38-0.40). Reserve genuinely low opacity (roughly
   0.30-0.40) for things that SHOULD look inactive -- disabled controls,
   input placeholders -- not for any text a user is meant to read as
   content. Light theme untouched -- Joe's complaint is specifically
   about dark surfaces; dark-text-on-light doesn't have the same
   contrast problem. This fixes everywhere that already pulls from these
   tokens; it does NOT fix the many places across the codebase that
   hardcode their own rgba(255,255,255,0.3x-0.5x) instead of using a
   token -- those need a separate, file-by-file pass (started this same
   session on the micro-lesson files; the rest of mobile.css/viewUnify.css/
   per-feature JS is still open). */

/* ── Shared constants (theme-independent) ────────────────── */
:root {
  /* Layout */
  --header-height:       56px;
  --sidebar-width:       180px;
  --sidebar-right-width: 200px;
  --content-max-width:   960px;

  /* Card */
  --card-width:          220px;
  --card-radius:         14px;
  --card-radius-lg:      18px;

  /* Spacing */
  --gap-xs:  4px;
  --gap-sm:  8px;
  --gap-md:  16px;
  --gap-lg:  24px;
  --gap-xl:  32px;

  /* Typography */
  --font-base: "Inter", "Segoe UI", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", "Fira Code", monospace;
  --text-xs:   10px;
  --text-sm:   12px;
  --text-md:   14px;
  --text-lg:   16px;
  --text-xl:   20px;

  /* Z-index */
  --z-content:  1;
  --z-panel:    900;
  --z-header:   1000;
  --z-im:       1010;
  --z-modal:    1055;
  --z-toast:    1100;

  /* Transitions */
  --t-fast:   0.12s ease;
  --t-base:   0.20s ease;
  --t-slow:   0.35s ease;

  /* CEFR colours (fixed) */
  --cefr-a1-bg:     rgba(56,189,248,0.55);
  --cefr-a1-border: rgba(56,189,248,0.80);
  --cefr-a2-bg:     rgba(14,165,233,0.55);
  --cefr-a2-border: rgba(14,165,233,0.80);
  --cefr-b1-bg:     rgba(16,185,129,0.55);
  --cefr-b1-border: rgba(16,185,129,0.80);
  --cefr-b2-bg:     rgba(5,150,105,0.55);
  --cefr-b2-border: rgba(5,150,105,0.80);
  --cefr-c1-bg:     rgba(168,85,247,0.55);
  --cefr-c1-border: rgba(168,85,247,0.80);

  /* Status colours (fixed) */
  --status-active-bg:     rgba(110,231,183,0.15);
  --status-active-color:  rgba(110,231,183,0.95);
  --status-active-border: rgba(110,231,183,0.35);
  --status-pending-bg:    rgba(251,191,36,0.12);
  --status-pending-color: rgba(251,191,36,0.90);
  --status-pending-border:rgba(251,191,36,0.30);
  --status-danger-bg:     rgba(239,68,68,0.10);
  --status-danger-color:  rgba(252,165,165,0.80);
  --status-danger-border: rgba(239,68,68,0.25);
  --status-draft-bg:      rgba(255,255,255,0.06);
  --status-draft-color:   var(--text-muted);
  --status-draft-border:  rgba(255,255,255,0.12);

  /* Accent (fixed) */
  --accent:         rgba(14,165,233,1);
  --accent-light:   rgba(147,220,255,0.95);
  --accent-subtle:  rgba(14,165,233,0.18);
  --accent-border:  rgba(14,165,233,0.45);
}

/* ── Theme: Dark Glass (default) ─────────────────────────── */
[data-theme="dark-glass"],
:root {
  --body-bg:             linear-gradient(135deg,#080d18 0%,#0f1e35 100%);
  --body-color:          rgba(255,255,255,0.88);

  --header-bg:           rgba(10,20,35,0.97);
  --header-border:       rgba(255,255,255,0.08);

  --sidebar-bg:          rgba(255,255,255,0.03);
  --sidebar-border:      rgba(255,255,255,0.07);
  --sidebar-item-hover:  rgba(255,255,255,0.06);
  --sidebar-item-active-bg:     rgba(14,165,233,0.15);
  --sidebar-item-active-color:  rgba(147,220,255,0.95);
  --sidebar-item-active-border: rgba(14,165,233,0.30);

  /* 2026-09-20 (Joe: the glass frames/cards/inputs are "hard to identify").
     THE FILL WAS WHITE AT 5%, OVER A PHOTOGRAPH. On a flat dark page that
     reads as a panel; over the bookshelf backdrop it is almost nothing, so
     cards, stat tiles and inputs dissolved into the image and their edges had
     to be guessed at. A brighter white made it worse -- it lifts the photo
     through the card instead of covering it.
     So the fill is now DARK and mostly opaque: the photo stays visible around
     and faintly through the panel (still glass, still blurred), but the panel
     itself is a surface you can see the edge of. Borders roughly doubled for
     the same reason. */
  --card-bg:             rgba(12,18,32,0.78);
  --card-border:         rgba(255,255,255,0.22);
  --card-hover-border:   rgba(147,220,255,0.45);
  --card-blur:           blur(14px);
  --card-shadow:         0 8px 32px rgba(0,0,0,0.45);

  --input-bg:            rgba(12,18,32,0.75);
  --input-border:        rgba(255,255,255,0.24);
  --input-focus-border:  rgba(147,220,255,0.55);
  --input-color:         rgba(255,255,255,0.95);
  --input-placeholder:   rgba(255,255,255,0.52);

  --btn-ghost-bg:        rgba(255,255,255,0.06);
  --btn-ghost-border:    rgba(255,255,255,0.14);
  --btn-ghost-color:     var(--text-secondary);
  --btn-ghost-hover-bg:  rgba(255,255,255,0.12);

  --btn-primary-bg:      rgba(14,165,233,0.25);
  --btn-primary-border:  rgba(14,165,233,0.45);
  --btn-primary-color:   rgba(147,220,255,0.95);
  --btn-primary-hover:   rgba(14,165,233,0.38);

  --btn-danger-bg:       rgba(239,68,68,0.15);
  --btn-danger-border:   rgba(239,68,68,0.35);
  --btn-danger-color:    rgba(252,165,165,0.90);
  --btn-danger-hover:    rgba(239,68,68,0.25);

  --btn-success-bg:      rgba(110,231,183,0.15);
  --btn-success-border:  rgba(110,231,183,0.35);
  --btn-success-color:   rgba(110,231,183,0.95);
  --btn-success-hover:   rgba(110,231,183,0.25);

  --nav-btn-bg:          rgba(255,255,255,0.06);
  --nav-btn-border:      rgba(255,255,255,0.14);
  --nav-btn-color:       var(--text-secondary);
  --nav-btn-active-bg:   rgba(255,255,255,0.16);
  --nav-btn-active-color:rgba(255,255,255,0.95);

  --modal-bg:            rgba(10,15,28,0.92);
  --modal-border:        rgba(255,255,255,0.12);
  --modal-blur:          blur(16px);

  /* 2026-09-20 (Joe: "all text needs to be not muted"). Labels and secondary
     copy sat at 0.68 and 0.85 -- fine on a flat panel, grey mush over a
     photograph. Everything moves up; "muted" now means slightly quieter than
     the heading, not hard to read. --text-primary is unchanged at 0.95. */
  --text-primary:        rgba(255,255,255,0.95);
  --text-secondary:      rgba(255,255,255,0.93);
  --text-muted:          rgba(255,255,255,0.86);
  --text-label:          rgba(255,255,255,0.88);

  --divider:             rgba(255,255,255,0.14);

  --scrollbar-thumb:     rgba(255,255,255,0.16);
  --scrollbar-track:     rgba(255,255,255,0.03);

  --select-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='rgba(255,255,255,0.45)'/%3E%3C/svg%3E");
}

/* ── Library SVG icons on dark surfaces ──────────────────────
   Every icon under public/assets/svg/ (the teacher's "Browse library"
   card-image picker, ~250+ single-color line icons across 22 categories)
   is authored with fill="none" stroke="currentColor" specifically so it
   can be recolored via CSS `color` -- see activityBuilderMobile.js's
   inline-SVG picker grid, which already does this correctly. But once a
   teacher picks an icon, its card_image URL gets rendered as a plain
   <img src="...svg"> in every other place that shows it (activity list
   cards, the activity detail hero, the builder's own Card Image preview)
   -- an <img> is opaque to page CSS, so currentColor never resolves and
   the icon falls back to its default black, which is invisible against
   these dark surfaces (Joe: "it renders black against the dark surface
   and is impossible to see with the human eye... It should be set
   globally"). Force these to white wherever they're embedded as <img>,
   site-wide, rather than patching each render site individually. Turned
   off under the light theme, where a white icon would be the one that
   disappears against the page's light background instead. */
img[src*="/assets/svg/"] { filter: brightness(0) invert(1); }
[data-theme="light"] img[src*="/assets/svg/"] { filter: none; }

/* ── Theme: Soft Dark ────────────────────────────────────── */
[data-theme="soft-dark"] {
  --body-bg:             linear-gradient(135deg,#1a1a2e 0%,#16213e 100%);
  --body-color:          rgba(220,220,240,0.90);

  --header-bg:           rgba(22,22,46,0.97);
  --header-border:       rgba(255,255,255,0.10);

  --sidebar-bg:          rgba(255,255,255,0.04);
  --sidebar-border:      rgba(255,255,255,0.08);
  --sidebar-item-hover:  rgba(255,255,255,0.07);
  --sidebar-item-active-bg:     rgba(99,102,241,0.20);
  --sidebar-item-active-color:  rgba(199,210,254,0.95);
  --sidebar-item-active-border: rgba(99,102,241,0.40);

  --card-bg:             rgba(255,255,255,0.06);
  --card-border:         rgba(255,255,255,0.10);
  --card-hover-border:   rgba(199,210,254,0.35);
  --card-blur:           blur(10px);
  --card-shadow:         0 6px 24px rgba(0,0,0,0.25);

  --input-bg:            rgba(255,255,255,0.07);
  --input-border:        rgba(255,255,255,0.14);
  --input-focus-border:  rgba(199,210,254,0.50);
  --input-color:         rgba(220,220,240,0.90);
  --input-placeholder:   rgba(220,220,240,0.30);

  --btn-ghost-bg:        rgba(255,255,255,0.06);
  --btn-ghost-border:    rgba(255,255,255,0.15);
  --btn-ghost-color:     rgba(220,220,240,0.75);
  --btn-ghost-hover-bg:  rgba(255,255,255,0.12);

  --btn-primary-bg:      rgba(99,102,241,0.25);
  --btn-primary-border:  rgba(99,102,241,0.50);
  --btn-primary-color:   rgba(199,210,254,0.95);
  --btn-primary-hover:   rgba(99,102,241,0.38);

  --btn-danger-bg:       rgba(239,68,68,0.15);
  --btn-danger-border:   rgba(239,68,68,0.35);
  --btn-danger-color:    rgba(252,165,165,0.90);
  --btn-danger-hover:    rgba(239,68,68,0.25);

  --btn-success-bg:      rgba(110,231,183,0.15);
  --btn-success-border:  rgba(110,231,183,0.35);
  --btn-success-color:   rgba(110,231,183,0.95);
  --btn-success-hover:   rgba(110,231,183,0.25);

  --nav-btn-bg:          rgba(255,255,255,0.06);
  --nav-btn-border:      rgba(255,255,255,0.14);
  --nav-btn-color:       rgba(220,220,240,0.65);
  --nav-btn-active-bg:   rgba(99,102,241,0.20);
  --nav-btn-active-color:rgba(199,210,254,0.95);

  --modal-bg:            rgba(22,22,46,0.94);
  --modal-border:        rgba(255,255,255,0.12);
  --modal-blur:          blur(14px);

  --text-primary:        rgba(220,220,240,0.95);
  --text-secondary:      rgba(220,220,240,0.85);
  --text-muted:          rgba(220,220,240,0.68);
  --text-label:          rgba(220,220,240,0.68);

  --divider:             rgba(255,255,255,0.08);

  --scrollbar-thumb:     rgba(255,255,255,0.18);
  --scrollbar-track:     rgba(255,255,255,0.04);

  --select-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='rgba(200,200,240,0.50)'/%3E%3C/svg%3E");
}

/* ── Theme: Light ────────────────────────────────────────── */
[data-theme="light"] {
  --body-bg:             linear-gradient(135deg,#f0f4f8 0%,#e8eef5 100%);
  --body-color:          rgba(15,23,42,0.88);

  --header-bg:           rgba(255,255,255,0.95);
  --header-border:       rgba(0,0,0,0.08);

  --sidebar-bg:          rgba(255,255,255,0.70);
  --sidebar-border:      rgba(0,0,0,0.07);
  --sidebar-item-hover:  rgba(0,0,0,0.05);
  --sidebar-item-active-bg:     rgba(14,165,233,0.12);
  --sidebar-item-active-color:  rgba(2,100,180,0.95);
  --sidebar-item-active-border: rgba(14,165,233,0.35);

  --card-bg:             rgba(255,255,255,0.85);
  --card-border:         rgba(0,0,0,0.08);
  --card-hover-border:   rgba(14,165,233,0.45);
  --card-blur:           blur(8px);
  --card-shadow:         0 4px 16px rgba(0,0,0,0.08);

  --input-bg:            rgba(255,255,255,0.90);
  --input-border:        rgba(0,0,0,0.14);
  --input-focus-border:  rgba(14,165,233,0.60);
  --input-color:         rgba(15,23,42,0.88);
  --input-placeholder:   rgba(15,23,42,0.35);

  --btn-ghost-bg:        rgba(0,0,0,0.04);
  --btn-ghost-border:    rgba(0,0,0,0.12);
  --btn-ghost-color:     rgba(15,23,42,0.70);
  --btn-ghost-hover-bg:  rgba(0,0,0,0.08);

  --btn-primary-bg:      rgba(14,165,233,0.15);
  --btn-primary-border:  rgba(14,165,233,0.50);
  --btn-primary-color:   rgba(2,100,180,0.95);
  --btn-primary-hover:   rgba(14,165,233,0.25);

  --btn-danger-bg:       rgba(239,68,68,0.10);
  --btn-danger-border:   rgba(239,68,68,0.30);
  --btn-danger-color:    rgba(180,30,30,0.90);
  --btn-danger-hover:    rgba(239,68,68,0.18);

  --btn-success-bg:      rgba(16,185,129,0.12);
  --btn-success-border:  rgba(16,185,129,0.35);
  --btn-success-color:   rgba(5,120,80,0.95);
  --btn-success-hover:   rgba(16,185,129,0.22);

  --nav-btn-bg:          rgba(0,0,0,0.04);
  --nav-btn-border:      rgba(0,0,0,0.12);
  --nav-btn-color:       rgba(15,23,42,0.60);
  --nav-btn-active-bg:   rgba(14,165,233,0.15);
  --nav-btn-active-color:rgba(2,100,180,0.95);

  --modal-bg:            rgba(255,255,255,0.97);
  --modal-border:        rgba(0,0,0,0.10);
  --modal-blur:          blur(8px);

  --text-primary:        rgba(15,23,42,0.92);
  --text-secondary:      rgba(15,23,42,0.60);
  --text-muted:          rgba(15,23,42,0.40);
  --text-label:          rgba(15,23,42,0.45);

  --divider:             rgba(0,0,0,0.07);

  --scrollbar-thumb:     rgba(0,0,0,0.18);
  --scrollbar-track:     rgba(0,0,0,0.04);

  --select-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='rgba(15,23,42,0.45)'/%3E%3C/svg%3E");
}

/* ── Text utility classes (2026-09-03) ───────────────────────
   Joe: "is it possible to refactor the files and create the shared
   source for all the files" -- Stage 2 of the legibility fix. Most
   per-feature JS files (dashboard.js, presenterRemote.js, the act_*.js
   runners, etc.) don't read these CSS variables at all -- they hardcode
   their own rgba(255,255,255,0.3x-0.5x) directly into inline style=""
   strings inside template literals, which is why the same legibility
   complaint keeps resurfacing in a different file each time (see this
   file's own 2026-09-03 comment above, and dashboardLegibility.css's
   2026-07-18 one, for two earlier instances of exactly this). These
   classes give any file a real alternative to hardcoding a colour: write
   class="text-secondary" instead of style="color:var(--text-muted)"
   and it inherits whatever the active theme's --text-secondary resolves
   to, everywhere, automatically. Not yet adopted anywhere -- migrating
   individual files to use these instead of their own hardcoded colours
   is Stage 3, done opportunistically as those files are touched for
   other reasons, not a single sweep of the whole codebase at once. */
.text-primary   { color: var(--text-primary); }
.text-secondary { color: var(--text-secondary); }
.text-muted     { color: var(--text-muted); }
.text-label     { color: var(--text-label); }
