/*
 * Kagaku design system — the single source of the visual language (ADR 0023).
 * Sections: font · reset · tokens (:root) · dark theme · base elements · utilities.
 * Components consume var(--…) only; they never hardcode colors or magic numbers.
 */

/* ------------------------------------------------------------------ font --- */

@font-face {
    font-family: "Inter";
    font-style: normal;
    font-weight: 100 900; /* variable */
    font-display: swap;
    src: url("../fonts/InterVariable.woff2") format("woff2");
}

/* ----------------------------------------------------------------- reset --- */

*,
*::before,
*::after {
    box-sizing: border-box;
}

* {
    margin: 0;
}

html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;

    /* The viewport never scrolls (ADR 0025): the app shell is exactly one viewport tall and the
       content region inside it is the sole scroll container. scroll-padding-top for anchor jumps
       and the quicklink scroll-spy lives on that region (.app-shell__main), not here. Assumes
       every route renders inside MainLayout (Routes.razor's DefaultLayout enforces this today) —
       a bare @layout-less page would find itself unable to scroll at all. */
    overflow: hidden;
}

body {
    min-height: 100dvh;
    line-height: var(--leading-normal);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

img,
svg,
video,
canvas {
    display: block;
    max-width: 100%;
}

button,
input,
textarea,
select {
    font: inherit;
    color: inherit;
}

:where(a) {
    color: var(--accent);
    text-decoration: none;
}

:where(a:hover) {
    text-decoration: underline;
}

/* ---------------------------------------------------------------- tokens --- */

:root {
    /* Typography */
    --font-sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --font-mono: ui-monospace, "Cascadia Code", "SF Mono", Menlo, Consolas, monospace;

    --text-xs: 0.6875rem;  /* 11px */
    --text-sm: 0.8125rem;  /* 13px */
    --text-base: 0.875rem; /* 14px — dense, information-first */
    --text-lg: 1rem;       /* 16px */
    --text-xl: 1.25rem;    /* 20px */
    --text-2xl: 1.5rem;    /* 24px */

    --font-weight-normal: 400;
    --font-weight-medium: 500;
    --font-weight-semibold: 600;
    --font-weight-bold: 700;

    --leading-tight: 1.25;
    --leading-normal: 1.5;

    /* Spacing — 4px base */
    --space-1: 0.25rem;  /* 4 */
    --space-2: 0.5rem;   /* 8 */
    --space-3: 0.75rem;  /* 12 */
    --space-4: 1rem;     /* 16 */
    --space-5: 1.5rem;   /* 24 */
    --space-6: 2rem;     /* 32 */
    --space-7: 3rem;     /* 48 */
    --space-8: 4rem;     /* 64 */

    /* Radii */
    --radius-sm: 4px;
    --radius-md: 7px;
    --radius-lg: 11px;
    --radius-full: 999px;

    /* Control sizing — the shared height for inputs and buttons so they line up in a row */
    --control-height: 2.25rem;
    --control-height-sm: 1.75rem;

    /* Chrome — the app header's height; page shells subtract it to fill exactly one viewport */
    --app-header-height: 3.25rem;

    /* Layout — the shared maximum width for every page shell (projects list, workspace, settings),
       so navigation between pages never causes a width jump (ADR 0023). */
    --shell-max-width: 90rem;

    /* Z-index layers */
    --z-base: 0;
    --z-dropdown: 1000;
    --z-sticky: 1100;
    --z-drawer: 1200;
    --z-modal: 1300;
    --z-toast: 1400;

    /* Motion */
    --dur-fast: 100ms;
    --dur-base: 180ms;
    --dur-slow: 300ms;
    --ease: cubic-bezier(0.2, 0, 0, 1);

    /* Color — light theme (semantic roles, not raw hues) */
    --bg: #f6f6f8;
    --surface: #ffffff;
    --surface-raised: #ffffff;
    --surface-sunken: #f0f0f3;
    --surface-hover: #f4f4f6;

    --text: #1b1b20;
    --text-muted: #6a6a75;
    --text-subtle: #9b9ba4;

    --border: #e5e5ea;
    --border-strong: #d3d3da;

    --accent: #5850ec;
    --accent-hover: #453ddb;
    --accent-contrast: #ffffff;
    --accent-subtle: #edecfd;

    --success: #15803d;
    --success-subtle: #e6f4ea;
    --warning: #b45309;
    --warning-subtle: #fbefe0;
    --danger: #c62828;
    --danger-subtle: #fbe9e9;
    --danger-hover: #a91f1f;
    --info: #1d4ed8;
    --info-subtle: #e7edfc;

    /* Categorical palette — a qualitative scale for domain categories (e.g. lore). Unlike the
       semantic tones above, a swatch carries no meaning: it is picked by identity, to tell one
       category from another. Each pairs a foreground with a subtle background tint, like the tones. */
    --swatch-1: #7c3aed; --swatch-1-subtle: #f0ebfe;
    --swatch-2: #2563eb; --swatch-2-subtle: #e7effe;
    --swatch-3: #db2777; --swatch-3-subtle: #fce8f1;
    --swatch-4: #b45309; --swatch-4-subtle: #fbefdd;
    --swatch-5: #0d9488; --swatch-5-subtle: #e0f5f2;
    --swatch-6: #e11d48; --swatch-6-subtle: #fde8ec;
    --swatch-7: #16a34a; --swatch-7-subtle: #e6f6ec;
    --swatch-8: #64748b; --swatch-8-subtle: #eef1f5;

    --on-state: #ffffff;

    /* Elevation */
    --shadow-1: 0 1px 2px rgba(20, 20, 30, 0.06), 0 1px 1px rgba(20, 20, 30, 0.04);
    --shadow-2: 0 2px 8px rgba(20, 20, 30, 0.08);
    --shadow-3: 0 12px 32px rgba(20, 20, 30, 0.14);

    --focus-ring: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent);
}

/* ------------------------------------------------------------ dark theme --- */

/* System preference (no explicit choice). */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme]) {
        color-scheme: dark;
        --bg: #101013;
        --surface: #1a1a1f;
        --surface-raised: #232329;
        --surface-sunken: #141417;
        --surface-hover: #26262d;

        --text: #ececf0;
        --text-muted: #9c9ca6;
        --text-subtle: #6c6c76;

        --border: #2c2c34;
        --border-strong: #3b3b45;

        --accent: #837bf5;
        --accent-hover: #948df7;
        --accent-contrast: #14121f;
        --accent-subtle: #24223a;

        --success: #4ade80;
        --success-subtle: #16261c;
        --warning: #fbbf5a;
        --warning-subtle: #2a2013;
        --danger: #f87171;
        --danger-subtle: #2a1717;
        --danger-hover: #fa8f8f;
        --info: #7aa2f7;
        --info-subtle: #161e2e;

        --swatch-1: #a78bfa; --swatch-1-subtle: #241f38;
        --swatch-2: #60a5fa; --swatch-2-subtle: #16213a;
        --swatch-3: #f472b6; --swatch-3-subtle: #2e1723;
        --swatch-4: #fbbf5a; --swatch-4-subtle: #2a2013;
        --swatch-5: #2dd4bf; --swatch-5-subtle: #0f2a27;
        --swatch-6: #fb7185; --swatch-6-subtle: #2c1720;
        --swatch-7: #4ade80; --swatch-7-subtle: #16261c;
        --swatch-8: #94a3b8; --swatch-8-subtle: #1e242c;

        --on-state: #14121f;

        --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
        --shadow-2: 0 2px 10px rgba(0, 0, 0, 0.45);
        --shadow-3: 0 14px 36px rgba(0, 0, 0, 0.55);
    }
}

/* Explicit choice wins over the media query (settings, ADR 0016). */
:root[data-theme="dark"] {
    color-scheme: dark;
    --bg: #101013;
    --surface: #1a1a1f;
    --surface-raised: #232329;
    --surface-sunken: #141417;
    --surface-hover: #26262d;

    --text: #ececf0;
    --text-muted: #9c9ca6;
    --text-subtle: #6c6c76;

    --border: #2c2c34;
    --border-strong: #3b3b45;

    --accent: #837bf5;
    --accent-hover: #948df7;
    --accent-contrast: #14121f;
    --accent-subtle: #24223a;

    --success: #4ade80;
    --success-subtle: #16261c;
    --warning: #fbbf5a;
    --warning-subtle: #2a2013;
    --danger: #f87171;
    --danger-subtle: #2a1717;
    --danger-hover: #fa8f8f;
    --info: #7aa2f7;
    --info-subtle: #161e2e;

    --swatch-1: #a78bfa; --swatch-1-subtle: #241f38;
    --swatch-2: #60a5fa; --swatch-2-subtle: #16213a;
    --swatch-3: #f472b6; --swatch-3-subtle: #2e1723;
    --swatch-4: #fbbf5a; --swatch-4-subtle: #2a2013;
    --swatch-5: #2dd4bf; --swatch-5-subtle: #0f2a27;
    --swatch-6: #fb7185; --swatch-6-subtle: #2c1720;
    --swatch-7: #4ade80; --swatch-7-subtle: #16261c;
    --swatch-8: #94a3b8; --swatch-8-subtle: #1e242c;

    --on-state: #14121f;

    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-2: 0 2px 10px rgba(0, 0, 0, 0.45);
    --shadow-3: 0 14px 36px rgba(0, 0, 0, 0.55);
}

:root[data-theme="light"] {
    color-scheme: light;
}

/* --------------------------------------------------------- base elements --- */

body {
    font-family: var(--font-sans);
    font-size: var(--text-base);
    font-weight: var(--font-weight-normal);
    color: var(--text);
    background-color: var(--bg);
}

h1,
h2,
h3,
h4 {
    line-height: var(--leading-tight);
    font-weight: var(--font-weight-semibold);
    color: var(--text);
}

h1 { font-size: var(--text-2xl); }
h2 { font-size: var(--text-xl); }
h3 { font-size: var(--text-lg); }
h4 { font-size: var(--text-base); }

small {
    font-size: var(--text-sm);
    color: var(--text-muted);
}

code,
kbd,
samp {
    font-family: var(--font-mono);
    font-size: 0.9em;
}

hr {
    border: none;
    border-top: 1px solid var(--border);
}

:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
    border-radius: var(--radius-sm);
}

::selection {
    background: color-mix(in srgb, var(--accent) 25%, transparent);
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/* -------------------------------------------------------------- utilities --- */

.kg-stack {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.kg-row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

.kg-cluster {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

.kg-spacer {
    flex: 1 1 auto;
}

/* An image preview that opens the Lightbox: an unstyled button around the thumbnail, announced by
   the zoom cursor. Shared by every generated-image preview (sprites, backgrounds, asset cards). */
.kg-view {
    display: block;
    width: 100%;
    padding: 0;
    border: none;
    background: none;
    cursor: zoom-in;
    border-radius: var(--radius-sm);
}

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

/* Centered content filling what the app header leaves — host message pages (error, not-found).
   Sized by the layout's flex column rather than 100dvh, so it never overflows past the header. */
.kg-fill {
    flex: 1 1 auto;
    min-height: 0;
    display: grid;
    place-items: center;
    padding: var(--space-5);
}

/* Locks background scroll while a modal overlay is open (overlay.js sets the class on <body>).
   The lock lands on the content region — the app's only scroll container (ADR 0025); its reserved
   scrollbar gutter keeps the lock itself from shifting anything. The body element in the selector
   is load-bearing: it out-specifies the region's own scoped overflow-y: auto, which ties otherwise
   and wins on order. */
body.kg-scroll-lock .app-shell__main {
    overflow-y: hidden;
}

/* The AI assistant dock (ai-assistant story) is part of the shell, not an overlay: while it is open
   (assistant.js sets the class on <body>) the shell reserves the panel's width so the whole page —
   header, side menu, content, status bar — reflows left of it and stays usable. The width scales
   with the viewport but is bounded; when the room runs out the content region scrolls horizontally
   rather than crushing, held above a usable minimum. The body element out-specifies the scoped
   .app-shell / .ws rules, as with the scroll lock above. */
body.kg-asst-open {
    --kg-asst-width: clamp(20rem, 26vw, 32rem);
}

.app-shell {
    transition: padding-right var(--dur-base) var(--ease);
}

body.kg-asst-open .app-shell {
    padding-right: var(--kg-asst-width);
}

body.kg-asst-open .app-shell__main {
    overflow-x: auto;
}

body.kg-asst-open .ws {
    min-width: 40rem;
}

@media (prefers-reduced-motion: reduce) {
    .app-shell {
        transition: none;
    }
}

/* Shared input chrome — one look for every text-like control (TextField, TextArea, …). */
.kg-input {
    padding-inline: var(--space-3);
    background: var(--surface);
    color: var(--text);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-md);
    font-size: var(--text-base);
    transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}

.kg-input::placeholder {
    color: var(--text-subtle);
}

.kg-input:hover:not(:disabled) {
    border-color: var(--text-subtle);
}

.kg-input:focus-visible {
    border-color: var(--accent);
    box-shadow: var(--focus-ring);
    outline: none;
}

.kg-input:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

.kg-input--invalid {
    border-color: var(--danger);
}
