/* ============================================================================
   theme.css — Obeikan AI design tokens (single source of truth)
   ----------------------------------------------------------------------------
   All themeable colors/fonts live here, not hardcoded in templates. Templates
   reference these CSS variables (var(--token)). The active theme is chosen by
   the data-theme attribute on <html> ("light" | "dark"), set by the theme
   bootstrap in base.html from the user's saved appearance preference.

   To add a new theme: copy a block below and change the values under a new
   [data-theme="<name>"] selector, then expose it in the Settings → Appearance
   picker (templates/settings.html).
   ============================================================================ */

/* ── Light (default) ─────────────────────────────────────────────────────── */
:root {
    --bg:             #FAF9F5;   /* warm paper canvas (one step lighter — Claude-exact) */
    --bg-raised:      #FFFFFF;   /* raised panels */
    --bg-secondary:   #F0EEE6;   /* list rows / secondary wells (KB doc lists) */
    --surface:        #FFFFFF;   /* cards / bubbles / composer */

    --sidebar-bg:     #F5F4EE;   /* light warm rail (theme-aware) */
    --sidebar-text:   #44413B;   /* re-derived against the lighter rail */
    --sidebar-strong: #1F1E1D;   /* logo / active item / titles */
    --sidebar-dim:    #6b6862;
    --sidebar-faint:  #9a968d;   /* section labels, meta */
    --sidebar-line:   rgba(31, 30, 29, 0.10);
    --sidebar-hover:  rgba(31, 30, 29, 0.05);
    --sidebar-active: rgba(31, 30, 29, 0.07);   /* neutral fill — terracotta-tinted active retired */
    --sidebar-well:   rgba(31, 30, 28, 0.04);
    --sidebar-chip:   #fbfaf7;
    --sidebar-accent: #c96442;

    --card:           #ffffff;
    --card-border:    rgba(31, 30, 28, 0.10);
    --border:         rgba(31, 30, 28, 0.10);
    --input-border:   rgba(31, 30, 28, 0.18);
    --input-focus:    #c96442;

    --text:           #1F1E1D;
    --muted:          #6b6862;
    --subtle:         #9a968d;

    --accent:            #c96442;
    --accent-hover:      #b5563a;
    --accent-weak:       rgba(201, 100, 66, 0.10);
    --btn-primary-bg:    #c96442;
    --btn-primary-hover: #b5563a;
    --btn-primary-text:  #ffffff;
    --user-bubble:       #EDEAE1;

    --success:  #3f7a4e;
    --warning:  #b5762a;
    --danger:   #b5443a;
    --primary:  #c96442;
    --primary-dark: #b5563a;

    /* Semantic status tokens (light) — ok / warn / danger / info bg+text pairs */
    --ok-bg:     #E5EFE6;
    --ok-text:   #2E5C3A;
    --warn-bg:   #F6ECD9;
    --warn-text: #7A5A1E;
    --danger-bg: #F6E0DC;
    --danger-text: #8C3A30;
    --info-bg:   #E8E9F2;
    --info-text: #3E4470;

    --font-sans:  "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --font-serif: "Lora", "Source Serif 4", ui-serif, Georgia, "Times New Roman", serif;
    --font-arabic:"Noto Naskh Arabic", "Amiri", "Segoe UI", sans-serif;
    /* Prompt/composer input boxes only (owner 2026-07-11): Styrene B stand-in.
       Latin subsets only — Arabic input falls through to the system stack. */
    --font-input: "Archivo", "Inter", ui-sans-serif, system-ui, sans-serif;

    --sidebar-width: 288px;
    --mobile-header-h: 52px;   /* sticky top bar shown < 1024px (off-canvas drawer trigger) */
    --radius-sm:  8px;
    --radius-md:  12px;
    --radius-lg:  16px;
    --radius-xl:  24px;

    /* ── Motion (app-wide) ────────────────────────────────────────────────────
       Shared open/close animation grammar so every panel, popover, menu, toast
       and dialog fades the same way — fast and noticeable, never sluggish. Open
       decelerates (ease-out), close accelerates (ease-in). Consume these instead
       of scattering magic durations. All motion that uses them is additionally
       gated behind `html.anim-ready` (added one frame after first paint, so the
       persisted collapsed state paints instantly) and wrapped in
       @media (prefers-reduced-motion: no-preference). */
    --anim-fast: 160ms;                            /* popovers · menus · toasts · fades */
    --anim-med:  200ms;                            /* panels · split-view (larger surfaces) */
    --anim-ease-out: cubic-bezier(0.16, 1, 0.3, 1);   /* open — decelerate into place */
    --anim-ease-in:  cubic-bezier(0.4, 0, 1, 1);      /* close — accelerate away */
}

/* ── Dark ────────────────────────────────────────────────────────────────── */
[data-theme="dark"] {
    --bg:             #262624;
    --bg-raised:      #2E2D2B;
    --bg-secondary:   #2E2D2B;   /* list rows / secondary wells (KB doc lists) */
    --surface:        #30302E;

    --sidebar-bg:     #1F1E1D;
    --sidebar-text:   rgba(255, 255, 255, 0.70);
    --sidebar-strong: #ffffff;
    --sidebar-dim:    rgba(255, 255, 255, 0.60);
    --sidebar-faint:  rgba(255, 255, 255, 0.34);
    --sidebar-line:   rgba(255, 255, 255, 0.08);
    --sidebar-hover:  rgba(255, 255, 255, 0.06);
    --sidebar-active: rgba(255, 255, 255, 0.09);
    --sidebar-well:   rgba(0, 0, 0, 0.20);
    --sidebar-chip:   rgba(255, 255, 255, 0.04);
    --sidebar-accent: #d97757;

    --card:           #2b2a27;
    --card-border:    rgba(255, 255, 255, 0.10);
    --border:         rgba(255, 255, 255, 0.10);
    --input-border:   rgba(255, 255, 255, 0.18);
    --input-focus:    #d97757;

    --text:           #FAF9F5;
    --muted:          #b3afa6;
    --subtle:         #85817a;

    --accent:            #d97757;
    --accent-hover:      #e08a6c;
    --accent-weak:       rgba(217, 119, 87, 0.14);
    --btn-primary-bg:    #d97757;
    --btn-primary-hover: #e08a6c;
    --btn-primary-text:  #ffffff;
    --user-bubble:       #393937;

    --success:  #5fa570;
    --warning:  #d9a24a;
    --danger:   #e0695f;
    --primary:  #d97757;
    --primary-dark: #e08a6c;

    /* Semantic status tokens (dark) — translucent tints over the dark canvas */
    --ok-bg:     rgba(95, 165, 112, 0.18);
    --ok-text:   #8FC79E;
    --warn-bg:   rgba(217, 162, 74, 0.16);
    --warn-text: #D9B577;
    --danger-bg: rgba(224, 105, 95, 0.16);
    --danger-text: #E59B93;
    --info-bg:   rgba(137, 146, 214, 0.18);
    --info-text: #AEB5E8;
}

/* ── Focus-visible ring (P3) ──────────────────────────────────────────────────
   One house keyboard-focus ring for EVERY interactive element, defined once here
   rather than copied per component: a 1px --accent border (where the element has
   a border) plus a 3px --accent-weak halo (spec §1.2). :focus-visible keeps it
   keyboard-only — mouse clicks stay quiet. The broad element/attribute selector
   list is the "strategy" (no 30 per-widget copies). Uses box-shadow, not layout
   borders, so nothing shifts; border-color only tints an existing hairline.
   A handful of components (.cchip, composer send, docs actions, context toggles)
   restate the same ring at higher specificity for a local tweak (radius/offset)
   — all use the identical --accent / --accent-weak tokens, so the house ring is
   uniform. */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible,
[role="button"]:focus-visible,
[role="tab"]:focus-visible,
[role="option"]:focus-visible,
[role="radio"]:focus-visible,
[role="checkbox"]:focus-visible,
[role="menuitem"]:focus-visible {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-weak);
}

/* ── Tooltips ───────────────────────────────────────────────────────────────
   Elements with data-tooltip="..." get an explanatory bubble on hover / keyboard
   focus. The bubble is created and positioned by static/tooltip.js as a SINGLE
   element appended to <body> (position: fixed), so it is NEVER clipped by an
   ancestor's overflow (sidebar, menus) and the positioner flips above/below and
   clamps within the viewport so it can't run off-screen at any resolution.
   Themed via CSS variables → adapts to light/dark; text-align:start → RTL-safe.
   data-tt="bottom" is only a *preference*; the positioner overrides it when
   there isn't room. */
.app-tooltip {
    position: fixed;
    z-index: 9999;
    width: max-content;
    max-width: min(280px, 90vw);
    background: var(--bg-raised);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 6px 10px;
    font-size: 12px;
    line-height: 1.45;
    font-weight: 400;
    text-align: start;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.20);
    opacity: 0;
    transform: translateY(2px);
    transition: opacity .12s ease, transform .12s ease;
    pointer-events: none;          /* never intercepts clicks */
}
.app-tooltip.show { opacity: 1; transform: translateY(0); }
.app-tooltip .app-tooltip-arr {
    position: absolute;
    margin-left: -5px;
    border: 5px solid transparent;
}
.app-tooltip.pos-top    .app-tooltip-arr { top: 100%;    border-top-color: var(--border); }
.app-tooltip.pos-bottom .app-tooltip-arr { bottom: 100%; border-bottom-color: var(--border); }

/* ── Compliance chips (P2-2) ─────────────────────────────────────────────────
   Shared by static/compliance_chips.js. Compact, hairline-bordered status pills
   that sit between a book object's stats and its action row (completion card).
   Semantic status tokens only; logical properties keep them RTL-correct. */
.compliance-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 12px 0;
}
.cchip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    line-height: 1.4;
    padding: 3px 9px;
    border-radius: 999px;
    border: 1px solid var(--border);
    text-decoration: none;
    white-space: nowrap;
    background: var(--surface);
    color: var(--muted);
}
.cchip:hover { border-color: var(--input-border); }
.cchip:focus-visible {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-weak);
}
/* Stroke styling mirrors base.css .icon-sm — without it the #i-* sprite
   symbols fall back to fill:black and render as invisible blobs. */
.cchip-icon {
    width: 12px; height: 12px; flex: 0 0 auto;
    stroke: currentColor; stroke-width: 1.8; fill: none;
    stroke-linecap: round; stroke-linejoin: round;
}
.cchip-dash { font-weight: 600; }
.cchip-label { text-transform: none; }        /* sentence case as authored */
.cchip.cchip-ok        { background: var(--ok-bg);     color: var(--ok-text); }
.cchip.cchip-attention { background: var(--warn-bg);   color: var(--warn-text); }
.cchip.cchip-running   { background: var(--surface);   color: var(--muted); }
.cchip.cchip-notrun    { background: transparent;      color: var(--subtle); }
.cchip.cchip-running .cchip-icon {
    animation: cchip-spin 1s linear infinite;
    transform-origin: center;
}
@keyframes cchip-spin { to { transform: rotate(360deg); } }

/* Flagged-lessons warn callout under the chips (self-diagnosis summary). */
.compliance-flagged {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    margin: 0 0 12px;
    padding: 8px 12px;
    font-size: 12.5px;
    line-height: 1.45;
    border-radius: var(--radius-sm);
    border: 1px solid var(--warn-text);
    background: var(--warn-bg);
    color: var(--warn-text);
}
.compliance-flagged .cchip-icon { width: 14px; height: 14px; margin-top: 2px; }
.compliance-flagged-link { color: var(--warn-text); text-decoration: underline; white-space: nowrap; }
.compliance-flagged-link:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--accent-weak);
    border-radius: 3px;
}

/* ── Thinking activity feed (P2-4, chat path only) ───────────────────────────
   A quiet, de-emphasized reasoning block above the streaming answer. Built ONLY
   when Gemma 4 thinking-mode reasoning arrives (chat.js createThinkingBlock);
   never present on the off path. No accent, hairline restraint, sentence case,
   #i-chevron-right sprite that rotates on expand. Reasoning is never the hero. */
.thinking {
    margin: 4px 0 10px;
    font-family: var(--font-sans);
}
.thinking-head {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 2px 0;
    background: none;
    border: none;
    cursor: pointer;
    color: var(--subtle);
    font-size: 13px;
    line-height: 1.4;
    text-align: start;
}
.thinking-head:hover { color: var(--muted); }
.thinking-head:focus-visible {
    outline: none;
    border-radius: 4px;
    box-shadow: 0 0 0 3px var(--accent-weak);
}
.thinking-label { font-weight: 500; }
.thinking-chev {
    width: 13px; height: 13px; flex: 0 0 auto;
    transition: transform .18s ease;
}
.thinking.is-open .thinking-chev { transform: rotate(90deg); }          /* expanded ▼ */
[dir="rtl"] .thinking:not(.is-open) .thinking-chev { transform: rotate(180deg); } /* collapsed ◄ */
.thinking-body {
    display: none;
    margin-top: 6px;
    padding-inline-start: 19px;      /* aligns under the label; mirrors under RTL */
    font-size: 13px;
    line-height: 1.55;
    color: var(--muted);
    white-space: pre-wrap;
    word-break: break-word;
    overflow-wrap: anywhere;
    max-height: 340px;
    overflow-y: auto;
}
.thinking.is-open .thinking-body { display: block; }
/* Quiet opacity pulse on the label while reasoning actively streams. */
.thinking.is-thinking.is-open .thinking-label {
    animation: thinking-pulse 1.6s ease-in-out infinite;
}
@keyframes thinking-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }

/* ── Reduced motion (P3) ──────────────────────────────────────────────────────
   One consolidated opt-out for every animation/transition declared in this
   stylesheet: the tooltip fade+slide, the compliance-chip spinner, and the
   thinking-feed chevron rotate + label pulse. */
@media (prefers-reduced-motion: reduce) {
    .app-tooltip { transition: none; }
    .cchip.cchip-running .cchip-icon { animation: none; }
    .thinking-chev { transition: none; }
    .thinking.is-thinking .thinking-label { animation: none; }
}
