/**
 * KUNAI Mouse Driver — Base Styles
 * Foundation layer: design tokens, reset, typography, layout shell.
 *
 * Load order (mirrors Titan): kunai-base.css → kunai-ui.css → kunai-shine.css
 * Identity: Titan's machined-black-under-one-light discipline, recolored to a
 * single crimson edge. "Murdered-out blade." See docs/kunai-redesign-spec.md.
 */

/* =============================================================================
   1. FONTS
   ============================================================================= */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@500;600&display=swap');

/* =============================================================================
   2. DESIGN TOKENS
   ============================================================================= */
:root {
    /* --- Backgrounds: dark → light scale --- */
    --bg-app: #050505;
    --bg-sidebar: rgba(20, 20, 20, 0.6);
    --bg-panel: rgba(30, 30, 30, 0.5);
    --bg-panel-solid: #161616;
    --bg-input: #111111;
    --bg-input-hover: #1a1a1a;
    --bg-surface: #181818;
    --bg-surface-alt: #222222;
    --bg-elevated: #2a2a2a;

    /* --- Material: Glass (panels, stage surfaces, large cards) --- */
    --glass-surface: rgba(20, 20, 20, 0.6);
    --glass-surface-strong: rgba(20, 20, 20, 0.72);
    --glass-control: rgba(255, 255, 255, 0.05);
    --glass-control-hover: rgba(255, 255, 255, 0.10);
    --glass-control-active: rgba(255, 255, 255, 0.12);
    --glass-border: rgba(255, 255, 255, 0.10);
    --glass-border-strong: rgba(255, 255, 255, 0.12);
    --glass-blur: blur(20px);
    --glass-shadow:
        inset 0 1px 1px rgba(255, 255, 255, 0.06),
        0 4px 24px rgba(0, 0, 0, 0.3);
    --glass-shadow-hover:
        inset 0 1px 1px rgba(255, 255, 255, 0.16),
        0 6px 28px rgba(0, 0, 0, 0.35);
    --glass-edge-mask: linear-gradient(
        180deg,
        rgba(255, 255, 255, 0.12) 0%,
        rgba(255, 255, 255, 0.04) 40%,
        rgba(255, 255, 255, 0) 60%,
        rgba(255, 255, 255, 0.03) 80%,
        rgba(255, 255, 255, 0.08) 100%);
    --glass-scrim: rgba(2, 2, 4, 0.82);

    /* --- Material: Overlay (modals, drawers, popovers, dropdowns) --- */
    --overlay-surface: rgba(14, 14, 14, 0.89);
    --overlay-surface-solid: rgb(14, 14, 14);
    --overlay-border: rgba(255, 255, 255, 0.10);
    --overlay-border-strong: rgba(255, 255, 255, 0.14);
    --overlay-blur: blur(10px);
    --overlay-blur-soft: blur(6px);

    /* --- Edge-highlight grammar: the "top lip catching overhead light" --- */
    --edge-highlight-subtle: inset 0 1px 0 rgba(255, 255, 255, 0.04);
    --edge-highlight: inset 0 1px 0 rgba(255, 255, 255, 0.05);
    --edge-highlight-strong: inset 0 1px 0 rgba(255, 255, 255, 0.06);
    --edge-highlight-bright: inset 0 1px 0 rgba(255, 255, 255, 0.08);

    --overlay-shadow: var(--edge-highlight), 0 20px 44px rgba(0, 0, 0, 0.34);
    --overlay-shadow-strong: var(--edge-highlight-strong), 0 24px 60px rgba(0, 0, 0, 0.42);
    --overlay-shadow-drawer: var(--edge-highlight), -18px 0 40px rgba(0, 0, 0, 0.34);

    /* --- Material: Tooltip (transient, near-opaque, no blur) --- */
    --tooltip-surface: rgba(16, 16, 16, 0.96);
    --tooltip-border: rgba(255, 255, 255, 0.08);
    --tooltip-shadow: var(--edge-highlight-subtle), 0 16px 34px rgba(0, 0, 0, 0.34);

    /* --- Borders --- */
    /* Passive stroke: the outline of a surface that groups, and every divider
       inside one. Deliberately a step under --glass-border, which is what a
       control draws at rest. The two were the same value, so an outline said
       nothing about whether a thing could be pressed, and a card of segments
       read as a table. Hierarchy: 0.06 groups, 0.10 can be pressed, 0.12 is
       under the pointer, accent is chosen. */
    --border-subtle: rgba(255, 255, 255, 0.06);
    --border-medium: #444444;

    /* --- Text: 4-tier hierarchy + value/link --- */
    --text-bright: #FFFFFF;
    --text-primary: #E0E0E0;
    --text-secondary: #B0B0B0;
    --text-tertiary: #A0A0A0;
    --text-value: rgba(var(--accent-rgb), 0.95);

    /* --- Type scale --- */
    --text-caption: 11px;
    --text-xs: 12px;
    --text-sm: 13px;
    --text-base: 14px;
    --text-md: 15px;
    --text-lg: 17px;
    --text-title: 19px;
    --text-xl: 21px;
    --text-icon: 24px;   /* a glyph box, not type: unchanged */
    --text-display: 29px;
    --text-display-fluid: clamp(22px, 2.2vw, var(--text-display));
    --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

    /* --- Accent: CRIMSON ("blade") — the one hue. red = active/live/primary --- */
    --accent: #FF333F;
    --accent-rgb: 255, 51, 63;
    --accent-hover: #E11D2B;
    --accent-pressed: #C2161F;
    /* Aliases so any leftover Titan-derived snippet still resolves to crimson. */
    --accent-blue: var(--accent);
    --accent-blue-rgb: var(--accent-rgb);
    --accent-blue-hover: var(--accent-hover);
    --accent-blue-pressed: var(--accent-pressed);
    /* Destructive shares the hue; distinguished by treatment (outlined vs solid). */
    --accent-red: var(--accent);
    --accent-red-rgb: var(--accent-rgb);
    --accent-red-hover: var(--accent-hover);
    /* Rare warning amber. */
    --accent-warning: #FF9F0A;
    --accent-warning-rgb: 255, 159, 10;

    /* --- Press-feedback tiers: every :active uses one of these --- */
    --press-deep: 0.92;     /* small icon buttons */
    --press-standard: 0.97; /* most buttons, pills, chips */
    --press-subtle: 0.98;   /* low-friction choosers (options, cards) */

    /* --- Radii --- */
    --radius-xs: 4px;
    --radius-sm: 8px;
    --radius-md: 12px;
    --radius-lg: 16px;
    --radius-xl: 24px;
    --radius-pill: 9999px;
    --surface-radius-primary: var(--radius-xl);
    --surface-radius-secondary: var(--radius-md);

    /* --- Control & surface geometry --- */
    --control-height-md: 36px;
    --control-padding-compact: 0 14px;
    --control-padding-md: 0 16px;
    --surface-padding-md: 16px;
    --surface-padding-panel: 16px 20px;
    --surface-padding-compact: 12px 16px;
    --surface-padding-popover: 14px 18px;
    --surface-padding-lg: 24px;

    /* --- Component-specific --- */
    --slider-thumb: #C8C8C8;
    /* The band under a track that its printed values stand in: a 5px tick, a
       5px gap and a 15px line, measured rather than guessed, or the labels hang
       out of the band and lean on whatever row comes next. A token, not a local:
       the scale is used inside the resolution grid and on its own under the
       sensor sliders, and where it was undefined the band collapsed to nothing.
       Re-measured when the type scale moved up a step. */
    --scale-ticks: 25px;

    /* --- Active / focus ring: 4-layer crimson halo --- */
    --active-state:
        inset 0 1px 0 0 rgba(255, 255, 255, 0.1),
        inset 0 0 0 1px rgba(var(--accent-rgb), 0.38),
        0 0 0 1px rgba(var(--accent-rgb), 0.92),
        0 0 0 3px rgba(var(--accent-rgb), 0.1);

    /* --- Animation: easings --- */
    --ease-ios: cubic-bezier(0.25, 1, 0.5, 1);
    --ease-balanced: cubic-bezier(0.4, 0, 0.2, 1);
    --ease-squish: cubic-bezier(0.175, 0.885, 0.32, 1.275);
    --ease-pop: cubic-bezier(0.34, 1.56, 0.64, 1);

    /* --- Animation: duration ladder --- */
    --duration-snap: 0.03s;
    --duration-micro: 0.1s;
    --duration-quick: 0.16s;
    --duration-base: 0.22s;
    --duration-reveal: 0.32s;
    --duration-settle: 0.4s;
    --duration-emphasis: 0.58s;
    --duration-reduce-motion: 0.00001s;

    /* --- Animation: per-surface motion presets --- */
    --motion-float-duration: var(--duration-quick);
    --motion-float-distance: 8px;
    --motion-float-scale: 0.992;
    --motion-menu-duration: var(--duration-quick);
    --motion-menu-distance: 5px;
    --motion-modal-duration: var(--duration-quick);
    --motion-modal-distance: 8px;
    --motion-drawer-duration: var(--duration-reveal);

    /* --- Stacking layers --- */
    --z-under: -1;
    --z-base: 0;
    --z-local: 1;
    --z-local-raised: 2;
    --z-local-top: 3;
    --z-chrome: 10;
    --z-sticky: 40;
    --z-popover: 100;
    --z-drawer: 800;
    --z-modal: 1000;
    --z-modal-content: 1010;
    --z-tooltip: 2000;
    --z-overlay: 4000;
    --z-toast: 9000;

    /* Static shine constant (matches Titan; never updated at runtime). */
    --btn-shine: 1;
}

/* =============================================================================
   3. RESET & BASE
   ============================================================================= */
* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    user-select: none;
}

/* The global no-select is for chrome, not for fields: a value you cannot
   select is a value you cannot retype. */
input, textarea, [contenteditable] { user-select: text; }

*:focus { outline: none; }

*:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

input:focus-visible,
textarea:focus-visible,
button:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

input[type="range"]:focus-visible { outline: none; }
input[type="range"]:focus-visible::-webkit-slider-thumb {
    box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.4);
}
input[type="range"]:focus-visible::-moz-range-thumb {
    box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.4);
}

.hidden { display: none !important; }

/* Windows spinner arrows are OS chrome sitting in the middle of a black
   product. Every number in this driver is typed or dragged, never nudged. */
input[type="number"] {
    -moz-appearance: textfield;
    appearance: textfield;
}
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.sr-only {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

/* Scrollbar — slim floating pill, brightens on hover */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.1);
    border-radius: var(--radius-pill);
    border: 2px solid var(--bg-app);
}
::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.2); }

/* =============================================================================
   4. TYPOGRAPHY
   ============================================================================= */
body {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    font-size: var(--text-base);
    font-weight: 400;
    color: var(--text-secondary);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: geometricPrecision;
}

h1, h2, h3, h4, button, input, textarea {
    font-family: inherit;
}

button {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* =============================================================================
   5. LAYOUT SHELL
   ============================================================================= */
body {
    background-color: var(--bg-app);
    height: 100vh;
    width: 100vw;
    overflow: hidden;
    display: flex;
}

/* The page light lives here rather than on <body> on purpose: the opacity
   animation makes this element a stacking context, and the product render
   blends against its backdrop. Painted any higher up, the blend would have
   nothing to blend with. */
.app-container {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    background-image: radial-gradient(circle at 50% 0%, #141414 0%, var(--bg-app) 78%);
    opacity: 0;
    animation: fade-in 0.6s var(--ease-ios) forwards;
}

/* The work takes the centre. The product is atmosphere behind it (see the
   backdrop in kunai-ui.css) and costs the layout nothing. */
.main-area {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
    position: relative;
}

.work-side {
    position: relative;
    z-index: var(--z-local);
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    /* The pill floats over the scroll rather than standing above it, so the
       column starts at the top of the section and the whole lead lives in the
       scroll's own padding. Both numbers are declared here, together, because
       three things depend on their relationship: where the pill sits, where the
       first content sits, and where the fade has to be opaque again. Letting
       them drift apart is how the narrow breakpoints ended up printing the
       first heading underneath the pill. */
    --pill-top: 20px;
    --content-top: 86px;      /* --pill-top + 42 of pill + 24 under it */
}

.work-scroll {
    flex-grow: 1;
    min-height: 0;
    overflow-y: auto;
    scrollbar-gutter: stable;
    /* The travel above the first content belongs to the scroll now, so the work
       has somewhere to go behind the glass. */
    padding: var(--content-top) 36px 56px;
    /* The work dissolves as it reaches the chrome rather than being cut off at
       it, and gone by the pill's top edge so nothing is left to smear.
       A blur was tried over this band first and it was the wrong instrument:
       blurring text that is still half visible spreads its highlights rather
       than removing them, so the words nearest the bar turned to grey mush and
       clamped into a bright halo against the top edge. A fade alone reads as a
       dissolve, and the pill's own backdrop-filter still does the glass where
       there is actually something behind it. Opaque two short of wherever the
       first content sits, derived rather than repeated, so it cannot drift out
       of step with the padding at a breakpoint. */
    -webkit-mask-image: linear-gradient(180deg, transparent 0, transparent 12px, #000 calc(var(--content-top) - 2px));
    mask-image: linear-gradient(180deg, transparent 0, transparent 12px, #000 calc(var(--content-top) - 2px));
}

/* =============================================================================
   6. CORE KEYFRAMES
   (component-specific keyframes live in kunai-ui.css)
   ============================================================================= */
@keyframes fade-in { to { opacity: 1; } }

@keyframes fade-in-tab {
    from { opacity: 0.8; transform: translateY(3px); }
    to { opacity: 1; transform: translateY(0); }
}

@keyframes fade-in-scale {
    from { opacity: 0; transform: scale(0.96); }
    to { opacity: 1; transform: scale(1); }
}

/* =============================================================================
   7. RESPONSIVE
   ============================================================================= */
/* The pill's lead tightens with everything else. These used to set a plain
   padding-top on the column, which stopped being the whole story once the pill
   began floating: content started 30px above the pill's own bottom edge, so the
   first heading of every tab rendered underneath it. */
@media (max-width: 1100px) {
    .work-side { --pill-top: 12px; --content-top: 74px; }   /* 12 + 42 + 20 */
    .work-scroll { padding: var(--content-top) 24px 48px; }
}

@media (max-width: 640px) {
    .work-side { --content-top: 70px; }                     /* 12 + 42 + 16 */
    .work-scroll { padding: var(--content-top) 16px 40px; }
}

/* =============================================================================
   8. REDUCED MOTION (dual-gate: OS query + body class)
   ============================================================================= */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: var(--duration-reduce-motion) !important;
        animation-delay: 0s !important;
        transition-duration: var(--duration-reduce-motion) !important;
    }
    .orbit-sweep { animation: none !important; }
}

body.app-reduce-motion *,
body.app-reduce-motion *::before,
body.app-reduce-motion *::after {
    animation-duration: var(--duration-reduce-motion) !important;
    animation-delay: 0s !important;
    transition-duration: var(--duration-reduce-motion) !important;
}
body.app-reduce-motion .orbit-sweep { animation: none !important; }

/* Global pause when tab not visible (set by JS). */
:root.tab-hidden *,
:root.tab-hidden *::before,
:root.tab-hidden *::after {
    animation-play-state: paused !important;
}
