/**
 * Base theme — TrainersMap brand tokens.
 * Ported from user-account `static/styles/base.css`; values are the TrainersMap palette.
 *
 * - `/theme-bootstrap.js` in `app.html` runs before these sheets (first paint matches persisted theme).
 * - Linked from `app.html` before `main.css` (static asset: `/styles/base.css`).
 * - `themeManager` (`lib/utility/settings/themes/manage.ts`) sets `data-theme`, `data-font-size`, `data-animation-speed`.
 * - THE ONLY PLACE BRAND COLORS ARE WRITTEN. Feature CSS uses `var(--app-*)`.
 * - Brand is red / white / black. `--app-fresh` is marketplace "New" only. Status colors (success, warning, error) and `--app-online` are not brand. Success stays green.
 */

/* Light (default) */
:root {
    color-scheme: light;

    --app-font-system: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --app-font-body: "Avenir Next", Avenir, "Inter Variable", Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --app-font-heading: var(--app-font-body);
    /* Brand display face. The folded-rune font built from the fold-type specimen.
       Faces are generated into /styles/fonts.css by deck/fonts/build.py. */
    --app-font-display: "TrainersMap", var(--app-font-heading);
    --app-font-digital: digital, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
    /* @ in username handles. Handle body stays --app-font-digital. Carlito is the metric Calibri stand-in on Linux. */
    --app-font-at: Calibri, Carlito, "Segoe UI", sans-serif;

    --app-bg: #f5f5f5;
    --app-surface: #ffffff;
    --app-bg-highlight: #eeeeee;
    --app-text: #111111;
    --app-text-dim: #6b6b6b;
    /* Inline <code> chip — wash of ink on paper, not --app-text-dim. */
    --app-code-bg: color-mix(in srgb, var(--app-text) 12%, var(--app-surface));
    /* Fenced code in chat — fallback ink if a block renders off a bubble. Bubbles remap via --code-ink. */
    --app-code-block-bg: #141414;
    --app-on-code-block: #e6e6e6;
    --app-code-block-dim: #8a8a8a;
    --app-code-block-border: rgba(255, 255, 255, 0.14);
    --app-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
    --app-accent: #111111;
    --app-on-accent: #ffffff;
    --app-pin: #ef233c;
    --app-on-pin: #ffffff;
    --app-active: var(--app-pin);
    --app-brand-lime: var(--app-pin);
    /* Marketplace "New" badge. Not a brand color. */
    --app-fresh: #1a6fd4;
    --app-on-fresh: #f3f8ff;
    --app-border: #e0e0e0;
    /* Field chrome — charcoal (`--app-text` / dark-mode `--app-bg`). Dividers stay `--app-border`. */
    --app-input-border: var(--app-text);
    /* Status green. Same role as warning / error. Not brand. */
    --app-success: #2b8c69;
    /* Presence dot only. Not a brand color. */
    --app-online: #22c55e;
    --app-warning: #f3a925;
    --app-error: #c83838;
    --app-on-error: #ffffff;
    /* Leaflet canvas behind tiles + the "you are here" pin. Not brand. */
    --app-map-bg: #dce7ea;
    --app-map-you: #2078e8;

    --app-radius: 0.9rem;
    --app-overlay: rgba(0, 0, 0, 0.45);
    /* Full-screen photo lightbox: near-black in both themes, light glyphs on top. */
    --app-lightbox-bg: rgba(0, 0, 0, 0.92);
    --app-on-lightbox: #f4f4f4;
    --app-shadow-color: rgba(0, 0, 0, 0.08);
    --app-shadow-color-strong: rgba(0, 0, 0, 0.25);
    --app-shadow: 0 8px 24px var(--app-shadow-color);
    --app-focus-ring: 0 0 0 3px rgba(239, 35, 60, 0.35);

    /* Brand marks that should flip with theme */
    --logo-filter: none;

    /* Window chrome — duplicate in main.css; change both if you resize bars */
    --status-bar-height: 20px;
    --chrome-bar-height: 26px;
    /* Reserved scrollbar gutter for a `scrollbar-gutter: stable` scrollport. Overlay scrollbars
       reserve nothing, so anything positioned against the viewport edge (the compose FAB) needs
       this to clear the bar instead of sitting 4px beside it. */
    --scrollbar-width: 16px;
    /* Home Screen bar: side clearance past the phone corners, and the top radius.
       Safari-in-browser ignores these. The bar itself sits on the glass. */
    --status-bar-tray-inset: 16px;
    --status-bar-tray-radius: 10px;
    --font-size-chrome-status-readout: 11px;
    --font-size-chrome-status-btn: 12px;

    /* Dialog / sheet stacking above sticky site header (site-header.css z 100) and status bar (10040). */
    --app-dialog-overlay-z: 10060;
    --app-dialog-content-z: 10061;

    /* Landing hero — always dark, both themes. Red is `--app-pin`. */
    --app-hero-bg: #141414;
    --app-hero-text: #ffffff;
    --app-hero-text-dim: #9a9a9a;
    --app-hero-grid: rgba(255, 255, 255, 0.045);
    /* Above header (30) + status bar (10040); below site notice (10050) + dialogs (10060). */
    --app-hero-z: 10045;
}

/* Dark */
[data-theme="dark"] {
    color-scheme: dark;
    scrollbar-color: var(--app-border) var(--app-bg);
    --app-bg: #111111;
    --app-surface: #1a1a1a;
    --app-bg-highlight: #242424;
    --app-text: #f5f5f5;
    --app-text-dim: #9a9a9a;
    --app-accent: #ffffff;
    --app-on-accent: #111111;
    --app-pin: #ef233c;
    --app-on-pin: #ffffff;
    --app-active: var(--app-pin);
    --app-brand-lime: var(--app-pin);
    --app-fresh: #27456f;
    --app-on-fresh: #c5d8f2;
    --app-border: #2e2e2e;
    --app-input-border: var(--app-border);
    --app-success: #4fc48f;
    --app-online: #4ade80;
    --app-warning: #f5b43a;
    --app-error: #ff6b6b;
    --app-on-error: #ffffff;
    --app-map-bg: #1b2126;
    --app-map-you: #5b9cff;
    --app-overlay: rgba(0, 0, 0, 0.65);
    --app-shadow-color: rgba(0, 0, 0, 0.5);
    --app-shadow-color-strong: rgba(0, 0, 0, 0.7);
    --app-focus-ring: 0 0 0 3px rgba(239, 35, 60, 0.3);
    --logo-filter: none;
}

/* Light (explicit) */
[data-theme="light"] {
    color-scheme: light;
    scrollbar-color: var(--app-border) var(--app-bg);
}

/* Font size steps */
:root,
[data-font-size="medium"] {
    --font-size-base: 15px;
    --font-size-small: 13px;
    --font-size-large: 17px;
    --font-size-h1: 30px;
    --font-size-h2: 22px;
    --font-size-h3: 18px;
    --font-size-h4: 15px;
    --font-size-h5: 14px;
    --font-size-h6: 13px;
    --font-size-button: 14px;
    --font-size-label: 13px;
    --font-size-caption: 12px;
    --font-size-table: 14px;
    --font-size-modal: 16px;
    --font-size-status: 13px;
}

[data-font-size="small"] {
    --font-size-base: 13px;
    --font-size-small: 11px;
    --font-size-large: 15px;
    --font-size-h1: 26px;
    --font-size-h2: 19px;
    --font-size-h3: 16px;
    --font-size-h4: 13px;
    --font-size-h5: 12px;
    --font-size-h6: 11px;
    --font-size-button: 12px;
    --font-size-label: 11px;
    --font-size-caption: 10px;
    --font-size-table: 12px;
    --font-size-modal: 14px;
    --font-size-status: 11px;
}

[data-font-size="large"] {
    --font-size-base: 17px;
    --font-size-small: 15px;
    --font-size-large: 19px;
    --font-size-h1: 34px;
    --font-size-h2: 25px;
    --font-size-h3: 20px;
    --font-size-h4: 17px;
    --font-size-h5: 16px;
    --font-size-h6: 15px;
    --font-size-button: 16px;
    --font-size-label: 15px;
    --font-size-caption: 14px;
    --font-size-table: 16px;
    --font-size-modal: 18px;
    --font-size-status: 15px;
}

/* Animation speed */
:root,
[data-animation-speed="normal"] {
    --animation-duration-fast: 0.15s;
    --animation-duration-normal: 0.3s;
    --animation-duration-slow: 0.5s;
}

[data-animation-speed="fast"] {
    --animation-duration-fast: 0.1s;
    --animation-duration-normal: 0.2s;
    --animation-duration-slow: 0.3s;
}

[data-animation-speed="slow"] {
    --animation-duration-fast: 0.25s;
    --animation-duration-normal: 0.5s;
    --animation-duration-slow: 0.8s;
}

/*
 * Theme flip (`themeManager.applySettings` => `crossfadeTheme`). The fade is one View Transitions
 * screenshot crossfade: `crossfadeTheme` snapshots the old palette, commits the new one, and the
 * browser dissolves the two page images on the compositor. One animation for the whole page, so
 * thousands of elements do not run per-element transitions on the main thread (that was slow and
 * glitchy) and un-animatable paints (logo swap, scrollbars) fade too.
 *
 * The `data-theme-transition` window covers only the commit frame. The "new" snapshot is captured
 * right after `commit`; an element still running its own transition in that frame (pressed buttons'
 * `transition-all`, the split grip's background, input `transition-colors`) is photographed with a
 * stale color and visibly trails the crossfade. Under the marker, transitions are OFF so the
 * snapshot lands on final values; it clears one frame later and normal hover/press fades return.
 * Reduced motion never calls `startViewTransition`, so this never applies.
 */
html[data-theme-transition] *,
html[data-theme-transition] *::before,
html[data-theme-transition] *::after {
    transition: none !important;
}

/*
 * View Transitions crossfade
 */
::view-transition-old(root),
::view-transition-new(root) {
    animation-duration: 0.25s;
    animation-timing-function: ease;
}

/* The root snapshot already carries the whole page; the default group animation would double it. */
::view-transition-group(root) {
    animation-duration: 0.25s;
}

/*
 * Shadcn subtree bridge: semantic vars inherit from `--app-*` on a wrapper when a portal
 * needs a coherent subtree. Global defaults map in `lib/tailwind.css` (`:root`).
 */
.app-shadcn-surface {
    --background: var(--app-bg);
    --foreground: var(--app-text);
    --card: var(--app-surface);
    --card-foreground: var(--app-text);
    --popover: var(--app-surface);
    --popover-foreground: var(--app-text);
    --primary: var(--app-accent);
    --primary-foreground: var(--app-on-accent);
    --secondary: var(--app-bg-highlight);
    --secondary-foreground: var(--app-text);
    --muted: var(--app-bg-highlight);
    --muted-foreground: var(--app-text-dim);
    --accent: var(--app-bg-highlight);
    --accent-foreground: var(--app-text);
    --destructive: var(--app-error);
    --destructive-foreground: var(--app-surface);
    --border: var(--app-border);
    --input: var(--app-input-border);
    --ring: var(--app-active);
}
