/*
 * Default Theme — Sage
 *
 * Migrated from Light Blue to Sage design system (v0.8.0).
 * CSS custom properties for easy theming. All color decisions here.
 */

:root {
    /* Primary palette — Sage */
    --primary: #5C6B59;
    --primary-dark: #3A4238;
    --primary-light: #E8EDE6;

    /* Accent colors — Sage */
    --accent: #9CA998;
    --accent-dark: #5C6B59;
    --accent-light: #E8EDE6;

    /* Secondary accent (terra — warm, replaces pink) */
    --pink: #CAB99E;
    --pink-light: #F5F0E8;

    /* Terra palette (warm secondary) */
    --terra: #CAB99E;
    --terra-lo: #DDD0BA;
    --terra-bg: rgba(202, 185, 158, 0.12);
    --terra-text: #7D6340;

    /* Leaning tint (2026-09-02): cool for heavy, warm for light, muted for
       even — `core/valence.py::temper_for`'s three states, painted the same
       on the entry rail, the reflections list bars and the help scale.
       ⛔ Not red and green: a day is not a verdict. Slate and terra are the
       palette's own temperatures. Marks only, never text. */
    --lean-cool: #6B7E94;
    --lean-even: var(--text-muted);
    --lean-warm: #B8996A;

    /* Background colors */
    --background: #F5F5F2;
    --card-background: #FFFFFF;
    /* The composer's writing surface (2026-09-02, Gabriel: "a slightly
       different color of the editing area and the rest of the page").
       A shade between the page and a card, so the words sit on paper. */
    --surface-writing: #FCFCFA;
    --background-hover: #ECEEE9;

    /* Sage surface variants */
    --surface: #FFFFFF;
    --card-bg: #E8EDEA;
    --bento-bg: #EDEEE9;
    --hero-bg: #ECEEE9;

    /* Border colors
     *
     * ⛔ **A CARD YOU CANNOT SEE IS NOT A CARD** (2026-09-07). The whole
     * grammar rests on one signal — *the card goes on the item; the name goes
     * on the ground* — and it was being carried by a difference nobody could
     * see. Measured: a white card on `--background` is **1.09:1**, and at
     * alpha 0.09 the hairline meant to give it an edge composited to #EBECEB,
     * **1.18:1** against the card. Gabriel had said so repeatedly — *"the same
     * colour of the background seems strange, and that is the same that I said
     * for almost all screen"* — first about the calendar, where thirty-five
     * cells read as a scatter, and then about nearly every screen.
     *
     * ⭐ **The edge does the work, not the ground.** Four candidates were put
     * side by side on the real components in both themes; Gabriel picked the
     * one that leaves the palette alone. `--background` is untouched: only this
     * line and its dark mirror moved, 0.09 → 0.16, taking the hairline to
     * **1.36:1** on the card.
     *
     * ⚠️ **3:1 IS THE WRONG TARGET HERE AND CHASING IT WOULD RUIN THE APP.**
     * WCAG 1.4.11 asks 3:1 of a graphic that carries meaning, and a hairline in
     * this palette cannot reach it — even alpha 0.28 stops at 1.77:1, and past
     * that it draws a wireframe rather than Pensio. The one mark where 3:1
     * genuinely applies is the calendar's written-day patch, and that carries
     * its meaning in SHAPE and in a spoken sentence, never in colour alone.
     *
     * 📐 docs/research/design/2026-09/2026-09-07-ground-and-edge/
     */
    --border-color: rgba(35, 40, 32, 0.16);
    --border-light: rgba(35, 40, 32, 0.05);

    /* Text colors — ink hierarchy
     *
     * Three TEXT steps, all AA (>= 4.5:1) on every ground we paint on
     * (--background #F5F5F2, --bento-bg #EDEEE9, --card-background #FFF):
     *
     *   --text-color      #232820  primary body text      13.8 / 12.9 / 15.0
     *   --text-secondary  #4A5448  secondary / metadata    7.3 /  6.8 /  8.0
     *   --text-muted      #61705C  tertiary / hints        4.8 /  4.5 /  5.3
     *
     * ⚠️ --card-bg (#E8EDEA) is the one ground --text-muted does NOT clear:
     * 4.45:1. Nothing pairs them today — both --card-bg surfaces
     * (relationship-list, token-list) carry --text-secondary — so this is a
     * gap to respect, not a bug to fix. Put --text-secondary on --card-bg.
     *
     * ⛔ --ink-faint is NOT a text colour. At 2.8:1 on --background and
     * 2.6:1 on --bento-bg it fails AA on every ground; it is kept only for
     * NON-TEXT use — icon strokes, hairlines, dot markers — where the 3:1
     * non-text threshold (WCAG 1.4.11) applies. Muted TEXT uses --text-muted.
     * Rule + ratios: docs/admin/design_system.md -> Text.
     */
    --text-color: #232820;
    --text-secondary: #4A5448;
    --text-muted: #61705C;
    --text-inverse: #FFFFFF;
    --ink: #232820;
    --ink-mid: #4A5448;
    --ink-faint: #8A9689;   /* non-text only — see note above */
    --title: #3A4238;
    --sage-text: #3A6850;

    /* Status colors (functional — kept universal) */
    --success: #22c55e;
    --success-dark: #15803d;
    --success-bg: #dcfce7;
    --success-text: #155724;
    --success-border: #c3e6cb;
    --warning: #f59e0b;
    --warning-bg: #fef3c7;
    --warning-text: #856404;
    --warning-border: #ffeeba;
    --error: #ef4444;
    --error-bg: #fee2e2;
    --error-text: #721c24;
    --error-border: #f5c6cb;
    --info: #5C6B59;
    --info-bg: #E8EDE6;
    --info-text: #3A4238;
    --info-border: #9CA998;

    /* Danger (buttons) */
    --danger: #dc2626;
    --danger-dark: #b91c1c;

    /* Shadows — sage-tinted */
    --shadow-sm: 0 1px 4px rgba(35, 40, 32, 0.05);
    --shadow-md: 0 4px 16px rgba(35, 40, 32, 0.07);
    --shadow-lg: 0 8px 32px rgba(156, 169, 152, 0.18);
    --shadow-xl: 0 12px 40px rgba(156, 169, 152, 0.12);

    /* Border radius — Sage-style (larger, softer) */
    --border-radius: 16px;
    --border-radius-sm: 10px;
    --border-radius-lg: 20px;

    /* Typography */
    --font-family: 'Plus Jakarta Sans', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --font-heading: 'Outfit', sans-serif;
    --font-body: 'Plus Jakarta Sans', sans-serif;
    --font-serif: 'Lora', serif;
    --font-hand: 'Caveat', cursive;
    --font-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;

    /* Transitions */
    --transition-fast: 0.15s ease;
    --transition-base: 0.2s ease;
    --transition-slow: 0.3s ease;

    /* Hover */
    --hover-color: #ECEEE9;

    /* Extra radii */
    --radius-pill: 100px;
    --radius-xl: 24px;

    /* ─────────────────────────────────────────────────────────────
     * Blueprint alignment — Phase E.2 (v0.21.2)
     * Additive token set: spacing scale, motion durations, named
     * easings, border widths, icon sizes. Existing tokens above are
     * unchanged. Values derived from Pensio's actual usage
     * frequencies; naming keeps `--space-base` for the 1rem unit
     * and reserves `--space-md` for Pensio's heavily-used 12px.
     * Plan: docs/phases/v0.21.1-design-system-audit.md
     * ─────────────────────────────────────────────────────────────
     */

    /* Spacing scale (Pensio mapping) */
    --space-2xs: 0.25rem;   /* 4px */
    --space-xs: 0.375rem;   /* 6px — off-grid, heavily used */
    --space-sm: 0.5rem;     /* 8px */
    --space-md: 0.75rem;    /* 12px — off-grid, heavily used */
    --space-base: 1rem;     /* 16px — canonical 1-unit */
    --space-lg: 1.25rem;    /* 20px — off-grid, heavily used */
    --space-xl: 1.5rem;     /* 24px */
    --space-2xl: 2rem;      /* 32px */

    /* Motion durations (additive — --transition-* tokens above remain) */
    --duration-quick: 120ms;
    --duration-normal: 200ms;
    --duration-emphasis: 350ms;
    --duration-celebration: 500ms;

    /* Easings (named curves; existing transitions default to plain `ease`) */
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
    --ease-in-out: cubic-bezier(0.45, 0, 0.55, 1);
    --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);

    /* Border widths */
    --border-width: 1px;
    --border-width-md: 2px;
    --border-width-lg: 3px;

    /* Icon sizes */
    /* ⭐ **THE COLOUR A LINE MARK TAKES INSIDE A CONTROL** (2026-09-06).
       Gabriel: *"the say, handwrite and focus are like white and the others
       have shades of green."* A line mark inherited `--text-color` (#232820),
       so beside the nav's two-tone green glyphs it read as a plain dark
       hairline. `--primary` is the middle green of the same family — the
       glyphs' detail tone is `--primary-dark` (#3A4238) and their body is
       `--accent` (#9CA998) — and it lifts to #AEC0A9 in dark on its own.
       ⛔ A single stroke cannot BE two tones; this is the closest one that
       reads as the same family. 📐 components/buttons.css `.btn__mark`. */
    --icon-mark: var(--primary);
    --icon-size-sm: 1rem;     /* 16px — inline-text icons */
    --icon-size: 1.5rem;      /* 24px — default, matches existing partials */
    --icon-size-lg: 2rem;     /* 32px — feature/empty-state icons */

    /* ⭐ **THE BOTTOM BAR'S HEIGHT, NAMED ONCE** (2026-09-10). The web
     * `.mobile-bottom-nav` and the native shells' tab bars are all 56px, and
     * the number was written out by hand in four files — `side-nav.css`,
     * `constellation.css`, `entry-form.css` and `explore.css` — each with its
     * own comment re-deriving it. A control that has to clear the bar reads
     * this instead.
     *
     * ⛔ **THE NATIVE TAB BAR IS DRAWN OVER THE WEB VIEW, AND
     * `env(safe-area-inset-bottom)` DOES NOT KNOW ABOUT IT.** That inset is the
     * home indicator only. Anything anchored to the bottom of the viewport
     * inside a shell needs BOTH: `calc(var(--bottom-bar) + env(safe-area-inset-bottom, 0px))`.
     * The voice recorder's stop button was covered on an iPad because it had
     * only the second half. */
    --bottom-bar: 56px;

    /* Typography scale (v0.41.1) — token-first type sizes. Floors:
     * running text ≥ --text-base-sm, meta ≥ --text-xs, badges ≥ --text-2xs;
     * inputs stay ≥ 1rem (iOS focus-zoom). Line-height pairing: 1.4 (≤ sm),
     * 1.5 (UI), 1.6–1.7 (prose). New CSS uses these tokens — no raw px;
     * legacy hardcoded values migrate opportunistically (nearest step). */
    --text-2xs: 0.6875rem;     /* 11px — badges, 1-3 char counters */
    --text-xs: 0.75rem;        /* 12px — meta floor */
    --text-sm: 0.8125rem;      /* 13px — labels, dense UI */
    --text-md: 0.875rem;       /* 14px — secondary UI text */
    --text-base-sm: 0.9375rem; /* 15px — dense-prose floor */
    --text-base: 1rem;         /* 16px — body */
    --text-lg: 1.125rem;       /* 18px */
    --text-xl: 1.25rem;        /* 20px */
    --text-2xl: 1.5rem;        /* 24px */
    --text-3xl: 2rem;          /* 32px */

    /* Aliases — backward-compatible naming convention */
    --accent-primary: var(--primary);
    /* Sage that is safe as TEXT/icon on a light surface (same #5C6B59 that
     * marketing-theme.css declares). themes/dark.css declared this and only
     * this, with the comment "undefined in light" beside it — a note next to a
     * defect is not a fix, and every app call site inherited instead of
     * painting. Same role as --accent-on-surface below; kept because 12 app +
     * 106 marketing rules already ask for it by this name. */
    --accent-text: var(--accent-dark);
    --bg-primary: var(--card-background);
    --bg-secondary: var(--background);
    --bg-accent: var(--primary-light);
    --text-primary: var(--text-color);
    /* The --semantic-* family had only its success member, so the usage meter
     * painted green at low and NOTHING at mid or high — `background:
     * var(--semantic-warning)` is invalid at computed-value time, and an
     * invalid background is transparent, not an error. Aliases, not new
     * colours: --success/--warning/--error themselves are untouched. */
    --semantic-success: var(--success);
    --semantic-warning: var(--warning);
    --semantic-error: var(--error);
    --radius-sm: var(--border-radius-sm);
    --radius-md: var(--border-radius);
    --radius-lg: var(--border-radius-lg);

    /* ─────────────────────────────────────────────────────────────
     * Dark-mode foundations (v0.55.0). Two additive sets:
     *   1. Fixed base-palette steps — theme-independent hues the dark
     *      map points at (see static/css/themes/dark.css).
     *   2. A thin semantic layer. Existing components keep consuming the
     *      base tokens above; NEW components should prefer these so a
     *      future theme is a clean one-to-one remap. The overloaded base
     *      tokens (--primary used as both text and fill) are split here
     *      into surface-text vs fill+on-fill roles.
     * Plan: docs/phases/v0.55.0-dark-mode.md
     * ───────────────────────────────────────────────────────────── */

    /* Tell the UA the app renders its OWN light/dark — stops the browser /
     * Android System WebView from algorithmically double-inverting our dark
     * CSS, while still letting prefers-color-scheme report the real setting.
     * dark.css overrides this to `dark`. */
    color-scheme: light;

    /* 1. Fixed base steps */
    --sage-300: #AEC0A9;   /* lifted sage — text/icon & fill on dark      */
    --sage-400: #9CB097;   /* accent on dark (bars, chips)                */
    --sage-deep: #3C5340;  /* user chat-bubble fill on dark               */
    --ink-0: #14180F;      /* near-black warm — text on light-sage fills  */
    --ink-1: #232820;      /* raised dark surface — the recording screen  */
    --paper-0: #E7EAE0;    /* warm off-white — body text on dark          */
    --terra-300: #D8C5A4;  /* lifted terra on dark                        */

    /* 2. Semantic layer (theme-mapped; remapped in themes/dark.css) */
    --surface-ground: var(--background);        /* page background         */
    --surface-raised: var(--card-background);   /* cards, nav, inputs      */
    --surface-inset: var(--bento-bg);           /* inset fills, tracks     */
    --surface-hover: var(--background-hover);   /* hover ground            */
    /* ⭐ THE card radius, one line. `/entries/` ships 20px and Gabriel liked
       it; the canvas frames draw 16px 215 times. One token means the answer
       lives here rather than in every sheet — flip to var(--border-radius)
       if 16 is ever wanted. Geometry, so dark.css needs nothing.
       📐 docs/admin/design_system.md "The card goes on the item" */
    --radius-card: var(--border-radius-lg);

    /* ⭐ **THE PAGE MEASURE.** The width of the content column on every
       single-column screen, and the width `.card-stack`, `.list-surface` and
       `.group` cap themselves to — one number, so the page's header, its
       section headings and its items share both edges and the column does not
       move when she navigates. It was six different numbers on 2026-09-05.
       ⚠️ **44rem WAS TOO NARROW AND IT WAS MEASURED, NOT FELT.** At 1280 with
       the 188px side nav the content area is ~1092px, so a 704px column left
       ~194px of nothing on each side and the page floated away from the nav it
       belongs to. Gabriel, 2026-09-06: *"the width is too narrow … it feels
       like a lot of empty space on the sides … it is too far even from the side
       menu."* 52rem (832px) leaves ~130px a side, which reads as a margin
       rather than a gap.

       ⛔ **THIS IS NOT THE READING MEASURE AND MUST NOT BECOME IT.** Her words
       are `.prose`, capped at **66ch** in `components/type.css`, so widening
       this does not lengthen a single line of anything anyone reads. What it
       widens is the furniture — cards, rows, headings — which had no reason to
       be at a prose measure in the first place.

       📐 components/page.css, and docs/admin/design_system.md "The measure". */
    --measure-page: 52rem;
    --text-body: var(--text-color);             /* primary text            */
    --text-title: var(--title);                 /* headings                */
    --border-faint: var(--border-light);        /* faint divider           */
    --accent-on-surface: var(--accent-dark);    /* sage text/icon on surface/tint (#5C6B59) */
    --accent-tint: var(--primary-light);        /* sage tint fill (active nav, badge)        */
    --accent-fill: var(--primary);              /* primary button / send fill                */
    --accent-on-fill: #FFFFFF;                  /* text/icon on --accent-fill                */
    --chat-user-fill: var(--primary);           /* user chat-bubble fill   */
    --chat-user-text: #FFFFFF;                  /* text on user bubble     */
}

/* Text-size preference (v0.41.1 — Settings → Account → Display).
 * The app CSS is ~95% rem-based, so scaling the rem root scales every
 * surface at once. The native shells pin user-scalable=no in the viewport
 * meta, which makes this the accessibility path for low-vision users.
 * Class is set on <html> by templates/base.html from User.text_size. */
html.text-size-large { font-size: 17.5px; }
html.text-size-xlarge { font-size: 19px; }