/* ─────────────────────────────────────────────────────────────────────────
 * Muzoon design tokens — WEB COPY of the canonical mobile artifact.
 *
 * Source path: Muzoon/specs/008-design-system-infrastructure/muzoon-tokens.css
 * Source git SHA: ed8635899772f1ff784e00e7d4f04c3d65853e50
 * Source content SHA-256: 5db1599f71ab69c88a0d9eeaf9a93aff21f1edb4c9d5d72e27e83ec2f6598664
 * Synced: 2026-05-21 (Phase 2 / T009, feature 004-design-system-web-port)
 *
 * DO NOT EDIT this file by hand. It is a byte-for-byte mirror of the mobile
 * canonical CSS and is enforced by the token parity gate
 * (`src/design-system/__tests__/tokens.parity.test.ts`, contract:
 * `specs/004-design-system-web-port/contracts/token-parity-gate.contract.md`).
 *
 * To resync: copy the canonical file again, refresh the SHAs above. Web-only
 * additions (breakpoints, z-index, focus-ring) live in `./theme.css`, NOT
 * here — they are listed in `./web-only.allowlist.json`.
 * ───────────────────────────────────────────────────────────────────────── */

/* KMP / Compose theme reference ─────────────────────────────────────────────
   This CSS file is the source of truth for the React mock-up. The Kotlin
   Multiplatform / Compose Multiplatform port mirrors it as a `MuzoonTheme`
   object exposed through a CompositionLocal. The skeleton below is the
   contract that downstream KMP comments (in components, screens, fixtures)
   resolve their `MuzoonTheme.*` references against.

   ── Kotlin object skeleton ────────────────────────────────────────────────
   // Top-level entry point — accessed as `MuzoonTheme.color`, `.shape`, etc.
   object MuzoonTheme {
     val color:      Colors      @Composable get() = LocalMuzoonColors.current
     val shape:      Shapes      @Composable get() = LocalMuzoonShapes.current
     val spacing:    Spacing     @Composable get() = LocalMuzoonSpacing.current
     val elevation:  Elevation   @Composable get() = LocalMuzoonElevation.current
     val typography: Typography  @Composable get() = LocalMuzoonTypography.current
   }

   // Colors — one Colors instance per theme block in this CSS file.
   data class Colors(
     val primary: Color,             val onPrimary: Color,
     val primaryContainer: Color,    val onPrimaryContainer: Color,
     val secondary: Color,           val onSecondary: Color,
     val secondaryContainer: Color,  val onSecondaryContainer: Color,
     val background: Color,          val onBackground: Color,
     val surface: Color,             val onSurface: Color,
     val surfaceVariant: Color,      val onSurfaceVariant: Color,
     val outline: Color,
     val error: Color,               val onError: Color,
     val success: Color,
     val mute: Color,
     val thumbOnControl: Color,      // pure white in BOTH themes (filled controls)
     val heroGradFrom: Color,        // mode-agnostic — navy in both themes
     val heroGradTo: Color,
     val heroOnGrad: Color,          // pure white in BOTH themes
     val heroInk: Color,
   )

   // Shape — Material 3 shape scale plus a `pill` for chips/Switch tracks.
   object Shapes {
     val small      = RoundedCornerShape(8.dp)    // --r-sm
     val medium     = RoundedCornerShape(12.dp)   // --r-md
     val large      = RoundedCornerShape(16.dp)   // --r-lg
     val extraLarge = RoundedCornerShape(20.dp)   // --r-xl
     val pill       = CircleShape                 // --r-pill (999px)
   }

   // Spacing — 4/8 grid. Names mirror CSS `--space-*` keys.
   object Spacing {
     val xs    = 4.dp     // --space-xs
     val sm    = 8.dp     // --space-sm
     val md    = 12.dp    // --space-md
     val base  = 16.dp    // --space-base
     val lg    = 20.dp    // --space-lg
     val xl    = 24.dp    // --space-xl
     val xxl   = 32.dp    // --space-2xl
     val xxxl  = 48.dp    // --space-3xl
     val xxxxl = 64.dp    // --space-4xl
   }

   // Elevation — Compose tonalElevation/shadowElevation dp values.
   // Map to the multi-layer CSS box-shadows by approximate optical weight;
   // exact translation lives in `MuzoonShadow` modifier on Android.
   object Elevation {
     val level1 = 1.dp    // --shadow-1   (cards, inline rows)
     val level2 = 4.dp    // --shadow-2   (sheets, popovers, sticky bars)
     val lift   = 10.dp   // --shadow-lift (hero card, dialog scrim peer)
   }

   // Typography — derived from observed font-size literals across src/.
   // Sizes are .sp (Compose scales them with user font-size preference);
   // the React mock-up uses raw px which the KMP port must translate.
   //
   //   serifTitle    26.sp / serif / 700  → TopBar h1, big screen titles
   //   titleMedium   18.sp / serif / 700  → MiniPlayerBar artwork title, hero
   //   titleSmall    15.sp / sans  / 600  → LessonRow title, CategoryChipCard
   //   bodyLarge     14.sp / sans  / 500  → MoreActionsSheet rows, sheet items
   //   bodyMedium    13.sp / sans  / 500  → Chip, ConfirmationDialog body
   //   bodySmall     12.sp / sans  / 500  → meta lines, lesson count
   //   labelMedium   11.sp / sans  / 500  → PrimaryNav labels, captions
   //   labelSmall     9.sp / sans  / 700  → TransportControls skip glyph
   //   numeric       --font-mono  / 500   → timestamps, counts, durations
   //                                        (size pinned at use-site, 10–11sp typical)
   //
   // FontFamily mapping (load via androidx.compose.ui.text.font.FontFamily):
   //   sans  = "Noto Naskh Arabic" + system Arabic stack (--font-sans)
   //   serif = "Noto Naskh Arabic"    (--font-serif) — h1/h2/h3 + scholar names
   //   mono  = "JetBrains Mono"       (--font-mono)  — Latin numerics in RTL ctx

   ── Token-mapping table ───────────────────────────────────────────────────
   CSS variable                      → Compose property
   --role-primary                    → MuzoonTheme.color.primary
   --role-on-primary                 → MuzoonTheme.color.onPrimary
   --role-primary-container          → MuzoonTheme.color.primaryContainer
   --role-secondary                  → MuzoonTheme.color.secondary
   --role-background                 → MuzoonTheme.color.background
   --role-surface                    → MuzoonTheme.color.surface
   --role-surface-variant            → MuzoonTheme.color.surfaceVariant
   --role-on-surface-variant         → MuzoonTheme.color.onSurfaceVariant
   --role-outline                    → MuzoonTheme.color.outline
   --role-error                      → MuzoonTheme.color.error
   --role-success                    → MuzoonTheme.color.success
   --role-mute                       → MuzoonTheme.color.mute
   --role-thumb-on-control           → MuzoonTheme.color.thumbOnControl
   --hero-grad-from / --hero-grad-to → MuzoonTheme.color.heroGradFrom/To
   --hero-on-grad                    → MuzoonTheme.color.heroOnGrad
   --hero-ink                        → MuzoonTheme.color.heroInk
   --r-sm  / --r-md / --r-lg / --r-xl→ MuzoonTheme.shape.small/medium/large/extraLarge
   --r-pill                          → MuzoonTheme.shape.pill (CircleShape)
   --space-xs … --space-4xl          → MuzoonTheme.spacing.xs … xxxxl
   --space-base                      → MuzoonTheme.spacing.base
   --shadow-1 / --shadow-2           → MuzoonTheme.elevation.level1/level2
   --shadow-lift                     → MuzoonTheme.elevation.lift
   --font-serif (26)                 → MuzoonTheme.typography.serifTitle
   --font-sans  (14/13)              → MuzoonTheme.typography.bodyLarge/bodyMedium
   --font-mono                       → MuzoonTheme.typography.numeric

   ── Light / dark mode ─────────────────────────────────────────────────────
   The `:root, [data-theme="light"]` and `[data-theme="dark"]` blocks below
   become two `Colors` instances on the KMP side: `lightColors()` and
   `darkColors()`. The root composable picks one based on the platform
   preference and provides it through CompositionLocal:

     @Composable fun MuzoonTheme(
       useDarkTheme: Boolean = isSystemInDarkTheme(),
       content: @Composable () -> Unit,
     ) {
       val colors = if (useDarkTheme) darkColors() else lightColors()
       CompositionLocalProvider(LocalMuzoonColors provides colors) { … }
     }

   Shape / spacing / typography are theme-invariant; only Colors and
   Elevation (the dark theme uses softer ambient shadows) flip.

   ── RTL ───────────────────────────────────────────────────────────────────
   The whole UI is Arabic. Wrap the root in:

     CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
       MuzoonTheme { App() }
     }

   Latin numerics (timestamps, durations) keep LTR by wrapping the leaf
   Text in `CompositionLocalProvider(LocalLayoutDirection provides Ltr)` —
   mirrors the `dir="ltr"` spans on numeric elements in the React source.
   ────────────────────────────────────────────────────────────────────── */

/* Muzoon design tokens — generated from handoff/tokens.json
   Theme switches via [data-theme="light"] / [data-theme="dark"] on <html>.
   Defaults to light when no attribute is set. */

:root,
[data-theme="light"] {
  /* ── Brand ─────────────────────────────── */
  --brand-deep:    #0F2A67;
  --brand-primary: #1B3F8E;
  --brand-bright:  #4068E1;
  --brand-tint:    #E9EEF8;

  /* ── Amber / Bookmark ──────────────────── */
  --amber-deep:     #A67A1E;
  --amber-bookmark: #C8942F;
  --amber-soft:     #F5DEA1;

  /* ── Semantic ──────────────────────────── */
  --danger:  #C62828;
  --success: #2E7D32;

  /* ── Hero gradient (mode-agnostic — brand navy in both themes) ── */
  --hero-grad-from: #1B3F8E;
  --hero-grad-to:   #0F2A67;
  --hero-ink:       #FFFFFF;

  /* ── Role tokens (theme-aware; prefer these in new code) ── */
  --role-background:           #FAFAFC;
  --role-surface:              #FFFFFF;
  --role-surface-variant:      #F1F3F5;
  --role-on-background:        #1A1D21;
  --role-on-surface:           #1A1D21;
  --role-on-surface-variant:   #5B6171;
  --role-outline:              #D1D5DC;
  --role-primary:              #1B3F8E;
  --role-on-primary:           #FFFFFF;
  --role-primary-container:    #E9EEF8;
  --role-on-primary-container: #1B3F8E;
  --role-secondary:            #C8942F;
  --role-on-secondary:         #FFFFFF;
  --role-secondary-container:  #F5DEA1;
  --role-on-secondary-container:#A67A1E;
  --role-error:                #C62828;
  --role-on-error:             #FFFFFF;
  --role-success:              #2E7D32;
  --role-mute:                 #8A8F9A;
  /* Thumb / label color that sits on filled controls (Switch thumb, primary
     PlayButton glyph, recording-overlay confirm). Pure white in both modes —
     these surfaces are tonal/branded controls, not theme-aware backgrounds. */
  --role-thumb-on-control:     #FFFFFF;
  /* Foreground on the navy hero gradient. Mode-agnostic (the gradient is
     navy in both themes), so this token reads pure white in both blocks. */
  --hero-on-grad:              #FFFFFF;

  /* iOS device backdrop (was hardcoded #EFEEEC) */
  --device-backdrop: #EFEEEC;

  /* ── Radius ─────────────────────────────── */
  --r-sm:   8px;
  --r-md:  12px;
  --r-lg:  16px;
  --r-xl:  20px;
  --r-pill: 999px;

  /* ── Spacing (4/8 grid) ─────────────────── */
  --space-xs:  4px;
  --space-sm:  8px;
  --space-md:  12px;
  --space-base:16px;
  --space-lg:  20px;
  --space-xl:  24px;
  --space-2xl: 32px;
  --space-3xl: 48px;
  --space-4xl: 64px;

  /* ── Elevation ──────────────────────────── */
  --shadow-1:    0 1px 2px rgba(16,24,40,.04), 0 1px 3px rgba(16,24,40,.04);
  --shadow-2:    0 4px 14px rgba(16,24,40,.06), 0 2px 6px rgba(16,24,40,.04);
  --shadow-lift: 0 10px 30px rgba(15,42,103,.08), 0 2px 6px rgba(15,42,103,.05);

  /* ── Motion ─────────────────────────────── */
  --dur-fast:  120ms;
  --dur-base:  180ms;
  --dur-slow:  240ms;
  --ease-standard:   cubic-bezier(0.2,0,0,1);
  --ease-emphasized: cubic-bezier(0.2,0,0,1);

  /* ── Type families ──────────────────────── */
  /* Brand body face is Noto Naskh Arabic (Muzoon brand-font rule —
     IBM Plex Sans Arabic is forbidden anywhere in the bundle). The
     fallback stack leans on the platform's native Arabic faces (SF Arabic
     on Apple, Segoe UI on Windows) so text paints with a brand-adjacent
     Arabic glyph before the woff2 swaps in. */
  --font-sans:  "Noto Naskh Arabic", system-ui, -apple-system, "SF Arabic", "Segoe UI", Arial, sans-serif;
  --font-serif: "Noto Naskh Arabic", serif;
  --font-mono:  "JetBrains Mono", ui-monospace, Menlo, monospace;
}

/* ── Dark — Warm Scholarly palette ──────────────────────────────
   Low-chroma warm neutral surfaces. Background is near-black (not pure
   black) so scroll content stays above the OLED transition floor.
   Brand navy lifts to a brighter cool-blue accent that pops against the
   warm neutral. Off-white text reduces mini-LED bloom and reading
   fatigue. Hero gradient stays brand-navy (mode-agnostic, declared in
   :root above). The dark theme deliberately sheds the legacy aliases —
   consumers should reference role tokens only. */
[data-theme="dark"] {
  --role-background:           #0B0B0E;
  --role-surface:              #16161B;
  --role-surface-variant:      #1F1F26;
  --role-on-background:        #ECEAE3;
  --role-on-surface:           #ECEAE3;
  --role-on-surface-variant:   #B5B0A5;
  --role-outline:              #2C2C36;
  --role-primary:              #8FA9FF;
  --role-on-primary:           #06112E;
  --role-primary-container:    rgba(143,169,255,0.14);
  --role-on-primary-container: #C4D0FF;
  --role-secondary:            #D6A55A;
  --role-on-secondary:         #160F00;
  --role-secondary-container:  rgba(214,165,90,0.16);
  --role-on-secondary-container:#E5BC79;
  --role-error:                #E66B6B;
  --role-on-error:             #160808;
  --role-success:              #7AC98E;
  --role-mute:                 #8A8578;
  --role-thumb-on-control:     #FFFFFF;
  --hero-on-grad:              #FFFFFF;

  --device-backdrop: #0B0B0E;

  /* ── Elevation (dark — softer ambient) ── */
  --shadow-1:    0 1px 2px rgba(0,0,0,.30), 0 1px 3px rgba(0,0,0,.20);
  --shadow-2:    0 4px 14px rgba(0,0,0,.40), 0 2px 6px rgba(0,0,0,.30);
  --shadow-lift: 0 10px 30px rgba(0,0,0,.45), 0 2px 6px rgba(0,0,0,.30);
}

/* Page background follows the theme so iframes and the index canvas swap together */
html,
body {
  background: var(--role-background);
  color: var(--role-on-background);
}


@font-face {
  font-family: "Noto Naskh Arabic";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/noto-naskh-arabic-700.woff2") format("woff2");
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF,
    U+FE70-FEFF, U+0660-0669, U+0030-0039, U+0020;
}


html { direction: rtl; }
body {
  margin: 0;
  font-family: var(--font-sans, "Noto Naskh Arabic"), system-ui, sans-serif;
  line-height: 1.75;
}
.cp-header, .cp-footer {
  display: flex; gap: 1rem; align-items: center;
  padding: 1rem 1.25rem;
}
.cp-main { max-width: 48rem; margin: 0 auto; padding: 1.25rem; }
.cp-main h1 { font-size: 1.75rem; margin: 0 0 .75rem; }
.cp-main h2 { font-size: 1.25rem; margin: 1.5rem 0 .5rem; }
.cp-count { font-variant-numeric: tabular-nums; }
.cp-list { list-style: none; padding: 0; margin: 0; }
.cp-list li {
  display: flex; justify-content: space-between; gap: 1rem;
  padding: .5rem 0; border-bottom: 1px solid var(--role-outline);
}
.cp-pagination { display: flex; gap: 1rem; margin-top: 1.5rem; }
.cp-source, .cp-empty { opacity: .75; font-size: .9rem; }
img { max-width: 100%; }
