/*
 * Prototype: quasi-fractal CSS core for agents.
 * Principle: one vocabulary at every scale. Sizes are relative to the nearest
 * container (cqi), bounded by clamp() and broken by thresholds where form changes.
 * Custom properties are unregistered on purpose: cqi inside them resolves at the
 * point of use, so every place measures itself.
 */
@layer reset, tokens, base, layout, surface, tone;

/* ───────────────────────── reset ───────────────────────── */
@layer reset {
  *, *::before, *::after { box-sizing: border-box; }
  * { margin: 0; }
  html { -webkit-text-size-adjust: none; text-size-adjust: none; }
  img, svg, video, canvas, picture { display: block; max-inline-size: 100%; block-size: auto; }
  input, button, textarea, select { font: inherit; color: inherit; }
  :where(p, h1, h2, h3, h4, h5, h6, li, dd, dt, label, span, a) { overflow-wrap: anywhere; }
  :where(td, th) { overflow-wrap: break-word; }
}

/* ───────────────────────── tokens ───────────────────────── */
@layer tokens {
  :root {
    color-scheme: light dark;
    --hue: 250;

    /* colour: a few seeds, everything else derived */
    --paper:     light-dark(oklch(0.985 0.004 var(--hue)), oklch(0.19 0.012 var(--hue)));
    --ink:       light-dark(oklch(0.23 0.02 var(--hue)),   oklch(0.94 0.008 var(--hue)));
    --accent:    light-dark(oklch(0.50 0.16 var(--hue)),   oklch(0.78 0.12 var(--hue)));
    --on-accent: light-dark(oklch(0.99 0 0),               oklch(0.18 0.02 var(--hue)));
    --danger:    light-dark(oklch(0.50 0.19 27),           oklch(0.76 0.14 27));
    --ok:        light-dark(oklch(0.47 0.12 150),          oklch(0.80 0.14 150));
    --warn:      light-dark(oklch(0.50 0.11 70),           oklch(0.83 0.13 80));
    --quiet:     color-mix(in oklch, var(--ink) 66%, var(--paper));
    --line:      color-mix(in oklch, var(--ink) 16%, transparent);
    /* translucent veil: nested surfaces compound by themselves */
    --veil:      color-mix(in oklch, var(--ink) 4.5%, transparent);

    /* space: relative to the nearest container, bounded, scaled by density */
    --density: 1;
    --s-2: calc(clamp(.125rem, .5cqi, .375rem) * var(--density));
    --s-1: calc(clamp(.25rem, 1.1cqi, .625rem) * var(--density));
    --s0:  calc(clamp(.5rem, 2.2cqi, 1rem) * var(--density));
    --s1:  calc(clamp(.75rem, 3.6cqi, 1.75rem) * var(--density));
    --s2:  calc(clamp(1rem, 6cqi, 3rem) * var(--density));
    --s3:  calc(clamp(1.5rem, 9cqi, 5rem) * var(--density));

    /* type: the same heading is smaller in a smaller place */
    --t-1: clamp(.8125rem, .78rem + .2cqi, .875rem);
    --t0:  clamp(.9375rem, .9rem + .25cqi, 1.0625rem);
    --t1:  clamp(1.0625rem, .95rem + .8cqi, 1.375rem);
    --t2:  clamp(1.1875rem, 1rem + 1.8cqi, 2rem);
    --t3:  clamp(1.375rem, .95rem + 3.4cqi, 3.25rem);

    --radius: clamp(.25rem, 1.2cqi, .875rem);
    --measure: 68ch;
    --wide: 76rem;
    --target: 2.5rem;

    --font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans", sans-serif;
    --font-mono: ui-monospace, "SF Mono", "Cascadia Code", "Roboto Mono", monospace;
  }

  :where([data-theme=light]) { color-scheme: light; }
  :where([data-theme=dark])  { color-scheme: dark; }
  :where([data-density=compact]) { --density: .7; --target: 2.25rem; }
  :where([data-density=comfy])   { --density: 1.3; }

  @media (prefers-contrast: more) {
    :root {
      --quiet: var(--ink);
      --line: color-mix(in oklch, var(--ink) 45%, transparent);
      --veil: color-mix(in oklch, var(--ink) 8%, transparent);
    }
  }
}

/* ───────────────────────── base: plain semantic HTML ───────────────────────── */
@layer base {
  :where(body) {
    min-block-size: 100dvh;
    font-family: var(--font);
    font-size: var(--t0);
    line-height: 1.5;
    color: var(--ink);
    background: var(--paper);
    -webkit-font-smoothing: antialiased;
  }
  :where([data-theme]) { color: var(--ink); background-color: var(--paper); }

  :where(h1) { font-size: var(--t3); }
  :where(h2) { font-size: var(--t2); }
  :where(h3) { font-size: var(--t1); }
  :where(h4, h5, h6) { font-size: var(--t0); }
  :where(h1, h2, h3, h4, h5, h6) { line-height: 1.15; font-weight: 650; text-wrap: balance; letter-spacing: -.01em; }
  :where(p, li, dd) { max-inline-size: var(--measure); text-wrap: pretty; }
  :where(small, figcaption, caption) { font-size: var(--t-1); }
  :where(strong, b) { font-weight: 650; }
  :where(code, kbd, samp, pre) { font-family: var(--font-mono); font-size: .92em; }
  :where(:not(pre) > code) { padding: .1em .35em; border-radius: .3em; background: var(--veil); }
  :where(pre) { padding: var(--s0); border-radius: var(--radius); background: var(--veil); overflow-x: auto; }
  :where(hr) { border: 0; border-block-start: 1px solid var(--line); }
  :where(ul, ol) { padding-inline-start: 1.25em; }
  /* a list that has a relation is a structure, not prose: no bullets */
  :where(ul[role=list], ol[role=list], menu, ul[data-l], ol[data-l]) { list-style: none; padding: 0; }

  :where(a) { color: var(--accent); text-underline-offset: .2em; text-decoration-thickness: from-font; }
  :where(:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }

  /* controls */
  :where(button, input[type=button], input[type=submit], input[type=reset]) {
    display: inline-flex; align-items: center; justify-content: center; gap: var(--s-1);
    min-block-size: var(--target); min-inline-size: var(--target);
    padding: var(--s-2) var(--s0);
    border: 1px solid var(--line); border-radius: var(--radius);
    background: var(--veil); font-weight: 550; line-height: 1.2; cursor: pointer;
  }
  :where(button:hover) { background: color-mix(in oklch, var(--ink) 9%, transparent); }
  :where(button:disabled) { opacity: .55; cursor: not-allowed; }

  :where(input:not([type=checkbox], [type=radio], [type=range], [type=button], [type=submit], [type=reset]), select, textarea) {
    inline-size: 100%; min-inline-size: 0;
    min-block-size: var(--target);
    padding: var(--s-2) var(--s0);
    border: 1px solid color-mix(in oklch, var(--ink) 28%, transparent); border-radius: var(--radius);
    background: var(--paper);
  }
  :where(textarea) { min-block-size: 6lh; resize: vertical; }
  :where(input[type=checkbox], input[type=radio]) { inline-size: 1.25rem; block-size: 1.25rem; accent-color: var(--accent); }
  :where(label) { display: flex; flex-direction: column; gap: var(--s-2); }
  :where(label:has(> input[type=checkbox], > input[type=radio])) { flex-direction: row; align-items: center; min-block-size: var(--target); }
  :where(label > span:first-child, legend) { font-weight: 550; }
  :where(fieldset) { border: 1px solid var(--line); border-radius: var(--radius); padding: var(--s1); min-inline-size: 0; }
  :where(legend) { padding-inline: var(--s-1); }
  :where([aria-invalid=true]) { border-color: var(--danger); }

  :where(details) { border-block-end: 1px solid var(--line); }
  :where(summary) { min-block-size: var(--target); display: flex; align-items: center; gap: var(--s-1); cursor: pointer; font-weight: 550; }

  /* data */
  :where(table) { inline-size: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
  :where(th, td) { padding: var(--s-1) var(--s0); text-align: start; vertical-align: top; border-block-end: 1px solid var(--line); }
  :where(thead th) { font-size: var(--t-1); font-weight: 600; color: var(--quiet); white-space: nowrap; }
  :where(caption) { text-align: start; padding-block-end: var(--s-1); color: var(--quiet); }
  :where(dl) { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 9rem), 1fr)); gap: var(--s0) var(--s1); }
  :where(dt) { font-size: var(--t-1); color: var(--quiet); }
  :where(dd) { margin: 0; font-weight: 550; }
  :where(dl > div) { display: flex; flex-direction: column; gap: var(--s-2); }

  /* a value shown as a figure: <data value="38">38</data>; inside prose it stays text */
  :where(data) { font-size: var(--t2); font-weight: 650; line-height: 1.1; font-variant-numeric: tabular-nums; }
  :where(p, li, td, dd, span, a) :where(data) { font: inherit; }

  /* status: <mark data-tone="ok">Активно</mark> */
  :where(mark) {
    display: inline-flex; align-items: center; gap: .35em;
    padding: .1em .6em; border-radius: 999px;
    font-size: var(--t-1); font-weight: 600; line-height: 1.35; max-inline-size: 100%;
    color: var(--ink);
    background: color-mix(in oklch, currentColor 13%, transparent);
  }
}

/* ───────────────────────── layout: eight relations, any scale ───────────────────────── */
@layer layout {
  /* every relation is a place that measures itself, except the ones sized by content */
  :where([data-l]) { container-type: inline-size; --gap: initial; }
  :where([data-l=cluster], [data-l=reel]),
  :where([data-l=cluster], [data-l=reel]) > :where(*) { container-type: normal; }

  :where([data-space=none])  { --gap: 0px; }
  :where([data-space=tight]) { --gap: var(--s-1); }
  :where([data-space=loose]) { --gap: var(--s2); }

  /* stack — things one under another */
  :where([data-l=stack]) { display: flex; flex-direction: column; gap: var(--gap, var(--s1)); }
  :where([data-l=stack]) > :where([data-push]) { margin-block-start: auto; }

  /* cluster — small things in a wrapping row */
  :where([data-l=cluster]) { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--gap, var(--s0)); }
  :where([data-l=cluster]) > :where([data-push]) { margin-inline-start: auto; }

  /* split — main beside side; folds into a stack when main would get too narrow */
  :where([data-l=split]) { display: flex; flex-direction: row; flex-wrap: wrap; gap: var(--gap, var(--s1)); }
  /* main needs both a share and an absolute minimum: below it the split folds */
  :where([data-l=split]) > :where(*) { flex: 999 1 0; min-inline-size: min(100%, max(55%, 17rem)); }
  :where([data-l=split]) > :where([data-side]),
  :where([data-l=split]:not(:has(> [data-side]))) > :where(:first-child) {
    flex: 1 1 clamp(8rem, 28cqi, 20rem); min-inline-size: 0;
  }

  /* switch — equal parts in a row, all at once into a column below the threshold */
  :where([data-l=switch]) { display: flex; flex-direction: row; flex-wrap: wrap; gap: var(--gap, var(--s1)); }
  :where([data-l=switch]) > :where(*) { flex-grow: 1; flex-basis: calc((30rem - 100%) * 999); }

  /* grid — many equal things, as many columns as fit */
  :where([data-l=grid]) {
    display: grid; gap: var(--gap, var(--s1));
    grid-template-columns: repeat(auto-fit, minmax(min(100%, clamp(9rem, 22cqi, 17rem)), 1fr));
  }

  /* reel — a strip that scrolls inside itself, never the page */
  :where([data-l=reel]) {
    display: flex; flex-direction: row; gap: var(--gap, var(--s0));
    overflow-x: auto; overscroll-behavior-inline: contain; scroll-snap-type: x proximity;
    padding-block-end: var(--s-1);
  }
  :where([data-l=reel]) > :where(*) { flex: 0 0 auto; scroll-snap-align: start; }
  :where([data-l=reel]) > :where(:only-child) { flex-grow: 1; }
  :where([data-l=reel]) > :where(table) { inline-size: max-content; min-inline-size: 100%; }

  /* center — a column of comfortable width at any scale */
  :where([data-l=center]) {
    inline-size: 100%; max-inline-size: var(--wide); margin-inline: auto;
    padding-inline: var(--s1);
  }

  /* cover — a tall place with its principal content in the middle */
  :where([data-l=cover]) {
    display: flex; flex-direction: column; justify-content: center; gap: var(--gap, var(--s1));
    min-block-size: 70svh;
  }
  :where([data-l=cover]) > :where([data-push]) { margin-block-start: auto; }

  /* media inside relations keeps its proportions */
  :where([data-l]) > :where(img, svg, video, picture) { align-self: flex-start; }
  /* media never grows past its own share: after folding it keeps its size */
  :where([data-l=split]) > :where(img, svg, video, picture) { flex-grow: 0; }
  :where(label[data-l=split]) { align-items: center; }

  :where([data-pad]) { padding: var(--s1); }

  /* fewer details on a smaller branch: secondary content leaves narrow places */
  @container (inline-size < 16rem) { :where([data-optional]) { display: none; } }
}

/* ───────────────────────── surface: depth relative to the parent ───────────────────────── */
@layer surface {
  :where([data-surface]) { padding: var(--s1); border-radius: var(--radius); }
  :where([data-surface=raised])  { background: var(--veil); }
  :where([data-surface=outline]) { border: 1px solid var(--line); }
  :where([data-surface=accent])  { background: color-mix(in oklch, var(--accent) 10%, transparent); }
  :where([data-surface]) > :where(table:only-child) { margin-block: calc(var(--s-1) * -1); }
}

/* ───────────────────────── tone: emphasis by intent ───────────────────────── */
@layer tone {
  :where([data-tone=quiet])  { color: var(--quiet); }
  :where([data-tone=strong]) { font-weight: 650; }
  :where([data-tone=accent]) { color: var(--accent); }
  :where([data-tone=danger]) { color: var(--danger); }
  :where([data-tone=ok])     { color: var(--ok); }
  :where([data-tone=warn])   { color: var(--warn); }

  :where(mark[data-tone]) { color: var(--ink); }
  :where(mark[data-tone=accent]) { background: color-mix(in oklch, var(--accent) 16%, transparent); }
  :where(mark[data-tone=danger]) { background: color-mix(in oklch, var(--danger) 16%, transparent); }
  :where(mark[data-tone=ok])     { background: color-mix(in oklch, var(--ok) 18%, transparent); }
  :where(mark[data-tone=warn])   { background: color-mix(in oklch, var(--warn) 20%, transparent); }
  :where(mark[data-tone=quiet])  { background: var(--veil); color: var(--quiet); }

  :where(button[data-tone=accent]) { background: var(--accent); color: var(--on-accent); border-color: transparent; }
  :where(button[data-tone=danger]) { background: var(--danger); color: var(--on-accent); border-color: transparent; }
  :where(button[data-tone=accent], button[data-tone=danger]):hover { filter: brightness(1.08); }
  :where(button[data-tone=quiet]) { background: transparent; border-color: transparent; color: var(--ink); }
}

@media (prefers-reduced-motion: no-preference) {
  @layer base {
    :where(button, a, summary) { transition: background-color .15s, filter .15s; }
  }
}
