/* Coddi on the web: one file of tokens and components (D-118, SPEC-UI §1, §28, §29).
   Values come from coddi-desktop src/index.css (@theme and .dark) and the
   prototype coddi-proto.html (.btn, .btn.def, .btn.dz, .sin, .dlgbox); names
   follow the prototype. Used verbatim by the service pages in frontend-static/
   (inlined by scripts/build_frontend_static.py) and by every server-rendered
   page (src/core/html_page_theme.py). Change a value here, not in a page.
   Inter Variable is served from this site (/fonts/ = frontend-static/fonts/,
   SIL OFL 1.1, fonts/LICENSE); no outside request, the system stack stands in
   until it arrives. */
@font-face { font-family: "Inter Variable"; font-style: normal; font-display: swap; font-weight: 100 900; src: url("/fonts/inter-cyrillic-wght-normal.woff2") format("woff2-variations"), url("/fonts/inter-cyrillic-wght-normal.woff2") format("woff2"); unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; }
@font-face { font-family: "Inter Variable"; font-style: normal; font-display: swap; font-weight: 100 900; src: url("/fonts/inter-latin-wght-normal.woff2") format("woff2-variations"), url("/fonts/inter-latin-wght-normal.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Inter Variable"; font-style: italic; font-display: swap; font-weight: 100 900; src: url("/fonts/inter-cyrillic-wght-italic.woff2") format("woff2-variations"), url("/fonts/inter-cyrillic-wght-italic.woff2") format("woff2"); unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; }
@font-face { font-family: "Inter Variable"; font-style: italic; font-display: swap; font-weight: 100 900; src: url("/fonts/inter-latin-wght-italic.woff2") format("woff2-variations"), url("/fonts/inter-latin-wght-italic.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }

:root {
  color-scheme: light dark;
  --bg: color-mix(in oklab, #f9f6f1 40%, #ffffff);      /* --color-surface-warm */
  --panel: color-mix(in oklab, #f9f6f1 70%, #ffffff);   /* --color-surface-warm-panel */
  --raise: color-mix(in oklab, #ddd4c7 30%, #ffffff);   /* --color-surface-warm-raised */
  --line: color-mix(in oklab, #ddd4c7 55%, #ffffff);    /* --color-line-warm */
  --card: #ffffff;                                      /* --color-card */
  --tx: oklch(0.141 0.005 285.823);                     /* --color-foreground */
  --on-tx: #ffffff;                                     /* text on .btn.def */
  --mu: oklch(0.552 0.016 285.938);                     /* --color-muted-foreground */
  --dim: oklch(from var(--tx) l c h / 0.62);            /* SPEC-UI §30: 62 % */
  --brand: #00b87c;                                     /* marks and lines, never text on light */
  --green: #00875a;                                     /* --color-brand-action */
  --green-hover: #00774f;                               /* --color-brand-action-hover */
  --link: var(--green);
  --bad: oklch(0.577 0.245 27.325);                     /* --color-destructive */
  --badbg: color-mix(in oklab, var(--bad) 6%, transparent);
  --badline: color-mix(in oklab, var(--bad) 25%, transparent);
  --badtx: color-mix(in oklab, var(--bad) 80%, var(--tx));
  --border-active: #a3a3a3;
  --ring: oklch(0.705 0.015 286.067);
  --shadow-pop: 0 8px 24px oklch(0 0 0 / 0.12);
  --shadow-modal: 0 24px 48px -12px oklch(0 0 0 / 0.25);
  --overlay: oklch(0 0 0 / 0.24);
  --ui: "Inter Variable", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: oklch(0.24 0.006 286);
    /* .dark --color-surface-warm-panel is white 4 % over the background; the
       page flattens it so a sticky bar does not show the text under it. */
    --panel: color-mix(in oklab, oklch(0.985 0 0) 4%, oklch(0.24 0.006 286));
    --raise: oklch(0.33 0.008 286);
    --line: oklch(1 0 0 / 10%);
    --card: oklch(0.21 0.006 285.885);
    --tx: oklch(0.985 0 0);
    --on-tx: oklch(0.21 0.006 285.885);
    --mu: oklch(0.705 0.015 286.067);
    /* #00875a is about 3:1 on the dark background; the brand green reads there. */
    --link: var(--brand);
    --bad: oklch(0.704 0.191 22.216);
    --badbg: color-mix(in oklab, var(--bad) 8%, transparent);
    --badline: color-mix(in oklab, var(--bad) 30%, transparent);
    --badtx: color-mix(in oklab, var(--bad) 85%, var(--tx));
    --border-active: oklch(0.5 0 0);
    --ring: oklch(0.552 0.016 285.938);
    --shadow-pop: 0 8px 24px oklch(0 0 0 / 0.3);
    --shadow-modal: 0 24px 48px -12px oklch(0 0 0 / 0.4);
    --overlay: oklch(0 0 0 / 0.5);
  }
}

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body { background: var(--bg); color: var(--tx); font: 400 13px/1.6 var(--ui); -webkit-font-smoothing: antialiased; }
a { color: var(--link); text-underline-offset: 2px; }
code, kbd, time.mono, .mono { font-family: var(--mono); }
h1, h2, h3, h4 { color: var(--tx); }
.title { font-size: 18px; line-height: 1.3; font-weight: 600; letter-spacing: -0.01em; margin: 0 0 8px; }   /* page heading, §29 */
.heading { font-size: 15px; line-height: 1.4; font-weight: 600; margin: 0 0 7px; }                      /* dialog heading, §29 */
.muted { color: var(--mu); }

/* Card — the dialog box of §28 (.dlgbox): 420 / 12 / 18 on the warm background. */
.card { width: 100%; max-width: 420px; background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 18px; }
.card h1, .card h2 { font-size: 15px; line-height: 1.4; font-weight: 600; margin: 0 0 7px; }
.card p { margin: 0 0 14px; font-size: 13px; line-height: 1.6; color: var(--mu); }
.card label { display: block; font-size: 11px; color: var(--mu); margin: 0 0 5px; }

/* Buttons — §28: 30 px, 6 × 11, radius 7, 12/400; .def charcoal, .dz destructive, .gh ghost 26 px, 4 × 9, 11.
   Line height 16 px makes the box exactly 30 (6 + 16 + 6 + 2 borders) and the ghost 26 (4 + 16 + 4 + 2). */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 30px; padding: 6px 11px; border: 1px solid var(--line); border-radius: 7px; background: var(--card); color: var(--tx); font: 400 12px/16px var(--ui); text-decoration: none; white-space: nowrap; cursor: pointer; appearance: none; transition: border-color 120ms ease-out, background-color 120ms ease-out, opacity 120ms ease-out; }
.btn:hover { border-color: var(--dim); }
.btn:active { background: var(--raise); }
.btn.def { background: var(--tx); border-color: var(--tx); color: var(--on-tx); font-weight: 500; }
.btn.def:hover { opacity: 0.9; border-color: var(--tx); }
.btn.def:active { opacity: 0.8; background: var(--tx); }
.btn.dz { background: var(--badbg); border-color: var(--badline); color: var(--badtx); font-weight: 500; }
.btn.dz:hover { border-color: var(--bad); }
.btn.gh { min-height: 26px; padding: 4px 9px; font-size: 11px; background: transparent; border-color: transparent; color: var(--mu); }
.btn.gh:hover { background: var(--raise); border-color: transparent; color: var(--tx); }
.btn:disabled, .btn[disabled], .btn[aria-disabled="true"] { opacity: 0.5; cursor: default; pointer-events: none; }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.card .actions { justify-content: flex-end; }   /* DESIGN R-5: buttons on the right, the main one last */

/* Field — §28 .sin: 32 px, 7 × 9, radius 7, 13 px. */
.sin { display: block; width: 100%; min-height: 32px; padding: 7px 9px; border: 1px solid var(--line); border-radius: 7px; background: var(--card); color: var(--tx); font: 400 13px/1.3 var(--ui); }
.sin::placeholder { color: var(--mu); }

/* Focus — one rule everywhere (§28, §30): border-active + ring 15 %, 2 px. */
.sin:focus, .sin:focus-visible, .btn:focus-visible { outline: none; border-color: var(--border-active); box-shadow: 0 0 0 2px oklch(from var(--ring) l c h / 0.15); }
/* A link or a bare control has no border to darken, so it keeps a visible outline (§30 rule 1: focus is seen everywhere). */
a:not(.btn):focus-visible, button:not(.btn):focus-visible, input[type="checkbox"]:focus-visible, input[type="radio"]:focus-visible + label, [tabindex]:not([tabindex="-1"]):not(.btn):focus-visible { outline: 2px solid oklch(from var(--ring) l c h / 0.5); outline-offset: 1px; border-radius: 7px; }
input[type="checkbox"] { accent-color: var(--green); }

/* Busy — §28: 16 px, brand 25 % ring, brand top. */
.spinner { width: 16px; height: 16px; border-radius: 50%; border: 2px solid color-mix(in oklab, var(--brand) 25%, transparent); border-top-color: var(--brand); display: inline-block; vertical-align: -3px; margin-right: 8px; animation: coddi-spin 1000ms linear infinite; }
@keyframes coddi-spin { to { transform: rotate(360deg); } }

/* The Coddi mark + wordmark (src/core/coddi-lockup.svg, D-122/D-241): the mark keeps its green,
   the wordmark takes the text colour, so the dark theme needs no second file. A page sets the height. */
.lockup { display: block; width: auto; flex: none; color: var(--tx); }

.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
[hidden] { display: none !important; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0ms !important; animation-duration: 0ms !important; }
  .spinner { animation-duration: 1000ms !important; }   /* §29: the spinner stays */
}
