/*
 * Yoshuko Design Tokens — CSS Custom Properties
 * Palette: Muted Brown + Warm Neutrals (the logo, wearing the whole product)
 * See: int_lms/app_root/UI.md for full design rationale and contrast verification.
 *
 * The brand colour is not a colour someone picked — it is #7B5F5F, sampled from the
 * "Yoshuko" wordmark in logo_dark.svg. `test_home_hero_and_palette.py` asserts that
 * --color-primary is a fill that appears in that file, so the palette cannot drift
 * away from the mark it is supposed to be derived from.
 *
 * This replaced a deep-forest-green palette. The greys went with it: #0D1D14 and
 * #5C6B61 were green-tinted, and grey that is secretly green reads as a second brand
 * colour sitting next to the brown. They are now warm neutrals.
 */

:root {
  /* ── Color: Background & Surface ───────────────────────────────────────── */
  --color-bg:             #FBFAF9;  /* warm off-white page background */
  --color-surface:        #FFFFFF;  /* card / panel surface */
  --color-surface-raised: #F5F2F0;  /* raised surface — rows, sidebar bg */
  --color-surface-sunken: #EDE7E4;  /* sunken / input background */

  /* ── Color: Text ────────────────────────────────────────────────────────── */
  --color-fg:             #17130F;  /* primary text — near-black, warm neutral */
  --color-muted-fg:       #6B625C;  /* secondary text — labels, metadata */
  --color-inverse-fg:     #FFFFFF;  /* text on dark surfaces */

  /* ── Color: Border ──────────────────────────────────────────────────────── */
  --color-border:         #E3DCD7;  /* standard border — warm neutral */
  --color-border-strong:  #C8BDB6;  /* stronger separation */

  /* ── Color: Brand ───────────────────────────────────────────────────────── */
  --color-primary:        #7B5F5F;  /* the "Yoshuko" wordmark in logo_dark.svg */
  --color-primary-hover:  #5F4848;  /* hover / active tint */
  --color-accent:         #D97706;  /* warm amber — decorative, non-text (≥24px) */
  --color-accent-fg:      #92400E;  /* dark amber — accessible text / interactive */
  --focus-ring:           #7B5F5F;  /* on-brand focus ring (matches primary) */
  --color-brand-brown:    #7B5F5F;  /* kept as an alias — the two are now the same */

  /* ── Color: Navigation surfaces ─────────────────────────────────────────────
     Both are the brand brown's hue, desaturated and lightened — the chrome
     carries the brand without competing with the content it frames. The course
     menu is the lighter of the two so a course screen reads as nested inside the
     app rather than sitting beside it.
     A creator can override either on /creator/appearance/; the override is written
     onto <html> as these same custom properties, so nothing else has to know. */
  --color-nav-surface:         #E9E3E3;  /* main navigation — muted brown */
  --color-course-menu-surface: #F2EFEF;  /* course workspace menu — lighter still */

  /* ── Color: Navigation ink ──────────────────────────────────────────────────
     A three-tier ramp per menu, because the creator sets the surface and the text
     has to stay readable on whatever they choose.

       ink         section labels — Learn / Create / Brand, and the course sections
       ink-muted   the links under them
       ink-subtle  third level: recent-course names, icons, the menu's back/close

     Emphasis runs darkest-first here; the whole ramp inverts under the [data-*-tone
     ="dark"] blocks below, where it runs lightest-first instead. Weights are NOT
     part of the ramp — the label stays semibold and the link medium regardless.

     Declared per menu rather than once: one surface can be light while the other is
     dark, so a single shared ramp would be wrong for one of them by construction.
     Every tier clears 4.5:1 against its own default surface (asserted in
     test_appearance_and_nav_chrome.py, which is also what stops a future palette
     tweak from quietly dropping the subtle tier below AA). */
  --color-nav-ink:                 #000000;
  --color-nav-ink-muted:           #3F3A36;
  --color-nav-ink-subtle:          #5E554F;
  --color-course-menu-ink:         #000000;
  --color-course-menu-ink-muted:   #3F3A36;
  --color-course-menu-ink-subtle:  #5E554F;

  /* The hover / active wash. A translucent ink rather than a fixed grey, so it
     darkens any surface by the same amount instead of being legible on the default
     tint and invisible on half of what the picker can produce. Flips to a light
     wash with the tone — a dark wash on a dark surface is no hover state at all,
     which reads as an unresponsive control rather than a subtle one. */
  --color-nav-overlay:         rgba(0, 0, 0, 0.07);
  --color-course-menu-overlay: rgba(0, 0, 0, 0.07);
}

/* ── Dark navigation surfaces ────────────────────────────────────────────────
   Set by the shell's <head> script when white ink contrasts better than black on
   the creator's chosen surface. That is decided by comparing the two WCAG contrast
   ratios directly, NOT by a lightness cut: is_light_color's luminance > 0.5 answers
   "is this light", but white text only clears the 4.5:1 AA floor once luminance
   drops to ~0.183, so every mid-tone between would be handed the less readable ink.

   The two menus switch independently: [data-nav-tone] governs #appSidebar,
   [data-course-menu-tone] governs #courseMenu. */
:root[data-nav-tone="dark"] {
  --color-nav-ink:        #FFFFFF;
  --color-nav-ink-muted:  #E7E1DD;
  --color-nav-ink-subtle: #C9C0BA;
  --color-nav-overlay:    rgba(255, 255, 255, 0.14);
}

:root[data-course-menu-tone="dark"] {
  --color-course-menu-ink:        #FFFFFF;
  --color-course-menu-ink-muted:  #E7E1DD;
  --color-course-menu-ink-subtle: #C9C0BA;
  --color-course-menu-overlay:    rgba(255, 255, 255, 0.14);
}

:root {

  /* ── Color: Dark section surface ────────────────────────────────────────────
     Named "hero" for historical reasons — the home page hero is white now. This is
     the dark band used by the closing CTA, the pricing/comparison page headers, the
     onboarding shell and the cookie banner. It is the brand brown taken almost to
     black so the white text on it clears AA by a wide margin. */
  --color-bg-hero:        #2C2321;  /* deep warm brown-black — dark bands */

  /* ── Color: Semantic ────────────────────────────────────────────────────── */
  --color-success:         #15803D;
  --color-success-surface: #F0FDF4;
  --color-warning:         #D97706;
  --color-warning-surface: #FFFBEB;
  --color-error:           #DC2626;
  --color-error-surface:   #FEF2F2;
  --color-info:            #2563EB;
  --color-info-surface:    #EFF6FF;

  /* ── Color: Help popup ──────────────────────────────────────────────────────
     Help is the one surface in the app that is deliberately NOT brand brown. It
     is an aside — the creator has stopped to ask a question — and painting it in
     the brand makes it compete with the section it is explaining. A muted green
     reads as guidance rather than as chrome, and nothing else in the palette is
     green, so a help popup can never be mistaken for anything else on the page.

     The header and the border are ONE token on purpose: the popup is framed by
     the colour of its own header bar, so the two cannot drift apart.
     White on #3F6B52 is ~6:1 and --color-fg on #F1F0EE is ~15:1 (both AA).
     Asserted in test_help_tip.py. */
  --color-help-header:     #3F6B52;  /* muted green — header bar AND border */
  --color-help-header-fg:  #FFFFFF;
  --color-help-surface:    #F1F0EE;  /* light grey content well */
  --color-help-fg:         var(--color-fg);

  /* ── Typography: Font Family ──────────────────────────────────────────────
     One family, not two. Headlines used to be Syne — a geometric display face whose
     wide, low-contrast letterforms are the least readable thing on a marketing page
     at the exact moment a visitor is deciding whether to keep reading. Display and
     body are now both Inter, separated by weight (800 vs 400/500) and by tracking
     (--tracking-tight), which is a stronger hierarchy signal than a second typeface
     and costs one font request instead of two.

     --font-family-display is kept as a distinct token rather than deleted: it is
     referenced from a dozen rules across the app, and it is where a display face
     would go back if one is ever chosen again. */
  --font-family-display: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-family-base:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-family-mono:    "JetBrains Mono", "Fira Code", "Cascadia Code", monospace;

  /* ── Typography: Tracking ───────────────────────────────────────────────────
     Inter needs negative tracking to hold together at display sizes; the larger the
     type, the tighter it wants to be. */
  --tracking-tight:   -0.02em;  /* headings */
  --tracking-tighter: -0.035em; /* hero headline only */
  --tracking-wide:     0.08em;  /* small-caps eyebrows and labels */

  /* ── Typography: Font Size ──────────────────────────────────────────────── */
  --font-size-xs:   0.75rem;
  --font-size-sm:   0.875rem;
  --font-size-base: 1rem;
  --font-size-lg:   1.125rem;
  --font-size-xl:   1.25rem;
  --font-size-2xl:  1.5rem;
  --font-size-3xl:  1.875rem;
  --font-size-4xl:  2.25rem;
  --font-size-5xl:  3rem;
  --font-size-6xl:  3.75rem;

  /* ── Typography: Font Weight ────────────────────────────────────────────── */
  --font-weight-normal:    400;
  --font-weight-medium:    500;
  --font-weight-semibold:  600;
  --font-weight-bold:      700;
  --font-weight-extrabold: 800;  /* hero headline — must stay in the @font request */

  /* ── Typography: Line Height ────────────────────────────────────────────── */
  --line-height-tight:   1.25;
  --line-height-normal:  1.5;
  --line-height-relaxed: 1.75;

  /* ── Spacing (4px scale) ────────────────────────────────────────────────── */
  --space-1:  0.25rem;
  --space-2:  0.5rem;
  --space-3:  0.75rem;
  --space-4:  1rem;
  --space-5:  1.25rem;
  --space-6:  1.5rem;
  --space-8:  2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;
  --space-20: 5rem;
  --space-24: 6rem;

  /* ── Border Radius ──────────────────────────────────────────────────────── */
  --radius-none: 0;
  --radius-sm:   0.25rem;
  --radius-md:   0.375rem;
  --radius-lg:   0.5rem;
  --radius-xl:   0.75rem;
  --radius-2xl:  1rem;
  --radius-full: 9999px;

  /* ── Elevation (box-shadow) ──────────────────────────────────────────────── */
  --elevation-0: none;
  --elevation-1: 0 1px 2px 0 rgba(44,35,33,0.06);
  --elevation-2: 0 1px 3px 0 rgba(44,35,33,0.10), 0 1px 2px -1px rgba(44,35,33,0.08);
  --elevation-3: 0 4px 6px -1px rgba(44,35,33,0.10), 0 2px 4px -2px rgba(44,35,33,0.08);
  --elevation-4: 0 10px 15px -3px rgba(44,35,33,0.10), 0 4px 6px -4px rgba(44,35,33,0.06);

  /* ── Motion ─────────────────────────────────────────────────────────────── */
  --duration-fast:   100ms;
  --duration-normal: 200ms;
  --duration-slow:   300ms;
  --easing-standard: cubic-bezier(0.4, 0, 0.2, 1);
  --easing-enter:    cubic-bezier(0, 0, 0.2, 1);
  --easing-exit:     cubic-bezier(0.4, 0, 1, 1);
}

/* ── Tenant theme overrides (injected via template context) ─────────────────
   Override brand tokens only; everything else stays global for
   consistency and accessibility compliance (WCAG 2.2 AA).
   Usage: set CSS vars on <body data-tenant> via inline <style> tag
   when request.tenant is set and org.theme.brand_primary exists. */
body[data-tenant] {
  /* overridden per-tenant in base.html when org.theme values present */
}

/* ── Bootstrap 5 integration ────────────────────────────────────────────────
   Map Yoshuko tokens onto Bootstrap CSS variables.
   Bootstrap uses --bs-* custom properties so we bridge them here.
   Keep --bs-primary-rgb in sync whenever --color-primary changes (123, 95, 95);
   test_the_bootstrap_bridge_rgb_matches_the_primary_hex asserts the two agree. */
:root {
  --bs-primary:          var(--color-primary);
  --bs-primary-rgb:      123, 95, 95;
  --bs-link-color:       var(--color-primary);
  --bs-link-hover-color: var(--color-primary-hover);
  --bs-body-color:       var(--color-fg);
  --bs-body-bg:          var(--color-bg);
  --bs-body-font-family: var(--font-family-base);
  --bs-border-color:     var(--color-border);
  --bs-border-radius:    var(--radius-lg);
  --bs-border-radius-sm: var(--radius-md);
  --bs-border-radius-lg: var(--radius-xl);
  --bs-secondary-color:  var(--color-muted-fg);
  --bs-success:          var(--color-success);   /* #15803D */
  --bs-success-rgb:      21, 128, 61;
  --bs-warning:          var(--color-warning);   /* #D97706 */
  --bs-warning-rgb:      217, 119, 6;
  --bs-danger:           var(--color-error);     /* #DC2626 */
  --bs-danger-rgb:       220, 38, 38;
  --bs-info:             var(--color-info);      /* #2563EB */
  --bs-info-rgb:         37, 99, 235;
}
