/*! Ksiego Design System · css/ksiego.css
 * Framework-free: tokens + base + layout + every component.
 * Built from css/src/*.css by tools/build-css.py — edit the sources, not this file.
 * Serve as-is. Works under: default-src 'self'; style-src 'self'; font-src 'self'.
 */

/* ---- css/src/00-tokens.css ---- */
/* Ksiego Design System — tokens compiled from tokens.json (local copy) */
:root, [data-theme="light"] {
  --ks-navy-900: #0b1f3b;
  --ks-navy-800: #132c50;
  --ks-navy-700: #1b3a67;
  --ks-blue-700: #1d4ed8;
  --ks-blue-600: #2563eb;
  --ks-blue-500: #3b82f6;
  --ks-blue-400: #60a5fa;
  --ks-blue-200: #bfd5fd;
  --ks-blue-100: #d8e6fe;
  --ks-blue-50: #eaf2ff;
  --ks-gray-900: #111827;
  --ks-gray-700: #374151;
  --ks-gray-500: #6b7280;
  --ks-gray-400: #9ca3af;
  --ks-gray-300: #cbd5e1;
  --ks-gray-200: #e2e8f0;
  --ks-gray-100: #eef2f7;
  --ks-gray-50: #f4f7fb;
  --ks-white: #ffffff;
  --ks-green-700: #15803d;
  --ks-green-600: #16a34a;
  --ks-green-50: #ecfdf3;
  --ks-amber-700: #b45309;
  --ks-amber-500: #f59e0b;
  --ks-amber-50: #fff8eb;
  --ks-red-700: #b91c1c;
  --ks-red-600: #dc2626;
  --ks-red-50: #fef2f2;
  --ks-violet-700: #6d28d9;
  --ks-violet-50: #f5f3ff;
  --ks-surface-app: #f4f7fb;
  --ks-surface-card: #ffffff;
  --ks-surface-sunken: #eef2f7;
  --ks-surface-section: #eaf2ff;
  --ks-surface-inverse: #0b1f3b;
  --ks-surface-hover: #f4f7fb;
  --ks-surface-selected: #eaf2ff;
  --ks-surface-disabled: #eef2f7;
  --ks-text-strong: #0b1f3b;
  --ks-text-default: #1f2a3c;
  --ks-text-muted: #5f6675;
  --ks-text-subtle: #9ca3af;
  --ks-text-inverse: #ffffff;
  --ks-text-link: #1d4ed8;
  --ks-text-accent: #2563eb;
  --ks-border: #e2e8f0;
  --ks-border-strong: #cbd5e1;
  --ks-border-accent: #2563eb;
  --ks-border-inverse: #1b3a67;
  --ks-focus-ring: #2563eb;
  --ks-focus-ring-offset: #ffffff;
  --ks-action-bg: #2563eb;
  --ks-action-bg-hover: #1d4ed8;
  --ks-action-bg-active: #1b3a67;
  --ks-action-fg: #ffffff;
  --ks-action-secondary-bg: #eaf2ff;
  --ks-action-secondary-bg-hover: #d8e6fe;
  --ks-action-secondary-fg: #1d4ed8;
  --ks-status-success-fg: #15803d;
  --ks-status-success-bg: #ecfdf3;
  --ks-status-warning-fg: #b45309;
  --ks-status-warning-bg: #fff8eb;
  --ks-status-danger-fg: #b91c1c;
  --ks-status-danger-bg: #fef2f2;
  --ks-status-info-fg: #1d4ed8;
  --ks-status-info-bg: #eaf2ff;
  --ks-status-neutral-fg: #374151;
  --ks-status-neutral-bg: #eef2f7;
  --ks-status-progress-fg: #6d28d9;
  --ks-status-progress-bg: #f5f3ff;
  --ks-registry-bg: #eaf2ff;
  --ks-registry-fg: #1d4ed8;
  --ks-registry-border: #bfd5fd;
  --ks-manual-bg: #fff8eb;
  --ks-manual-fg: #b45309;
  --ks-shadow-none: none;
  --ks-shadow-xs: 0 1px 2px rgba(11,31,59,.06);
  --ks-shadow-sm: 0 1px 3px rgba(11,31,59,.08),0 1px 2px rgba(11,31,59,.04);
  --ks-shadow-md: 0 4px 12px rgba(11,31,59,.08);
  --ks-shadow-lg: 0 12px 32px rgba(11,31,59,.12);
  --ks-shadow-modal: 0 24px 64px rgba(11,31,59,.24);
  --ks-shadow-focus: 0 0 0 3px rgba(37,99,235,.28);
  --ks-shadow-inset-top: inset 0 1px 0 rgba(255,255,255,.6);
}
[data-theme="dark"] {
  --ks-surface-app: #0a1526;
  --ks-surface-card: #0f1e33;
  --ks-surface-sunken: #0b1929;
  --ks-surface-section: #132c50;
  --ks-surface-inverse: #eaf2ff;
  --ks-surface-hover: #152b47;
  --ks-surface-selected: #1b3a67;
  --ks-surface-disabled: #13243b;
  --ks-text-strong: #f4f7fb;
  --ks-text-default: #dce6f2;
  --ks-text-muted: #9baac0;
  --ks-text-subtle: #77879e;
  --ks-text-inverse: #0b1f3b;
  --ks-text-link: #93c0fd;
  --ks-text-accent: #93c0fd;
  --ks-border: #1e3555;
  --ks-border-strong: #2b4770;
  --ks-border-inverse: #bfd5fd;
  --ks-focus-ring: #93c0fd;
  --ks-focus-ring-offset: #0f1e33;
  --ks-action-bg: #2563eb;
  --ks-action-bg-hover: #3b82f6;
  --ks-action-bg-active: #60a5fa;
  --ks-action-fg: #ffffff;
  --ks-action-secondary-bg: #16304f;
  --ks-action-secondary-bg-hover: #1b3a67;
  --ks-action-secondary-fg: #bfd5fd;
  --ks-status-success-fg: #6ee7a8;
  --ks-status-success-bg: #0c2a1c;
  --ks-status-warning-fg: #fcd34d;
  --ks-status-warning-bg: #2c2008;
  --ks-status-danger-fg: #fca5a5;
  --ks-status-danger-bg: #2c1112;
  --ks-status-info-fg: #93c0fd;
  --ks-status-info-bg: #14294a;
  --ks-status-neutral-fg: #c3cedd;
  --ks-status-neutral-bg: #16253c;
  --ks-status-progress-fg: #c4b5fd;
  --ks-status-progress-bg: #1e1b39;
  --ks-registry-bg: #14294a;
  --ks-registry-fg: #93c0fd;
  --ks-registry-border: #2b4770;
  --ks-manual-bg: #2c2008;
  --ks-manual-fg: #fcd34d;
  --ks-shadow-xs: 0 1px 2px rgba(0,0,0,.4);
  --ks-shadow-sm: 0 1px 3px rgba(0,0,0,.45);
  --ks-shadow-md: 0 4px 12px rgba(0,0,0,.5);
  --ks-shadow-lg: 0 12px 32px rgba(0,0,0,.55);
  --ks-shadow-modal: 0 24px 64px rgba(0,0,0,.7);
  --ks-shadow-focus: 0 0 0 3px rgba(147,192,253,.35);
}
@media (prefers-color-scheme: dark) { :where(:root:not([data-ks-theme-fixed])):not([data-theme]) {
  --ks-surface-app: #0a1526;
  --ks-surface-card: #0f1e33;
  --ks-surface-sunken: #0b1929;
  --ks-surface-section: #132c50;
  --ks-surface-inverse: #eaf2ff;
  --ks-surface-hover: #152b47;
  --ks-surface-selected: #1b3a67;
  --ks-surface-disabled: #13243b;
  --ks-text-strong: #f4f7fb;
  --ks-text-default: #dce6f2;
  --ks-text-muted: #9baac0;
  --ks-text-subtle: #77879e;
  --ks-text-inverse: #0b1f3b;
  --ks-text-link: #93c0fd;
  --ks-text-accent: #93c0fd;
  --ks-border: #1e3555;
  --ks-border-strong: #2b4770;
  --ks-border-inverse: #bfd5fd;
  --ks-focus-ring: #93c0fd;
  --ks-focus-ring-offset: #0f1e33;
  --ks-action-bg: #2563eb;
  --ks-action-bg-hover: #3b82f6;
  --ks-action-bg-active: #60a5fa;
  --ks-action-fg: #ffffff;
  --ks-action-secondary-bg: #16304f;
  --ks-action-secondary-bg-hover: #1b3a67;
  --ks-action-secondary-fg: #bfd5fd;
  --ks-status-success-fg: #6ee7a8;
  --ks-status-success-bg: #0c2a1c;
  --ks-status-warning-fg: #fcd34d;
  --ks-status-warning-bg: #2c2008;
  --ks-status-danger-fg: #fca5a5;
  --ks-status-danger-bg: #2c1112;
  --ks-status-info-fg: #93c0fd;
  --ks-status-info-bg: #14294a;
  --ks-status-neutral-fg: #c3cedd;
  --ks-status-neutral-bg: #16253c;
  --ks-status-progress-fg: #c4b5fd;
  --ks-status-progress-bg: #1e1b39;
  --ks-registry-bg: #14294a;
  --ks-registry-fg: #93c0fd;
  --ks-registry-border: #2b4770;
  --ks-manual-bg: #2c2008;
  --ks-manual-fg: #fcd34d;
  --ks-shadow-xs: 0 1px 2px rgba(0,0,0,.4);
  --ks-shadow-sm: 0 1px 3px rgba(0,0,0,.45);
  --ks-shadow-md: 0 4px 12px rgba(0,0,0,.5);
  --ks-shadow-lg: 0 12px 32px rgba(0,0,0,.55);
  --ks-shadow-modal: 0 24px 64px rgba(0,0,0,.7);
  --ks-shadow-focus: 0 0 0 3px rgba(147,192,253,.35);
} }
:root {
  --ks-lh-h1: 56px;
  --ks-lh-h2: 40px;
  --ks-lh-h3: 32px;
  --ks-lh-h4: 28px;
  --ks-lh-body: 24px;
  --ks-lh-small: 20px;
  --ks-lh-dense: 18px;
  --ks-lh-caption: 16px;
  --ks-space-0: 0px;
  --ks-space-1: 2px;
  --ks-space-2: 4px;
  --ks-space-3: 6px;
  --ks-space-4: 8px;
  --ks-space-5: 12px;
  --ks-space-6: 16px;
  --ks-space-7: 20px;
  --ks-space-8: 24px;
  --ks-space-9: 32px;
  --ks-space-10: 40px;
  --ks-space-11: 48px;
  --ks-space-12: 64px;
  --ks-topbar-h: 56px;
  --ks-sidenav-w: 248px;
  --ks-sidenav-w-collapsed: 64px;
  --ks-page-pad-x: 24px;
  --ks-page-max: 1440px;
  --ks-content-max: 1160px;
  --ks-row-h: 44px;
  --ks-row-h-comfy: 52px;
  --ks-control-h: 36px;
  --ks-control-h-sm: 28px;
  --ks-control-h-lg: 44px;
  --ks-touch-min: 44px;
  --ks-border-w: 1px;
  --ks-border-w-strong: 1.5px;
  --ks-focus-w: 2px;
  --ks-focus-offset: 2px;
  --ks-radius-xs: 4px;
  --ks-radius-sm: 6px;
  --ks-radius-md: 8px;
  --ks-radius-lg: 10px;
  --ks-radius-xl: 12px;
  --ks-radius-2xl: 16px;
  --ks-radius-pill: 999px;
  --ks-duration-instant: 80ms;
  --ks-duration-fast: 120ms;
  --ks-duration-base: 180ms;
  --ks-duration-slow: 260ms;
  --ks-ease-standard: cubic-bezier(.2,0,.2,1);
  --ks-ease-out: cubic-bezier(0,0,.2,1);
  --ks-text-body: 16px;
  --ks-text-h1: 48px;
  --ks-text-h2: 32px;
  --ks-text-h3: 24px;
  --ks-text-h4: 20px;
  --ks-text-small: 14px;
  --ks-text-dense: 13px;
  --ks-text-caption: 12px;
  --ks-gradient-brand: linear-gradient(135deg,#60A5FA 0%,#2563EB 55%,#1D4ED8 100%);
  --ks-gradient-dark: linear-gradient(135deg,#132C50 0%,#0B1F3B 100%);
  --ks-transition-control: background-color 120ms cubic-bezier(.2,0,.2,1),border-color 120ms cubic-bezier(.2,0,.2,1),color 120ms cubic-bezier(.2,0,.2,1),box-shadow 120ms cubic-bezier(.2,0,.2,1);
  --ks-weight-h1: 700;
  --ks-weight-h2: 600;
  --ks-weight-h3: 600;
  --ks-weight-h4: 600;
  --ks-weight-regular: 400;
  --ks-weight-medium: 500;
  --ks-weight-semibold: 600;
  --ks-weight-bold: 700;
  --ks-tracking-tight: -0.02em;
  --ks-tracking-normal: 0em;
  --ks-tracking-caps: 0.08em;
  --ks-font-sans: "Inter","Segoe UI",system-ui,-apple-system,sans-serif;
  --ks-font-mono: "JetBrains Mono","SFMono-Regular",Consolas,monospace;
  --ks-num-tabular: "tnum" 1,"lnum" 1;
}
.body { font-family: var(--ks-font-sans); font-size: 16px; line-height: 24px; font-weight: 400; }
.h1 { font-family: var(--ks-font-sans); font-size: 48px; line-height: 56px; font-weight: 700; letter-spacing: -0.02em; }
.h2 { font-family: var(--ks-font-sans); font-size: 32px; line-height: 40px; font-weight: 600; letter-spacing: -0.02em; }
.h3 { font-family: var(--ks-font-sans); font-size: 24px; line-height: 32px; font-weight: 600; letter-spacing: -0.02em; }
.h4 { font-family: var(--ks-font-sans); font-size: 20px; line-height: 28px; font-weight: 600; letter-spacing: -0.02em; }
.code { font-family: var(--ks-font-mono); font-size: 13px; line-height: 24px; font-weight: 400; }
.kbd { font-family: var(--ks-font-mono); font-size: 13px; line-height: 24px; font-weight: 400; }
.ui-small { font-family: var(--ks-font-sans); font-size: 14px; line-height: 20px; font-weight: 400; }
.ui-label { font-family: var(--ks-font-sans); font-size: 14px; line-height: 20px; font-weight: 600; }
.table-dense { font-family: var(--ks-font-sans); font-size: 13px; line-height: 18px; font-weight: 400; }
.caption { font-family: var(--ks-font-sans); font-size: 12px; line-height: 16px; font-weight: 500; }
.eyebrow { font-family: var(--ks-font-sans); font-size: 12px; line-height: 16px; font-weight: 500; letter-spacing: 0.08em; }
.mono-id { font-family: var(--ks-font-mono); font-size: 13px; line-height: 18px; font-weight: 400; }
.mono-id-strong { font-family: var(--ks-font-mono); font-size: 14px; line-height: 20px; font-weight: 600; }

/* ---- css/src/01-fonts.css ---- */
/* Self-hosted fonts. Inter (SIL OFL 1.1) — brand sheet 06. JetBrains Mono (SIL OFL 1.1) — identifier/money columns.
   Subsets: latin, latin-ext (Polish), cyrillic (UK/RU). Paths are relative to this file (css/src/). */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/inter-latin-400-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";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/inter-latin-ext-400-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/inter-cyrillic-400-normal.woff2") format("woff2");
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/inter-latin-500-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";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/inter-latin-ext-500-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/inter-cyrillic-500-normal.woff2") format("woff2");
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/inter-latin-600-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";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/inter-latin-ext-600-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/inter-cyrillic-600-normal.woff2") format("woff2");
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/inter-latin-700-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";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/inter-latin-ext-700-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/inter-cyrillic-700-normal.woff2") format("woff2");
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/jetbrains-mono-latin-400-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: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/jetbrains-mono-latin-ext-400-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/jetbrains-mono-cyrillic-400-normal.woff2") format("woff2");
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/jetbrains-mono-latin-500-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: "JetBrains Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/jetbrains-mono-latin-ext-500-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/jetbrains-mono-cyrillic-500-normal.woff2") format("woff2");
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* ---- css/src/02-base.css ---- */
/* ==========================================================================
   02 · Base — reset, document defaults, derived component values, motion
   Every colour, size and duration is a token (var(--ks-…)) or derived from
   tokens with calc()/color-mix(). Raw values allowed here: 0, 1 (line-height,
   flex), percentages and the README's 0.55 disabled opacity.
   ========================================================================== */

/* Derived component values. Declared on every theme scope so a nested
   [data-theme] re-resolves them against its own tokens. */
:root,
[data-theme] {
  /* Control boundaries (inputs, selects, checkbox, switch track) — ≥3:1 on
     ks-surface-card and ks-surface-app in both themes (WCAG 2.2 · 1.4.11). */
  --ksc-control-edge: color-mix(in srgb, var(--ks-text-muted) 85%, var(--ks-surface-card));
  --ksc-control-edge-hover: var(--ks-text-muted);
  /* Secondary text on tinted fills (sunken table headers, counts, segmented
     tabs): ks-text-muted is 4.3:1 there in light, this is 4.85:1. */
  --ksc-text-muted-on-tint: color-mix(in srgb, var(--ks-text-muted) 90%, var(--ks-text-strong));
  /* Primary action hover/press. Light theme uses the tokens as specified; the
     dark theme swaps to steps that keep the white label at ≥4.5:1. */
  --ksc-action-hover: var(--ks-action-bg-hover);
  --ksc-action-active: var(--ks-action-bg-active);
  /* White-on-navy alphas for the top bar (README: "white-on-navy alpha"). */
  --ksc-on-navy-fill: color-mix(in srgb, var(--ks-white) 14%, var(--ks-navy-900));
  --ksc-on-navy-line: color-mix(in srgb, var(--ks-white) 18%, var(--ks-navy-900));
  --ksc-on-navy-edge: color-mix(in srgb, var(--ks-white) 45%, var(--ks-navy-900));
  --ksc-on-navy-muted: color-mix(in srgb, var(--ks-white) 72%, var(--ks-navy-900));
  /* Modal backdrop: rgba(11,31,59,.44) + 2px blur (README). */
  --ksc-overlay: color-mix(in srgb, var(--ks-navy-900) 44%, transparent);
  --ksc-overlay-blur: var(--ks-space-1);
  /* Banner edges derived from each status pair. */
  --ksc-edge-danger: color-mix(in srgb, var(--ks-status-danger-fg) 28%, var(--ks-status-danger-bg));
  --ksc-edge-warning: color-mix(in srgb, var(--ks-status-warning-fg) 28%, var(--ks-status-warning-bg));
  --ksc-edge-info: var(--ks-registry-border);
  --ksc-edge-success: color-mix(in srgb, var(--ks-status-success-fg) 28%, var(--ks-status-success-bg));
  /* Chip on a tinted banner. */
  --ksc-chip-on-tint: color-mix(in srgb, var(--ks-surface-card) 65%, transparent);
  /* Disabled (README: 0.55 opacity + not-allowed). */
  --ksc-disabled-opacity: 0.55;
  /* The one token behind the muted Ksiego mark (ProfileBadge, out of profile — a stated exception
     to "never recolour the mark", founders 2026-09-28; see Logo). Grayscale + this opacity, never
     a second drawing. */
  --ksc-mark-muted: 0.45;
  /* Icon sizes built from the space scale. */
  --ksc-icon-xs: var(--ks-space-5);                                   /* 12 */
  --ksc-icon-sm: calc(var(--ks-space-5) + var(--ks-space-1));         /* 14 */
  --ksc-icon-md: var(--ks-space-6);                                   /* 16 */
  --ksc-icon: calc(var(--ks-space-6) + var(--ks-space-1));            /* 18 */
  --ksc-icon-lg: var(--ks-space-7);                                   /* 20 */
  --ksc-icon-xl: var(--ks-space-8);                                   /* 24 */
  /* Small square controls (pager, top-bar buttons): 30px. */
  --ksc-square-sm: calc(var(--ks-control-h-sm) + var(--ks-space-1));
  /* Motion. */
  --ksc-spin: calc(var(--ks-duration-slow) * 3.5);                    /* ≈900ms */
  --ksc-shimmer: calc(var(--ks-duration-slow) * 5.4);                 /* ≈1.4s  */
}

[data-theme="dark"] {
  --ksc-text-muted-on-tint: var(--ks-text-muted);
  --ksc-action-hover: var(--ks-blue-700);
  --ksc-action-active: var(--ks-navy-700);
}
@media (prefers-color-scheme: dark) { :where(:root:not([data-ks-theme-fixed])):not([data-theme]) {
  --ksc-text-muted-on-tint: var(--ks-text-muted);
  --ksc-action-hover: var(--ks-blue-700);
  --ksc-action-active: var(--ks-navy-700);
} }

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  color-scheme: light;
}
html[data-theme="dark"] { color-scheme: dark; }
@media (prefers-color-scheme: dark) { html:where(:root:not([data-ks-theme-fixed])):not([data-theme]) { color-scheme: dark; } }

body {
  margin: 0;
  background: var(--ks-surface-app);
  color: var(--ks-text-default);
  font-family: var(--ks-font-sans);
  font-size: var(--ks-text-body);
  line-height: var(--ks-lh-body);
  font-feature-settings: var(--ks-num-tabular);
  /* A word longer than its box (a client name typed as one word, a long e-mail or account
     number) breaks rather than running out of the box and scrolling the page sideways
     (2026-10-01). break-word, not anywhere: it does not shrink a table column's min-content, so
     ordinary words still keep their columns. A flex or grid child holding text also needs
     min-width: 0 to let it wrap - see the rules that set it. */
  overflow-wrap: break-word;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  color: var(--ks-text-strong);
  letter-spacing: var(--ks-tracking-tight);
}
h1 { font-size: var(--ks-text-h1); line-height: var(--ks-lh-h1); font-weight: var(--ks-weight-h1); }
h2 { font-size: var(--ks-text-h2); line-height: var(--ks-lh-h2); font-weight: var(--ks-weight-h2); }
h3 { font-size: var(--ks-text-h3); line-height: var(--ks-lh-h3); font-weight: var(--ks-weight-h3); }
h4 { font-size: var(--ks-text-h4); line-height: var(--ks-lh-h4); font-weight: var(--ks-weight-h4); }
h5, h6 { font-size: var(--ks-text-small); line-height: var(--ks-lh-small); font-weight: var(--ks-weight-semibold); letter-spacing: var(--ks-tracking-normal); }

p { margin: 0; text-wrap: pretty; }
ul, ol { margin: 0; padding: 0; }
figure { margin: 0; }
img, svg { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
table { border-collapse: collapse; }
dialog { color: inherit; }

a {
  color: var(--ks-text-link);
  text-decoration: none;
  font-weight: var(--ks-weight-medium);
}
a:hover { color: var(--ks-text-strong); text-decoration: underline; }

code, kbd, samp {
  font-family: var(--ks-font-mono);
  font-size: var(--ks-text-dense);
}

::selection { background: var(--ks-blue-100); color: var(--ks-navy-900); }

/* Focus ring: 2px ks-focus-ring outline at 2px offset. Never removed. */
:focus-visible {
  outline: var(--ks-focus-w) solid var(--ks-focus-ring);
  outline-offset: var(--ks-focus-offset);
}
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible { border-radius: var(--ks-radius-xs); }

[hidden] { display: none !important; }

/* ---- Motion --------------------------------------------------------------- */
@keyframes ks-spin { to { transform: rotate(360deg); } }
@keyframes ks-fade-in { from { opacity: 0; transform: translateY(var(--ks-space-2)); } to { opacity: 1; transform: none; } }
@keyframes ks-toast-in { from { opacity: 0; transform: translateY(var(--ks-space-4)) scale(.98); } to { opacity: 1; transform: none; } }
@keyframes ks-drawer-in { from { transform: translateX(100%); } to { transform: none; } }
@keyframes ks-shimmer { from { background-position: -200% 0; } to { background-position: 200% 0; } }

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
  }
}

/* ---- css/src/03-layout.css ---- */
/* ==========================================================================
   03 · Layout primitives and text utilities
   Small, composable helpers so page markup never needs style="…".
   ========================================================================== */

/* Stack: vertical rhythm. Default gap 16px. */
.ks-stack { display: flex; flex-direction: column; gap: var(--ks-space-6); min-width: 0; }
.ks-stack--2xs { gap: var(--ks-space-1); }
.ks-stack--xs { gap: var(--ks-space-2); }
.ks-stack--sm { gap: var(--ks-space-4); }
.ks-stack--md { gap: var(--ks-space-5); }
.ks-stack--lg { gap: var(--ks-space-8); }
.ks-stack--xl { gap: var(--ks-space-9); }

/* Cluster: horizontal, wrapping. Default gap 8px. */
.ks-cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ks-space-4); min-width: 0; }
.ks-cluster--xs { gap: var(--ks-space-2); }
.ks-cluster--md { gap: var(--ks-space-5); }
.ks-cluster--lg { gap: var(--ks-space-6); }
.ks-cluster--xl { gap: var(--ks-space-8); }
.ks-cluster--nowrap { flex-wrap: nowrap; }
.ks-cluster--start { align-items: flex-start; }
.ks-cluster--end { justify-content: flex-end; }
.ks-cluster--between { justify-content: space-between; }
.ks-cluster--baseline { align-items: baseline; }
.ks-cluster--stretch { align-items: stretch; }

.ks-spacer { flex: 1; min-width: 0; }
.ks-grow { flex: 1; min-width: 0; }
.ks-none { flex: none; }

/* Grid */
.ks-grid { display: grid; gap: var(--ks-space-6); min-width: 0; }
.ks-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ks-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ks-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.ks-grid--main-aside { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
.ks-grid--aside-main { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); }
.ks-grid--auto { grid-template-columns: repeat(auto-fit, minmax(calc(var(--ks-space-12) * 3.5), 1fr)); }
.ks-grid--sm { gap: var(--ks-space-4); }
.ks-grid--md { gap: var(--ks-space-5); }
.ks-grid--start { align-items: start; }
@media (max-width: 900px) {
  .ks-grid--2, .ks-grid--3, .ks-grid--4,
  .ks-grid--main-aside, .ks-grid--aside-main { grid-template-columns: minmax(0, 1fr); }
}

/* Width constraints */
.ks-measure { max-width: var(--ks-content-max); }
.ks-measure--form { max-width: calc(var(--ks-space-12) * 11); }
.ks-measure--narrow { max-width: calc(var(--ks-space-12) * 7); }
.ks-full { width: 100%; }

/* Card / panel — README: white, 1px ks-border, 12px radius, xs/sm shadow. */
.ks-card {
  background: var(--ks-surface-card);
  border: var(--ks-border-w) solid var(--ks-border);
  border-radius: var(--ks-radius-xl);
  box-shadow: var(--ks-shadow-xs);
  padding: var(--ks-space-6);
  min-width: 0;
}
.ks-card--raised { box-shadow: var(--ks-shadow-sm); }
.ks-card--flush { padding: 0; overflow: hidden; }
.ks-card--compact { padding: var(--ks-space-5); }
.ks-card--roomy { padding: var(--ks-space-8); }
.ks-card--section { background: var(--ks-surface-section); border-color: var(--ks-blue-200); box-shadow: var(--ks-shadow-none); }
.ks-card__title {
  margin: 0 0 var(--ks-space-5);
  font-size: var(--ks-text-small);
  line-height: var(--ks-lh-small);
  font-weight: var(--ks-weight-semibold);
  letter-spacing: var(--ks-tracking-normal);
  color: var(--ks-text-strong);
}
.ks-divider { border: 0; border-top: var(--ks-border-w) solid var(--ks-border); margin: 0; }

/* Text utilities */
.ks-text-strong { color: var(--ks-text-strong); }
.ks-text-muted { color: var(--ks-text-muted); }
.ks-text-link { color: var(--ks-text-link); }
.ks-text-accent { color: var(--ks-text-accent); }
.ks-text-danger { color: var(--ks-status-danger-fg); }
.ks-text-success { color: var(--ks-status-success-fg); }
.ks-text-warning { color: var(--ks-status-warning-fg); }
.ks-text-small { font-size: var(--ks-text-small); line-height: var(--ks-lh-small); }
.ks-text-dense { font-size: var(--ks-text-dense); line-height: var(--ks-lh-dense); }
.ks-text-caption { font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); }
.ks-text-body { font-size: var(--ks-text-body); line-height: var(--ks-lh-body); }
.ks-text-right { text-align: right; }
.ks-text-center { text-align: center; }
.ks-weight-medium { font-weight: var(--ks-weight-medium); }
.ks-weight-semibold { font-weight: var(--ks-weight-semibold); }
.ks-weight-bold { font-weight: var(--ks-weight-bold); }
.ks-mono { font-family: var(--ks-font-mono); }
.ks-num { font-variant-numeric: tabular-nums; }
.ks-nowrap { white-space: nowrap; }
.ks-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.ks-eyebrow {
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-caption);
  font-weight: var(--ks-weight-semibold);
  letter-spacing: var(--ks-tracking-caps);
  text-transform: uppercase;
  color: var(--ks-text-muted);
}
.ks-display {
  font-size: var(--ks-text-h1);
  line-height: var(--ks-lh-h1);
  font-weight: var(--ks-weight-h1);
  letter-spacing: var(--ks-tracking-tight);
  color: var(--ks-text-strong);
}
.ks-amount {
  font-family: var(--ks-font-mono);
  font-size: var(--ks-text-h3);
  line-height: var(--ks-lh-h3);
  font-weight: var(--ks-weight-semibold);
  color: var(--ks-text-strong);
}

/* Lists without bullets */
.ks-list-plain { list-style: none; margin: 0; padding: 0; }

/* Link that looks like a list row */
.ks-link-quiet { color: inherit; font-weight: inherit; }
.ks-link-quiet:hover { color: var(--ks-text-link); }

/* Screen-reader only */
.ks-visually-hidden {
  position: absolute !important;
  width: var(--ks-border-w);
  height: var(--ks-border-w);
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Skip link */
.ks-skip-link {
  position: absolute;
  left: var(--ks-space-4);
  top: calc(-1 * var(--ks-space-12));
  z-index: 100;
  padding: var(--ks-space-4) var(--ks-space-6);
  background: var(--ks-surface-card);
  border-radius: var(--ks-radius-md);
  box-shadow: var(--ks-shadow-md);
}
.ks-skip-link:focus { top: var(--ks-space-4); }

/* Margin helpers (top only — spacing between siblings belongs to stacks) */
.ks-mt-xs { margin-top: var(--ks-space-2); }
.ks-mt-sm { margin-top: var(--ks-space-4); }
.ks-mt-md { margin-top: var(--ks-space-6); }
.ks-mt-lg { margin-top: var(--ks-space-8); }
.ks-self-start { align-self: flex-start; }
.ks-self-center { align-self: center; }

/* ---- css/src/10-core.css ---- */
/* ==========================================================================
   10 · Core — Icon, Button, Input, Select, SearchInput, Checkbox, Switch,
   Tabs, FieldRow
   ========================================================================== */

/* ---- Icon ----------------------------------------------------------------
   <svg class="ks-icon" aria-hidden="true" focusable="false">
     <use href="icons/icons.svg#ks-i-search"></use></svg>                    */
.ks-icon {
  display: inline-block;
  flex: none;
  width: var(--ksc-icon);
  height: var(--ksc-icon);
  color: inherit;
  vertical-align: middle;
  overflow: visible;
}
.ks-icon--xs { width: var(--ksc-icon-xs); height: var(--ksc-icon-xs); }
.ks-icon--sm { width: var(--ksc-icon-sm); height: var(--ksc-icon-sm); }
.ks-icon--md { width: var(--ksc-icon-md); height: var(--ksc-icon-md); }
.ks-icon--lg { width: var(--ksc-icon-lg); height: var(--ksc-icon-lg); }
.ks-icon--xl { width: var(--ksc-icon-xl); height: var(--ksc-icon-xl); }
.ks-icon--spin { animation: ks-spin var(--ksc-spin) linear infinite; }
.ks-icon--muted { color: var(--ks-text-muted); }
.ks-icon--accent { color: var(--ks-text-accent); }
.ks-icon--success { color: var(--ks-status-success-fg); }
.ks-icon--warning { color: var(--ks-status-warning-fg); }
.ks-icon--danger { color: var(--ks-status-danger-fg); }
.ks-icon--info { color: var(--ks-status-info-fg); }

/* Icon tile — 12px-radius pale tile from brand sheet 07. */
.ks-icon-tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--ks-control-h-lg);
  height: var(--ks-control-h-lg);
  border-radius: var(--ks-radius-xl);
  background: var(--ks-surface-section);
  color: var(--ks-blue-600);
}
[data-theme="dark"] .ks-icon-tile { color: var(--ks-text-accent); }
@media (prefers-color-scheme: dark) { :where(:root:not([data-ks-theme-fixed])):not([data-theme]) .ks-icon-tile { color: var(--ks-text-accent); } }
.ks-icon-tile--bordered { background: var(--ks-surface-app); border: var(--ks-border-w) solid var(--ks-border); }

/* ---- Button -------------------------------------------------------------- */
.ks-btn {
  --ksc-btn-h: var(--ks-control-h);
  --ksc-btn-pad: var(--ks-space-6);
  --ksc-btn-gap: var(--ks-space-4);
  --ksc-btn-font: var(--ks-text-small);
  --ksc-btn-icon: var(--ksc-icon-md);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ksc-btn-gap);
  height: var(--ksc-btn-h);
  padding: 0 calc(var(--ksc-btn-pad) - var(--ks-space-1));
  border: var(--ks-border-w) solid transparent;
  border-radius: var(--ks-radius-lg);
  background: var(--ks-action-bg);
  color: var(--ks-action-fg);
  font-family: var(--ks-font-sans);
  font-size: var(--ksc-btn-font);
  font-weight: var(--ks-weight-medium);
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  transition: var(--ks-transition-control);
  user-select: none;
}
.ks-btn .ks-icon { width: var(--ksc-btn-icon); height: var(--ksc-btn-icon); }
.ks-btn:hover { text-decoration: none; }
.ks-btn:active { transform: translateY(calc(var(--ks-border-w) / 2)); }
.ks-btn:focus-visible { border-radius: var(--ks-radius-lg); }

/* Variants */
.ks-btn--primary { background: var(--ks-action-bg); color: var(--ks-action-fg); box-shadow: var(--ks-shadow-xs); }
.ks-btn--primary:hover { background: var(--ksc-action-hover); color: var(--ks-action-fg); }
.ks-btn--primary:active { background: var(--ksc-action-active); }

.ks-btn--secondary { background: var(--ks-action-secondary-bg); color: var(--ks-action-secondary-fg); }
.ks-btn--secondary:hover { background: var(--ks-action-secondary-bg-hover); color: var(--ks-action-secondary-fg); }

.ks-btn--outline { background: var(--ks-surface-card); color: var(--ks-text-strong); border-color: var(--ks-border-strong); }
.ks-btn--outline:hover { background: var(--ks-surface-hover); color: var(--ks-text-strong); border-color: var(--ksc-control-edge); }
.ks-btn--outline:active { background: var(--ks-surface-sunken); }

.ks-btn--ghost { background: transparent; color: var(--ks-text-default); }
.ks-btn--ghost:hover { background: var(--ks-surface-hover); color: var(--ks-text-strong); }
.ks-btn--ghost:active { background: var(--ks-surface-sunken); }

.ks-btn--danger { background: var(--ks-red-600); color: var(--ks-white); }
.ks-btn--danger:hover { background: var(--ks-red-700); color: var(--ks-white); }

.ks-btn--link {
  height: auto;
  padding: 0;
  background: transparent;
  color: var(--ks-text-link);
}
.ks-btn--link:hover { color: var(--ks-text-link); text-decoration: underline; }
.ks-btn--link:active { transform: none; }

/* On navy (top bar, CTA band) */
.ks-btn--on-dark {
  background: transparent;
  color: var(--ks-white);
  border-color: var(--ksc-on-navy-edge);
}
.ks-btn--on-dark:hover { background: var(--ksc-on-navy-fill); color: var(--ks-white); }

/* Sizes: sm 28px (table rows, filter bars) · md 36px · lg 44px (login, mobile, CTA) */
.ks-btn--sm {
  --ksc-btn-h: var(--ks-control-h-sm);
  --ksc-btn-pad: var(--ks-space-5);
  --ksc-btn-gap: var(--ks-space-3);
  --ksc-btn-font: var(--ks-text-dense);
  --ksc-btn-icon: var(--ksc-icon-sm);
}
.ks-btn--lg {
  --ksc-btn-h: var(--ks-control-h-lg);
  --ksc-btn-pad: var(--ks-space-7);
  --ksc-btn-gap: var(--ks-space-5);
  --ksc-btn-font: var(--ks-text-body);
  --ksc-btn-icon: var(--ksc-icon);
}
.ks-btn--block { display: flex; width: 100%; }
.ks-btn--icon { width: var(--ksc-btn-h); padding: 0; }
/* Compact: on a phone (<=600px) the button is its icon alone. Put the text in .ks-btn__label so it
   stays the accessible name (visually hidden, not removed); above 600px nothing changes. Also
   applied to every button inside .ks-pagehead__actions--compact. */
@media (max-width: 600px) {
  .ks-btn--compact,
  .ks-pagehead__actions--compact .ks-btn { width: var(--ksc-btn-h); padding: 0; flex: none; }
  .ks-btn--compact .ks-btn__label,
  .ks-pagehead__actions--compact .ks-btn__label {
    position: absolute;
    width: var(--ks-border-w);
    height: var(--ks-border-w);
    margin: calc(var(--ks-border-w) * -1);
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}
.ks-btn--square-sm { --ksc-btn-h: var(--ksc-square-sm); width: var(--ksc-square-sm); padding: 0; border-radius: var(--ks-radius-md); }

/* Loading: aria-busy="true". Put the spinner first; it replaces the leading icon. */
.ks-btn__spinner { display: none; }
.ks-btn[aria-busy="true"] .ks-btn__spinner { display: inline-block; animation: ks-spin var(--ksc-spin) linear infinite; }
.ks-btn[aria-busy="true"] .ks-btn__icon { display: none; }
.ks-btn[aria-busy="true"] { pointer-events: none; }

/* Disabled — 0.55 opacity + not-allowed. A busy button is not faded: it keeps full contrast
   (the faded label on the primary fill was 2.3:1) and says "working" through the spinner. */
.ks-btn:disabled,
.ks-btn[aria-disabled="true"] {
  opacity: var(--ksc-disabled-opacity);
  cursor: not-allowed;
  transform: none;
  box-shadow: var(--ks-shadow-none);
}
.ks-btn--primary:disabled:hover, .ks-btn--primary[aria-disabled="true"]:hover { background: var(--ks-action-bg); }
.ks-btn--secondary:disabled:hover { background: var(--ks-action-secondary-bg); }
.ks-btn--outline:disabled:hover { background: var(--ks-surface-card); border-color: var(--ks-border-strong); }
.ks-btn--ghost:disabled:hover { background: transparent; }
.ks-btn--danger:disabled:hover { background: var(--ks-red-600); }

.ks-btn-group { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ks-space-4); }
.ks-btn-group--end { justify-content: flex-end; }

/* ---- Field (Input, Select, SearchInput) ----------------------------------- */
.ks-field {
  --ksc-field-h: var(--ks-control-h);
  --ksc-field-font: var(--ks-text-small);
  display: flex;
  flex-direction: column;
  gap: var(--ks-space-3);
  min-width: 0;
}
.ks-field--sm { --ksc-field-h: var(--ks-control-h-sm); --ksc-field-font: var(--ks-text-dense); }
.ks-field--lg { --ksc-field-h: var(--ks-control-h-lg); }

.ks-field__label {
  font-size: var(--ks-text-small);
  line-height: var(--ks-lh-small);
  font-weight: var(--ks-weight-medium);
  color: var(--ks-text-strong);
}
.ks-field__req { color: var(--ks-status-danger-fg); }
.ks-field__optional { color: var(--ks-text-muted); font-weight: var(--ks-weight-regular); }

.ks-field__control {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--ks-space-4);
  height: var(--ksc-field-h);
  padding: 0 calc(var(--ks-space-4) + var(--ks-space-1));
  background: var(--ks-surface-card);
  border: var(--ks-border-w) solid var(--ksc-control-edge);
  border-radius: var(--ks-radius-lg);
  transition: var(--ks-transition-control);
  min-width: 0;
}
.ks-field__control:hover { border-color: var(--ksc-control-edge-hover); }
.ks-field__control:focus-within {
  border-color: var(--ks-focus-ring);
  box-shadow: var(--ks-shadow-focus);
}
/* Date and time inputs: Chromium puts focus in the input's internal segments, so the input matches
   neither :focus-visible nor even :focus (checked 2026-09-30), and the ring never showed. Only
   :focus-within on the control sees it. Those segments take focus from the keyboard or from a click
   into one, so the ring shows for both — on a date field that is where typing goes either way. */
.ks-field__control:has(:focus-visible),
.ks-field__control:focus-within:has(input[type="date"], input[type="time"], input[type="datetime-local"], input[type="month"]) {
  outline: var(--ks-focus-w) solid var(--ks-focus-ring);
  outline-offset: var(--ks-focus-offset);
}
.ks-field__control:has([aria-invalid="true"]) { border-color: var(--ks-status-danger-fg); }
.ks-field__control:has([aria-invalid="true"]):focus-within {
  box-shadow: 0 0 0 calc(var(--ks-focus-w) + var(--ks-border-w)) var(--ks-status-danger-bg);
}
.ks-field__control:has(:disabled) {
  background: var(--ks-surface-disabled);
  border-color: var(--ks-border-strong);
  cursor: not-allowed;
}
.ks-field__control:has(:disabled) > * { opacity: var(--ksc-disabled-opacity); }
.ks-field__control:has([readonly]) { background: var(--ks-surface-sunken); }

.ks-field__input {
  flex: 1;
  min-width: 0;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--ks-text-default);
  font-family: var(--ks-font-sans);
  font-size: var(--ksc-field-font);
}
.ks-field__input:focus-visible { outline: 0; }
.ks-field__input::placeholder { color: var(--ks-text-muted); opacity: 1; }
.ks-field__input:disabled { cursor: not-allowed; }
.ks-field__input--mono { font-family: var(--ks-font-mono); letter-spacing: calc(var(--ks-tracking-caps) / 4); }
.ks-field__input--right { text-align: right; }
textarea.ks-field__input { padding: var(--ks-space-4) 0; resize: vertical; }
.ks-field__control--textarea { height: auto; min-height: calc(var(--ks-control-h) * 2.5); align-items: stretch; }

.ks-field__icon { width: var(--ksc-icon-md); height: var(--ksc-icon-md); color: var(--ks-text-muted); }
.ks-field__suffix {
  display: inline-flex;
  align-items: center;
  gap: var(--ks-space-3);
  flex: none;
  color: var(--ks-text-muted);
  font-size: var(--ks-text-dense);
}

/* Select: native <select> inside the control, chevron drawn with the sprite. */
.ks-field__control--select { padding: 0; }
.ks-select {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  padding: 0 calc(var(--ks-space-9) + var(--ks-space-1)) 0 calc(var(--ks-space-4) + var(--ks-space-1));
  cursor: pointer;
  border-radius: var(--ks-radius-lg);
}
.ks-select:has(option[value=""]:checked) { color: var(--ks-text-muted); }
.ks-select option { color: var(--ks-text-default); background: var(--ks-surface-card); }
.ks-field__chevron {
  position: absolute;
  right: calc(var(--ks-space-4) + var(--ks-space-1));
  width: var(--ksc-icon-md);
  height: var(--ksc-icon-md);
  color: var(--ks-text-muted);
  pointer-events: none;
}

.ks-field__hint,
.ks-field__error {
  display: flex;
  align-items: flex-start;
  gap: var(--ks-space-2);
  margin: 0;
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-caption);
  color: var(--ks-text-muted);
}
.ks-field__error { color: var(--ks-status-danger-fg); font-weight: var(--ks-weight-medium); }
.ks-field__error .ks-icon,
.ks-field__hint .ks-icon { width: var(--ksc-icon-xs); height: var(--ksc-icon-xs); margin-top: calc(var(--ks-space-1) / 2); }

/* Search input */
.ks-search { width: calc(var(--ks-space-12) * 4.375); max-width: 100%; }
.ks-search--full { width: 100%; }
.ks-search .ks-field__input::-webkit-search-cancel-button { cursor: pointer; }
/* A server search in flight: htmx puts htmx-request on the field or on its hx-indicator (an
   ancestor), and the search icon gives way to a spinner in the same place. */
.ks-search__busy { display: none; }
.htmx-request .ks-search .ks-search__busy,
.ks-search:has(.ks-field__input.htmx-request) .ks-search__busy { display: inline-block; animation: ks-spin var(--ksc-spin) linear infinite; }
.htmx-request .ks-search .ks-field__icon:not(.ks-search__busy),
.ks-search:has(.ks-field__input.htmx-request) .ks-field__icon:not(.ks-search__busy) { display: none; }

/* ---- Checkbox & radio ----------------------------------------------------- */
.ks-check,
.ks-table__select {
  --ksc-check: calc(var(--ks-space-6) + var(--ks-space-1));   /* 18px */
}
.ks-check {
  display: inline-flex;
  align-items: center;
  gap: var(--ks-space-4);
  cursor: pointer;
  color: var(--ks-text-default);
  font-size: var(--ks-text-small);
  line-height: var(--ks-lh-small);
}
.ks-check--sm { --ksc-check: var(--ks-space-6); }           /* 16px — dense table rows */
.ks-check:has(.ks-check__hint) { align-items: flex-start; }
.ks-check__input {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  flex: none;
  display: inline-grid;
  place-content: center;
  width: var(--ksc-check);
  height: var(--ksc-check);
  margin: 0;
  background: var(--ks-surface-card);
  border: var(--ks-border-w) solid var(--ksc-control-edge);
  border-radius: var(--ks-radius-sm);
  cursor: inherit;
  transition: var(--ks-transition-control);
}
.ks-check:has(.ks-check__hint) .ks-check__input { margin-top: calc(var(--ks-space-1) / 2); }
.ks-check__input:hover { border-color: var(--ksc-control-edge-hover); }
.ks-check__input::before {
  content: "";
  width: calc(var(--ksc-check) * 0.28);
  height: calc(var(--ksc-check) * 0.52);
  margin-top: calc(var(--ksc-check) * -0.08);
  border: solid var(--ks-action-fg);
  border-width: 0 calc(var(--ks-border-w) * 2.25) calc(var(--ks-border-w) * 2.25) 0;
  transform: rotate(45deg) scale(0);
  transition: transform var(--ks-duration-instant) var(--ks-ease-out);
}
.ks-check__input:checked,
.ks-check__input:indeterminate,
.ks-check__input[data-state="mixed"] {
  background: var(--ks-action-bg);
  border-color: var(--ks-action-bg);
}
.ks-check__input:checked::before { transform: rotate(45deg) scale(1); }
.ks-check__input:indeterminate::before,
.ks-check__input[data-state="mixed"]::before {
  width: calc(var(--ksc-check) * 0.5);
  height: 0;
  margin-top: 0;
  border-width: 0 0 calc(var(--ks-border-w) * 2.25) 0;
  transform: none;
}
.ks-check__input[type="radio"] { border-radius: 50%; }
.ks-check__input[type="radio"]::before {
  width: calc(var(--ksc-check) * 0.4);
  height: calc(var(--ksc-check) * 0.4);
  margin: 0;
  border: 0;
  border-radius: 50%;
  background: var(--ks-action-fg);
  transform: scale(0);
}
.ks-check__input[type="radio"]:checked::before { transform: scale(1); }
.ks-check__input[aria-invalid="true"] { border-color: var(--ks-status-danger-fg); }
.ks-check:has(:disabled) { cursor: not-allowed; opacity: var(--ksc-disabled-opacity); }
.ks-check__text { display: flex; flex-direction: column; gap: var(--ks-space-1); min-width: 0; }
.ks-check__hint { font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); color: var(--ks-text-muted); }
.ks-checkgroup { display: flex; flex-direction: column; gap: var(--ks-space-4); margin: 0; padding: 0; border: 0; }
.ks-checkgroup__legend { padding: 0; margin-bottom: var(--ks-space-3); font-size: var(--ks-text-small); font-weight: var(--ks-weight-medium); color: var(--ks-text-strong); }

/* ---- Switch ------------------------------------------------------------------
   Instant-effect toggle: <input type="checkbox" role="switch">                 */
.ks-switch {
  --ksc-switch-w: var(--ks-control-h-lg);                                  /* 44 */
  --ksc-switch-h: var(--ks-space-8);                                       /* 24 */
  --ksc-switch-thumb: calc(var(--ks-space-6) + var(--ks-space-1));         /* 18 */
  --ksc-switch-inset: calc((var(--ksc-switch-h) - var(--ksc-switch-thumb)) / 2);
  display: inline-flex;
  align-items: center;
  gap: var(--ks-space-5);
  cursor: pointer;
  color: var(--ks-text-default);
  font-size: var(--ks-text-small);
  line-height: var(--ks-lh-small);
}
.ks-switch__input {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  flex: none;
  width: var(--ksc-switch-w);
  height: var(--ksc-switch-h);
  margin: 0;
  border-radius: var(--ks-radius-pill);
  background: var(--ksc-control-edge);
  cursor: inherit;
  transition: background-color var(--ks-duration-base) var(--ks-ease-standard);
}
.ks-switch__input::before {
  content: "";
  position: absolute;
  top: var(--ksc-switch-inset);
  left: var(--ksc-switch-inset);
  width: var(--ksc-switch-thumb);
  height: var(--ksc-switch-thumb);
  border-radius: 50%;
  background: var(--ks-white);
  box-shadow: var(--ks-shadow-sm);
  transition: transform var(--ks-duration-base) var(--ks-ease-standard);
}
.ks-switch__input:checked { background: var(--ks-action-bg); }
.ks-switch__input:checked::before { transform: translateX(calc(var(--ksc-switch-w) - var(--ksc-switch-thumb) - var(--ksc-switch-inset) * 2)); }
.ks-switch__input:focus-visible { outline-offset: var(--ks-focus-offset); border-radius: var(--ks-radius-pill); }
.ks-switch:has(:disabled) { cursor: not-allowed; opacity: var(--ksc-disabled-opacity); }
.ks-switch__text { display: flex; flex-direction: column; gap: var(--ks-space-1); }
.ks-switch__hint { font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); color: var(--ks-text-muted); }
.ks-switch__state { font-size: var(--ks-text-caption); color: var(--ks-text-muted); }

/* ---- Tabs --------------------------------------------------------------------
   underline — page sections · segmented — in-panel switches.
   Works with role="tab" buttons (aria-selected) or plain links (aria-current). */
.ks-tabs { display: flex; flex-direction: column; gap: var(--ks-space-6); min-width: 0; }
.ks-tabs__list {
  display: flex;
  align-items: stretch;
  gap: var(--ks-space-1);
  border-bottom: var(--ks-border-w) solid var(--ks-border);
  overflow-x: auto;
  scrollbar-width: none;
}
.ks-tabs__list::-webkit-scrollbar { display: none; }
/* More tabs than fit: js/ksiego.js sets data-overflow on the list (start | end | both) and the
   edge that still has tabs behind it fades out. Without JS the list still scrolls, just unhinted. */
.ks-tabs__list[data-overflow="end"] { mask-image: linear-gradient(to right, var(--ks-text-strong) calc(100% - var(--ks-space-9)), transparent); }
.ks-tabs__list[data-overflow="start"] { mask-image: linear-gradient(to left, var(--ks-text-strong) calc(100% - var(--ks-space-9)), transparent); }
.ks-tabs__list[data-overflow="both"] { mask-image: linear-gradient(to right, transparent, var(--ks-text-strong) var(--ks-space-9), var(--ks-text-strong) calc(100% - var(--ks-space-9)), transparent); }
.ks-tabs__tab {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--ks-space-3) + var(--ks-space-1) / 2);
  height: var(--ks-control-h);
  margin: 0 0 calc(var(--ks-border-w) * -1);
  padding: 0 var(--ks-space-5) var(--ks-space-1);
  border: 0;
  border-bottom: var(--ks-focus-w) solid transparent;
  background: transparent;
  color: var(--ks-text-muted);
  font-family: var(--ks-font-sans);
  font-size: var(--ks-text-small);
  font-weight: var(--ks-weight-medium);
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  transition: var(--ks-transition-control);
}
.ks-tabs__tab .ks-icon { width: var(--ksc-icon-md); height: var(--ksc-icon-md); }
.ks-tabs__tab:hover { color: var(--ks-text-strong); text-decoration: none; }
.ks-tabs__tab[aria-selected="true"],
.ks-tabs__tab[aria-current="page"] {
  color: var(--ks-text-strong);
  font-weight: var(--ks-weight-semibold);
  border-bottom-color: var(--ks-action-bg);
}
.ks-tabs__tab:disabled,
.ks-tabs__tab[aria-disabled="true"] { color: var(--ks-text-subtle); cursor: not-allowed; }
.ks-tabs__tab:focus-visible { outline-offset: calc(var(--ks-focus-offset) * -1); }
.ks-tabs__count {
  min-width: var(--ks-space-7);
  padding: 0 var(--ks-space-3);
  border-radius: var(--ks-radius-pill);
  background: var(--ks-surface-sunken);
  color: var(--ksc-text-muted-on-tint);
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-caption);
  font-weight: var(--ks-weight-semibold);
  text-align: center;
}
.ks-tabs__tab[aria-selected="true"] .ks-tabs__count,
.ks-tabs__tab[aria-current="page"] .ks-tabs__count { background: var(--ks-surface-section); color: var(--ks-text-link); }
.ks-tabs__panel { min-width: 0; }
.ks-tabs__panel:focus-visible { border-radius: var(--ks-radius-md); }

.ks-tabs--segmented .ks-tabs__list {
  display: inline-flex;
  align-self: flex-start;
  gap: var(--ks-space-2);
  padding: calc(var(--ks-space-1) + var(--ks-border-w));
  border: 0;
  border-radius: var(--ks-radius-lg);
  background: var(--ks-surface-sunken);
}
.ks-tabs--segmented .ks-tabs__tab {
  color: var(--ksc-text-muted-on-tint);
  height: calc(var(--ks-control-h-sm) + var(--ks-space-1));
  margin: 0;
  padding: 0 var(--ks-space-5);
  border: 0;
  border-radius: var(--ks-radius-md);
}
.ks-tabs--segmented .ks-tabs__tab[aria-selected="true"],
.ks-tabs--segmented .ks-tabs__tab[aria-current="page"] {
  background: var(--ks-surface-card);
  box-shadow: var(--ks-shadow-xs);
}
.ks-tabs--segmented .ks-tabs__tab:focus-visible { outline-offset: 0; }
.ks-tabs--flush { gap: 0; }

/* ---- FieldRow ------------------------------------------------------------------
   Read-mode label/value rows inside <dl class="ks-fieldlist">.               */
.ks-fieldlist { margin: 0; display: flex; flex-direction: column; min-width: 0; }
.ks-fieldrow {
  display: grid;
  grid-template-columns: calc(var(--ks-space-12) * 3.125) minmax(0, 1fr);  /* 200px label */
  gap: var(--ks-space-6);
  align-items: baseline;
  padding: var(--ks-space-4) 0;
  border-bottom: var(--ks-border-w) solid var(--ks-border);
}
.ks-fieldrow:last-child { border-bottom: 0; }
.ks-fieldrow__label {
  margin: 0;
  font-size: var(--ks-text-small);
  line-height: var(--ks-lh-small);
  color: var(--ks-text-muted);
}
.ks-fieldrow__value {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ks-space-4);
  margin: 0;
  min-width: 0;
  font-size: var(--ks-text-small);
  line-height: var(--ks-lh-small);
  color: var(--ks-text-default);
}
/* The value is a flex row, so its text is a flex item sized by its longest word: anywhere (not
   break-word) lets that word shrink and break, and the children may shrink below their content. */
.ks-fieldrow__value { overflow-wrap: anywhere; }
.ks-fieldrow__value > * { min-width: 0; max-width: 100%; }
.ks-fieldrow__secondary { font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); color: var(--ks-text-muted); }
.ks-grid > .ks-fieldrow { border-bottom: 0; padding-block: 0; }
.ks-fieldrow--stacked { display: flex; flex-direction: column; align-items: stretch; gap: var(--ks-space-2); }
.ks-fieldlist--narrow .ks-fieldrow { grid-template-columns: calc(var(--ks-space-12) * 2.25) minmax(0, 1fr); }
@media (max-width: 480px) {
  .ks-fieldrow { display: flex; flex-direction: column; align-items: stretch; gap: var(--ks-space-2); }
}

/* ---- css/src/20-data.css ---- */
/* ==========================================================================
   20 · Data — DataTable, SkeletonRows, Pager, FilterBar, FilterChip, Menu
   ========================================================================== */

/* ---- DataTable -----------------------------------------------------------
   A real <table>. At ≤480px of available width the same markup renders as a
   card list (container query) using each cell's data-label.               */
.ks-table {
  container: ks-table / inline-size;
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.ks-table__scroll {
  overflow-x: auto;
  background: var(--ks-surface-card);
  border: var(--ks-border-w) solid var(--ks-border);
  border-radius: var(--ks-radius-xl);
}
.ks-filterbar + .ks-table__scroll,
.ks-filterbar + .ks-table__bulk + .ks-table__scroll,
.ks-table__bulk + .ks-table__scroll { border-top-left-radius: 0; border-top-right-radius: 0; }

.ks-table__table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--ks-text-dense);
  line-height: var(--ks-lh-dense);
  color: var(--ks-text-default);
}
.ks-table--comfy .ks-table__table { font-size: var(--ks-text-small); line-height: var(--ks-lh-small); }

.ks-table__table thead th {
  height: calc(var(--ks-row-h) - var(--ks-space-3));   /* 38px header */
  padding: 0 var(--ks-space-5);
  background: var(--ks-surface-sunken);
  border-bottom: var(--ks-border-w) solid var(--ks-border);
  text-align: left;
  white-space: nowrap;
  vertical-align: middle;
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-caption);
  font-weight: var(--ks-weight-semibold);
  letter-spacing: var(--ks-tracking-caps);
  text-transform: uppercase;
  color: var(--ksc-text-muted-on-tint);
}
.ks-table--sticky thead th { position: sticky; top: 0; z-index: 1; }
.ks-table__table th[aria-sort] { color: var(--ks-text-strong); }

.ks-table__sort {
  display: inline-flex;
  align-items: center;
  gap: var(--ks-space-2);
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
}
.ks-table__sort:hover { color: var(--ks-text-strong); text-decoration: none; }
.ks-table__sort .ks-icon { width: var(--ksc-icon-xs); height: var(--ksc-icon-xs); color: var(--ks-text-muted); }
th[aria-sort] .ks-table__sort .ks-icon { color: var(--ks-text-link); }
/* One sprite glyph per direction: show the one that matches aria-sort. */
.ks-table__sort-asc,
.ks-table__sort-desc { display: none; }
th[aria-sort="ascending"] .ks-table__sort-none,
th[aria-sort="descending"] .ks-table__sort-none { display: none; }
th[aria-sort="ascending"] .ks-table__sort-asc,
th[aria-sort="descending"] .ks-table__sort-desc { display: inline-block; }

.ks-table__table tbody td {
  height: var(--ks-row-h);
  padding: var(--ks-space-3) var(--ks-space-5);
  border-bottom: var(--ks-border-w) solid var(--ks-border);
  vertical-align: middle;
  white-space: nowrap;
  max-width: calc(var(--ks-space-12) * 4.25);
  overflow: hidden;
  text-overflow: ellipsis;
}
/* A cell's overflow: hidden (for the ellipsis) also clips any tooltip bubble inside it, so a cell
   holding ClientMarker's strip lets its bubbles out and moves the ellipsis onto its other children. */
.ks-table__table tbody td:has(.ks-markers) { overflow: visible; }
.ks-table__table tbody td:has(.ks-markers) > .ks-table__primary {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ks-table--comfy .ks-table__table tbody td { height: var(--ks-row-h-comfy); }
.ks-table__table tbody tr:last-child td { border-bottom: 0; }
.ks-table__table tbody tr { transition: background-color var(--ks-duration-instant) var(--ks-ease-standard); }
.ks-table__table tbody tr:hover { background: var(--ks-surface-hover); }
.ks-table__table tbody tr:has(.ks-table__select :checked),
.ks-table__table tbody tr[aria-selected="true"] { background: var(--ks-surface-selected); }
.ks-table__table tbody tr:focus-within { background: var(--ks-surface-hover); }

.ks-table__select { width: calc(var(--ks-space-9) + var(--ks-space-4)); padding-left: var(--ks-space-6) !important; padding-right: 0 !important; }
.ks-table__cell--num { text-align: right; font-family: var(--ks-font-mono); font-variant-numeric: tabular-nums; }
.ks-table__cell--mono { font-family: var(--ks-font-mono); }
.ks-table__cell--wrap { white-space: normal !important; }
.ks-table__cell--actions { width: 1%; text-align: right; overflow: visible !important; }
.ks-table__cell--muted { color: var(--ks-text-muted); }
.ks-table__table th.ks-table__cell--num { text-align: right; }
.ks-table__primary { color: var(--ks-text-strong); font-weight: var(--ks-weight-medium); }
a.ks-table__primary:hover { color: var(--ks-text-link); }
.ks-table__sub { display: block; color: var(--ks-text-muted); font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); }
.ks-table__stack { display: flex; flex-direction: column; align-items: flex-start; gap: var(--ks-space-1); white-space: normal; }

/* Bulk selection bar — visible only while a row checkbox is checked (CSS :has). */
.ks-table__bulk {
  display: none;
  align-items: center;
  gap: var(--ks-space-5);
  padding: calc(var(--ks-space-4) + var(--ks-space-1) / 2) var(--ks-space-6);
  background: var(--ks-surface-selected);
  border: var(--ks-border-w) solid var(--ks-blue-200);
  border-bottom: 0;
  font-size: var(--ks-text-small);
  color: var(--ks-text-link);
}
.ks-table:has(tbody .ks-table__select :checked) .ks-table__bulk,
.ks-table__bulk[data-state="open"] { display: flex; }
.ks-filterbar + .ks-table__bulk { border-top: 0; }
.ks-table__bulk-count { font-weight: var(--ks-weight-medium); }

/* State rows: loading / empty / error inside the same frame. */
.ks-table__table tbody td.ks-table__state {
  height: auto;
  padding: var(--ks-space-4);
  white-space: normal;
  max-width: none;
}
.ks-table__state .ks-empty,
.ks-table__state .ks-banner { border-radius: var(--ks-radius-lg); }
.ks-table__skeleton td { overflow: visible; }
/* Group header row: caption cell spanning the table when grouped (Grupuj).
   DRAFT — under review with the founders, not yet in the component README. */
.ks-table__table tbody tr.ks-table__group-row { background: var(--ks-surface-sunken); }
.ks-table__table tbody td.ks-table__group {
  height: calc(var(--ks-row-h) - var(--ks-space-3));
  padding: 0 var(--ks-space-6);
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-caption);
  font-weight: var(--ks-weight-semibold);
  letter-spacing: var(--ks-tracking-caps);
  text-transform: uppercase;
  color: var(--ks-text-muted);
}
.ks-table__group-count {
  margin-left: var(--ks-space-2);
  padding: 0 calc(var(--ks-space-2) + var(--ks-border-w));
  border-radius: var(--ks-radius-pill);
  background: var(--ks-surface-card);
  color: var(--ks-text-strong);
  font-weight: var(--ks-weight-semibold);
  text-transform: none;
  letter-spacing: normal;
}
/* The loading body of a table: hidden until htmx marks it while its request is in flight. */
tbody.htmx-indicator { display: none; }
tbody.htmx-indicator.htmx-request { display: table-row-group; }
/* And while it shows, the rows give way to it, as the component's Loading example draws the table:
   one body at a time. Both at once pushed the rows down the page for the length of the request and
   snapped them back when the answer landed. */
.ks-table__table tbody.htmx-indicator.htmx-request ~ tbody { display: none; }

/* A cell icon stands in for the text label in the card list only (data-icon on the <td>); in the
   table proper the column header carries the meaning, so the glyph is not shown. */
.ks-table__cellicon { display: none; }

/* Card list at narrow widths */
@container ks-table (max-width: 480px) {
  .ks-table__scroll { background: transparent; border: 0; overflow: visible; }
  .ks-table__table,
  .ks-table__table tbody,
  .ks-table__table tr,
  .ks-table__table td { display: block; width: 100%; }
  .ks-table__table thead {
    position: absolute;
    width: var(--ks-border-w);
    height: var(--ks-border-w);
    overflow: hidden;
    clip-path: inset(50%);
  }
  .ks-table__table tbody { display: flex; flex-direction: column; gap: var(--ks-space-4); }
  /* tbody.htmx-indicator[.htmx-request] (0,2,1 / 0,1,1 at equal source position) outranks or ties the
     rule above depending on state: restate both states here so a skeleton body neither shows outside
     a request (plain page load) nor loses the card-list layout while one is in flight. */
  .ks-table__table tbody.htmx-indicator:not(.htmx-request) { display: none; }
  .ks-table__table tbody.htmx-indicator.htmx-request { display: flex; flex-direction: column; gap: var(--ks-space-4); }
  .ks-table__table tbody tr {
    display: grid;
    gap: var(--ks-space-2);
    padding: var(--ks-space-5);
    background: var(--ks-surface-card);
    border: var(--ks-border-w) solid var(--ks-border);
    border-radius: var(--ks-radius-xl);
  }
  .ks-table__table tbody td,
  .ks-table--comfy .ks-table__table tbody td {
    display: grid;
    grid-template-columns: minmax(calc(var(--ks-space-12) * 1.5), 38%) minmax(0, 1fr);
    gap: var(--ks-space-4);
    height: auto;
    max-width: none;
    padding: 0;
    border: 0;
    white-space: normal;
    overflow-wrap: anywhere;
    /* The desktop cell clips for its ellipsis; a card wraps instead, and clipping would cut the
       44px hit areas of the links inside it (70-touch.css). */
    overflow: visible;
    text-align: left;
  }
  .ks-table__table tbody td::before {
    content: attr(data-label);
    overflow-wrap: normal;
    font-family: var(--ks-font-sans);
    font-variant-numeric: normal;
    font-size: var(--ks-text-caption);
    line-height: var(--ks-lh-dense);
    font-weight: var(--ks-weight-semibold);
    letter-spacing: var(--ks-tracking-caps);
    text-transform: uppercase;
    color: var(--ks-text-muted);
  }
  .ks-table__table tbody td > * { justify-self: start; min-width: 0; max-width: 100%; }
  /* Icon label: a glyph column instead of the uppercase text. The text stays as the cell's
     accessible name (visually hidden, not removed), so nothing is lost to a screen reader. */
  .ks-table__table tbody td[data-icon] { grid-template-columns: var(--ksc-icon-md) minmax(0, 1fr); align-items: start; }
  .ks-table__table tbody td[data-icon]::before {
    position: absolute;
    width: var(--ks-border-w);
    height: var(--ks-border-w);
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  /* Short labels (NIP, ZUS, VAT): a narrow label column, and the icon rows use the same width so every
     value in the card starts on one line, without the 38% gap the long labels need. */
  .ks-table--short-labels .ks-table__table tbody td,
  .ks-table--short-labels .ks-table__table tbody td[data-icon] { grid-template-columns: var(--ks-space-10) minmax(0, 1fr); }
  /* A profile badge in a cell takes the icon form (see ProfileBadge) by itself at card-list width, so
     the server renders one markup for every width and needs no viewport knowledge. */
  .ks-table__table tbody td .ks-profile .ks-profile__badge {
    justify-content: center;
    width: calc(var(--ksc-icon-md) + var(--ks-space-4));
    height: calc(var(--ksc-icon-md) + var(--ks-space-4));
    padding: 0;
    background: transparent;
  }
  .ks-table__table tbody td .ks-profile--out .ks-profile__badge { background: var(--ks-status-neutral-bg); }
  .ks-table__table tbody td .ks-profile .ks-profile__label,
  .ks-table__table tbody td .ks-profile .ks-profile__reason {
    position: absolute;
    width: var(--ks-border-w);
    height: var(--ks-border-w);
    margin: calc(var(--ks-border-w) * -1);
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  /* ClientMarker's strip in a card: a 224px bubble does not fit a ~205px value column at 375px, and
     no left/right alignment on the item can fix that. The bubble anchors to the strip (stretched to
     the column) instead of the item, and is capped at the column's width, so it wraps rather than
     being cut. */
  .ks-table__table tbody td .ks-markers { position: relative; justify-self: stretch; }
  /* The name's own ellipsis clip is for the table proper; a card wraps it, and the clip would cut
     the link's 44px hit area (70-touch.css). */
  .ks-table__table tbody td:has(.ks-markers) > .ks-table__primary { overflow: visible; }
  .ks-table__table tbody td .ks-markers .ks-tooltip { position: static; }
  .ks-table__table tbody td .ks-markers .ks-tooltip__bubble {
    left: 0;
    transform: none;
    text-align: left;
    max-width: min(calc(var(--ks-space-12) * 3.5), 100%);
  }
  .ks-table__table tbody td[data-icon] > .ks-table__cellicon {
    display: block;
    width: var(--ksc-icon-md);
    height: var(--ksc-icon-md);
    margin-top: calc(var(--ks-space-1) / 2);
    color: var(--ks-text-muted);
  }
  .ks-table__table tbody td:not([data-label])::before,
  .ks-table__table tbody td[data-label=""]::before { content: none; }
  .ks-table__table tbody td:not([data-label]),
  .ks-table__table tbody td[data-label=""] { display: block; }
  .ks-table__table tbody td[data-primary] {
    display: block;
    font-size: var(--ks-text-small);
    line-height: var(--ks-lh-small);
  }
  .ks-table__table tbody td[data-primary]::before { content: none; }
  tbody .ks-table__select { position: absolute; padding: 0 !important; }
  /* Only the name moves aside for the checkbox; the rows under it use the card's full width. */
  .ks-table__table tbody tr:has(.ks-table__select) { position: relative; }
  .ks-table__table tbody tr:has(.ks-table__select) td[data-primary] { padding-left: var(--ks-space-9); }
  .ks-table__table tbody tr .ks-table__select { left: var(--ks-space-5); top: var(--ks-space-5); width: auto; }
  /* A cell holding a form or a copy block needs the whole card width, label above. */
  .ks-table__table tbody td:has(.ks-table__cellform),
  .ks-table__table tbody td:has(.ks-copy) { display: block; }
  .ks-table__table tbody td:has(.ks-table__cellform)::before,
  .ks-table__table tbody td:has(.ks-copy)::before { display: block; margin-bottom: var(--ks-space-2); }
  .ks-table__cellform { width: 100%; }
  .ks-table__cellform .ks-field { flex: 1 1 100%; width: auto; }
  .ks-table__cellform .ks-btn { width: 100%; justify-content: center; }
  .ks-table__cell--num { font-family: var(--ks-font-mono); }
  .ks-table__cell--actions { width: auto; }
  .ks-table__table tbody td.ks-table__state { display: block; padding: 0; }
  .ks-table__table tbody tr:has(.ks-table__state) { padding: 0; border: 0; background: transparent; }
  /* Group header row (DRAFT, see the FilterBar note above): a flush label, not a card. */
  .ks-table__table tbody td.ks-table__group { display: block; padding: var(--ks-space-3) var(--ks-space-1); }
  .ks-table__table tbody tr:has(.ks-table__group) { padding: 0; border: 0; background: transparent; }
  .ks-table__bulk { flex-wrap: wrap; border-radius: var(--ks-radius-lg); border-bottom: var(--ks-border-w) solid var(--ks-blue-200); }
}

/* ---- Inline form in a cell (save an issue number next to the row) ------------- */
.ks-table__cellform { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ks-space-4); margin: 0; }
.ks-table__cellform .ks-field { width: calc(var(--ks-space-12) * 2.5); }
.ks-table__cellform .ks-btn { flex: none; }

/* ---- Pager ------------------------------------------------------------------ */
.ks-pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ks-space-5);
  padding: calc(var(--ks-space-4) + var(--ks-space-1)) var(--ks-space-2) 0;
  font-size: var(--ks-text-dense);
  color: var(--ks-text-muted);
}
.ks-pager__nav { display: flex; align-items: center; gap: var(--ks-space-2); margin-left: auto; }
.ks-pager__page { padding: 0 var(--ks-space-4); color: var(--ks-text-default); }
.ks-pager__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--ksc-square-sm);
  height: var(--ksc-square-sm);
  background: var(--ks-surface-card);
  border: var(--ks-border-w) solid var(--ks-border-strong);
  border-radius: var(--ks-radius-md);
  color: var(--ks-text-default);
  cursor: pointer;
}
.ks-pager__btn:hover { background: var(--ks-surface-hover); color: var(--ks-text-strong); text-decoration: none; }
.ks-pager__btn .ks-icon { width: var(--ksc-icon-sm); height: var(--ksc-icon-sm); }
.ks-pager__btn:disabled,
.ks-pager__btn[aria-disabled="true"] { color: var(--ks-text-subtle); cursor: not-allowed; background: var(--ks-surface-card); }

/* ---- SkeletonRows ------------------------------------------------------------ */
.ks-skeleton {
  display: block;
  height: var(--ks-space-3);
  border-radius: var(--ks-radius-sm);
  background: linear-gradient(90deg, var(--ks-surface-sunken) 25%, var(--ks-gray-100) 37%, var(--ks-surface-sunken) 63%);
  background-size: 200% 100%;
  animation: ks-shimmer var(--ksc-shimmer) linear infinite;
}
[data-theme="dark"] .ks-skeleton {
  background-image: linear-gradient(90deg, var(--ks-surface-sunken) 25%, var(--ks-surface-hover) 37%, var(--ks-surface-sunken) 63%);
}
@media (prefers-color-scheme: dark) { :where(:root:not([data-ks-theme-fixed])):not([data-theme]) .ks-skeleton {
  background-image: linear-gradient(90deg, var(--ks-surface-sunken) 25%, var(--ks-surface-hover) 37%, var(--ks-surface-sunken) 63%);
} }
.ks-skeleton--head { height: var(--ks-space-4); opacity: 0.8; }
.ks-skeleton--block { height: calc(var(--ks-space-12) + var(--ks-space-6)); border-radius: var(--ks-radius-xl); }
.ks-skeleton--w20 { width: 20%; }
.ks-skeleton--w30 { width: 30%; }
.ks-skeleton--w40 { width: 40%; }
.ks-skeleton--w50 { width: 50%; }
.ks-skeleton--w60 { width: 60%; }
.ks-skeleton--w70 { width: 70%; }
.ks-skeleton--w80 { width: 80%; }
.ks-skeleton--w90 { width: 90%; }

.ks-skeleton-rows {
  background: var(--ks-surface-card);
  border: var(--ks-border-w) solid var(--ks-border);
  border-radius: var(--ks-radius-xl);
  overflow: hidden;
}
.ks-skeleton-rows__head,
.ks-skeleton-rows__row {
  display: grid;
  grid-template-columns: 26fr 18fr 14fr 16fr 12fr;
  gap: var(--ks-space-8);
  align-items: center;
  height: var(--ks-row-h);
  padding: 0 var(--ks-space-6);
  border-bottom: var(--ks-border-w) solid var(--ks-border);
}
.ks-skeleton-rows__head { height: calc(var(--ks-row-h) - var(--ks-space-2)); background: var(--ks-surface-sunken); }
.ks-skeleton-rows__row:last-child { border-bottom: 0; }

/* ---- FilterBar ------------------------------------------------------------- */
.ks-filterbar {
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-start;
  gap: var(--ks-space-4);
  margin: 0;
  padding: var(--ks-space-5) var(--ks-space-6);
  background: var(--ks-surface-card);
  border: var(--ks-border-w) solid var(--ks-border);
  border-bottom: 0;
  border-radius: var(--ks-radius-xl) var(--ks-radius-xl) 0 0;
}
.ks-filterbar--standalone { border-bottom: var(--ks-border-w) solid var(--ks-border); border-radius: var(--ks-radius-xl); }
/* Grupuj/Widok (__actions) stay put in the top-right corner: the outer row never wraps, so
   __actions can never be pushed to a line of its own. __filters is the one flex item allowed to
   shrink (flex: 1 1 auto, min-width: 0) and it wraps its own chips internally when they no longer
   fit — the chips grow a second (or third) line under the search field while search and __actions
   hold their position on the first line (founders 2026-09-29, reported against Klienci). */
.ks-filterbar__filters { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ks-space-4); flex: 1 1 auto; min-width: 0; }
.ks-filterbar__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ks-space-4); margin-left: auto; flex: 0 0 auto; }
.ks-filterbar__status { font-size: var(--ks-text-caption); color: var(--ks-text-muted); }
.ks-filterbar .htmx-indicator { display: none; }
.ks-filterbar .htmx-request .htmx-indicator,
.ks-filterbar.htmx-request .htmx-indicator { display: inline-flex; }
/* Medium (a tablet, or a narrow desktop window): search and __actions keep the first row, with
   __actions in the top-right corner, and __filters takes a full-width second row of its own.
   Squeezed into one row the search shrank to a few letters and the chips stacked one per line. */
@container ks-table (max-width: 900px) {
  .ks-filterbar { flex-wrap: wrap; }
  .ks-filterbar .ks-search { flex: 1 1 auto; }
  .ks-filterbar__filters { order: 3; flex: 1 1 100%; }
}
@media (max-width: 1100px) {
  .ks-filterbar--standalone { flex-wrap: wrap; }
  .ks-filterbar--standalone .ks-search { flex: 1 1 auto; }
  .ks-filterbar--standalone .ks-filterbar__filters { order: 3; flex: 1 1 100%; }
}
/* Phone: search, then __actions (each control a full line), then the chips, wrapping so every
   chip and "+ Dodaj filtr" stay in view (a sideways-scrolling row hid them past the edge). */
@container ks-table (max-width: 480px) {
  .ks-filterbar .ks-search { flex: 1 1 100%; width: 100%; }
  .ks-filterbar__actions { margin-left: 0; flex: 1 1 100%; min-width: 0; }
  .ks-filterbar__actions > * { flex: 1 1 auto; min-width: 0; }
}
@media (max-width: 480px) {
  .ks-filterbar--standalone .ks-search { flex: 1 1 100%; width: 100%; }
  .ks-filterbar--standalone .ks-filterbar__actions { margin-left: 0; flex: 1 1 100%; min-width: 0; }
  .ks-filterbar--standalone .ks-filterbar__actions > * { flex: 1 1 auto; min-width: 0; }
}

/* A compact <select> for a toolbar (group-by, saved view) that reads like a FilterChip: ONE bordered
   control with its label inside ("Grupuj  Brak  v"), same height/radius as the chips row. The label is
   part of the control, not a caption beside it, so it costs no extra width or a second line. The native
   <select> stays (works without JS, native picker on a phone) - it is only made transparent. */
.ks-toolbar-select {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--ks-space-3);
  height: var(--ks-control-h);
  padding-left: calc(var(--ks-space-4) + var(--ks-space-1));
  background: var(--ks-surface-card);
  border: var(--ks-border-w) solid var(--ks-border-strong);
  border-radius: var(--ks-radius-lg);
  color: var(--ks-text-muted);
  font-size: var(--ks-text-dense);
  transition: var(--ks-transition-control);
}
.ks-toolbar-select:hover { background: var(--ks-surface-hover); }
.ks-toolbar-select:has(:focus-visible) { outline: var(--ks-focus-w) solid var(--ks-focus-ring); outline-offset: var(--ks-focus-offset); }
.ks-toolbar-select__label { white-space: nowrap; }
.ks-toolbar-select__control { position: relative; display: inline-flex; align-items: center; align-self: stretch; }
.ks-toolbar-select__select {
  appearance: none;
  -webkit-appearance: none;
  height: 100%;
  padding: 0 calc(var(--ks-space-8) + var(--ks-space-1)) 0 0;
  background: transparent;
  border: 0;
  color: var(--ks-text-default);
  font-family: var(--ks-font-sans);
  font-size: var(--ks-text-dense);
  font-weight: var(--ks-weight-medium);
  cursor: pointer;
}
.ks-toolbar-select__select:focus-visible { outline: 0; }
.ks-toolbar-select__select option { color: var(--ks-text-default); background: var(--ks-surface-card); }
.ks-toolbar-select__chevron {
  position: absolute;
  right: var(--ks-space-3);
  width: var(--ksc-icon-xs);
  height: var(--ksc-icon-xs);
  color: var(--ks-text-muted);
  pointer-events: none;
}

/* ---- FilterChip -------------------------------------------------------------- */
.ks-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--ks-space-3);
  height: var(--ks-control-h);
  padding: 0 calc(var(--ks-space-4) + var(--ks-space-1));
  background: var(--ks-surface-card);
  border: var(--ks-border-w) solid var(--ks-border-strong);
  border-radius: var(--ks-radius-lg);
  color: var(--ks-text-default);
  font-family: var(--ks-font-sans);
  font-size: var(--ks-text-dense);
  white-space: nowrap;
  cursor: pointer;
  transition: var(--ks-transition-control);
}
button.ks-chip:hover,
.ks-chip__main:hover { background: var(--ks-surface-hover); }
.ks-chip__label { color: var(--ks-text-muted); }
.ks-chip__value { font-weight: var(--ks-weight-semibold); color: var(--ks-text-strong); }
.ks-chip__count {
  padding: 0 calc(var(--ks-space-2) + var(--ks-border-w));
  border-radius: var(--ks-radius-pill);
  background: var(--ks-surface-sunken);
  color: var(--ks-text-strong);
  font-size: var(--ks-text-caption);
  font-weight: var(--ks-weight-semibold);
}
.ks-chip .ks-icon { width: var(--ksc-icon-xs); height: var(--ksc-icon-xs); color: var(--ks-text-muted); }
.ks-chip[aria-expanded="true"] { border-color: var(--ks-focus-ring); }
.ks-chip[aria-expanded="true"] .ks-chip__caret,
.ks-chip__main[aria-expanded="true"] .ks-chip__caret { transform: rotate(180deg); }

/* Active chip: a group of two buttons (open menu · clear). */
.ks-chip[data-state="active"] {
  padding: 0;
  gap: 0;
  background: var(--ks-surface-selected);
  border-color: var(--ks-blue-200);
  color: var(--ks-text-link);
  cursor: default;
  overflow: hidden;
}
.ks-chip[data-state="active"] .ks-chip__label { color: var(--ks-text-link); }
.ks-chip[data-state="active"] .ks-chip__count { background: var(--ks-blue-200); color: var(--ks-navy-900); }
.ks-chip[data-state="active"] .ks-icon { color: var(--ks-text-link); }
.ks-chip__main,
.ks-chip__clear {
  display: inline-flex;
  align-items: center;
  gap: var(--ks-space-3);
  height: 100%;
  margin: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.ks-chip__main { padding: 0 var(--ks-space-2) 0 calc(var(--ks-space-4) + var(--ks-space-1)); }
.ks-chip__clear { padding: 0 var(--ks-space-4) 0 var(--ks-space-2); border-left: var(--ks-border-w) solid var(--ks-blue-200); }
.ks-chip__main:hover,
.ks-chip__clear:hover { background: var(--ks-action-secondary-bg-hover); }
.ks-chip__clear:hover { color: var(--ks-status-danger-fg); }
.ks-chip__main:focus-visible,
.ks-chip__clear:focus-visible { outline-offset: calc(var(--ks-focus-offset) * -1); }

/* Add a filter: opens a menu of not-yet-active dimensions, each item then opens
   that dimension's own menu (chained popovers). DRAFT, see the note above __views. */
.ks-chip--add { background: transparent; border-style: dashed; color: var(--ks-text-muted); }
.ks-chip--add:hover { background: var(--ks-surface-hover); border-color: var(--ks-border-strong); color: var(--ks-text-default); }
.ks-chip--add .ks-icon { color: inherit; }

/* ---- Menu (popover) ---------------------------------------------------------
   <div class="ks-menu" popover id="…"> … </div>, opened by popovertarget.    */
.ks-menu {
  min-width: calc(var(--ks-space-12) * 3.5);
  max-width: min(calc(var(--ks-space-12) * 6), calc(100vw - var(--ks-space-8)));
  margin: 0;
  padding: var(--ks-space-3);
  inset: auto;
  background: var(--ks-surface-card);
  color: var(--ks-text-default);
  border: var(--ks-border-w) solid var(--ks-border);
  border-radius: var(--ks-radius-lg);
  box-shadow: var(--ks-shadow-lg);
}
.ks-menu:popover-open { animation: ks-fade-in var(--ks-duration-fast) var(--ks-ease-out); }
/* Anchored under the invoker where CSS anchor positioning exists; ksiego.js
   positions it elsewhere; without either it opens centred (still usable). */
@supports (position-area: bottom) {
  .ks-menu[popover] {
    position-area: bottom span-right;
    position-try-fallbacks: flip-block, flip-inline;
    margin-top: var(--ks-space-3);
  }
  .ks-menu--end[popover] { position-area: bottom span-left; }
}
.ks-menu[data-positioned] {
  position: fixed;
  top: var(--ksc-pop-y, auto);
  left: var(--ksc-pop-x, auto);
}
.ks-menu__label {
  padding: var(--ks-space-2) var(--ks-space-4);
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-caption);
  font-weight: var(--ks-weight-semibold);
  letter-spacing: var(--ks-tracking-caps);
  text-transform: uppercase;
  color: var(--ks-text-muted);
}
/* A label that repeats its opener ("Dodaj filtr" under "+ Dodaj filtr", "Status ZUS" under the
   "Status ZUS" chip) is for screen readers only. It shows when the menu was reached from another
   menu (data-ks-via, set by ksiego.js): its opener then reads "Dodaj filtr", not the dimension. */
.ks-menu:not([data-ks-via]) > .ks-menu__label--opener {
  position: absolute;
  width: var(--ks-border-w);
  height: var(--ks-border-w);
  margin: calc(var(--ks-border-w) * -1);
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.ks-menu__item {
  display: flex;
  align-items: center;
  gap: var(--ks-space-4);
  width: 100%;
  min-height: var(--ks-control-h-sm);
  padding: var(--ks-space-3) var(--ks-space-4);
  border: 0;
  border-radius: var(--ks-radius-md);
  background: transparent;
  color: var(--ks-text-default);
  font-family: var(--ks-font-sans);
  font-size: var(--ks-text-dense);
  font-weight: var(--ks-weight-regular);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.ks-menu__item:hover { background: var(--ks-surface-hover); color: var(--ks-text-strong); text-decoration: none; }
.ks-menu__item[aria-checked="true"],
.ks-menu__item[aria-current="true"],
.ks-menu__item[aria-selected="true"],
.ks-menu__item:has(:checked) { background: var(--ks-surface-selected); color: var(--ks-text-strong); }
.ks-menu__item:focus-visible { outline-offset: calc(var(--ks-focus-offset) * -1); }
.ks-menu__item .ks-icon { width: var(--ksc-icon-sm); height: var(--ksc-icon-sm); color: var(--ks-text-muted); }
.ks-menu__item input { margin: 0; }
/* Disabled item: not offered yet (e.g. no page behind it). Drop href/leave off `disabled`
   so it isn't a real control (see Pager, Tabs, SideNav) — aria-disabled + inert styling only. */
.ks-menu__item[aria-disabled="true"] { color: var(--ks-text-subtle); cursor: not-allowed; }
.ks-menu__item[aria-disabled="true"] .ks-icon { color: var(--ks-text-subtle); }
.ks-menu__item[aria-disabled="true"]:hover,
.ks-menu__item[aria-disabled="true"]:focus-visible { background: transparent; color: var(--ks-text-subtle); }
.ks-menu__sep { height: 0; margin: var(--ks-space-2) 0; border: 0; border-top: var(--ks-border-w) solid var(--ks-border); }
/* A menu item with its own destructive control beside it (a saved view's "Usuń").
   __remove is not .ks-menu__item, so ksiego.js's ↑/↓ roving skips it - Tab reaches
   it as the next stop after its item instead. */
.ks-menu__row { display: flex; align-items: center; gap: var(--ks-space-1); }
.ks-menu__row > .ks-menu__item { flex: 1 1 auto; min-width: 0; }
.ks-menu__remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--ks-control-h-sm);
  height: var(--ks-control-h-sm);
  padding: 0;
  border: 0;
  border-radius: var(--ks-radius-md);
  background: transparent;
  color: var(--ks-text-muted);
  cursor: pointer;
}
.ks-menu__remove:hover { background: var(--ks-surface-hover); color: var(--ks-status-danger-fg); }
.ks-menu__remove:focus-visible { outline-offset: calc(var(--ks-focus-offset) * -1); }
.ks-menu__remove .ks-icon { width: var(--ksc-icon-xs); height: var(--ksc-icon-xs); color: inherit; }
.ks-menu__footer {
  display: flex;
  align-items: center;
  gap: var(--ks-space-4);
  margin-top: var(--ks-space-2);
  padding: var(--ks-space-3) var(--ks-space-4) var(--ks-space-1);
  border-top: var(--ks-border-w) solid var(--ks-border);
  font-size: var(--ks-text-dense);
}

/* ---- css/src/30-feedback.css ---- */
/* ==========================================================================
   30 · Feedback — StatusBadge, Toast, ToastStack, Modal, EmptyState,
   ServiceErrorBanner
   ========================================================================== */

/* ---- StatusBadge -------------------------------------------------------------
   Every tone carries a glyph or a word — status is never colour-only.       */
.ks-badge {
  --ksc-badge-fg: var(--ks-status-neutral-fg);
  --ksc-badge-bg: var(--ks-status-neutral-bg);
  display: inline-flex;
  align-items: center;
  gap: calc(var(--ks-space-2) + var(--ks-border-w));
  max-width: 100%;
  padding: calc(var(--ks-space-1) + var(--ks-border-w)) calc(var(--ks-space-4) + var(--ks-border-w));
  border: var(--ks-border-w) solid transparent;
  border-radius: var(--ks-radius-pill);
  background: var(--ksc-badge-bg);
  color: var(--ksc-badge-fg);
  font-size: var(--ks-text-dense);
  line-height: var(--ks-lh-dense);
  font-weight: var(--ks-weight-medium);
  white-space: nowrap;
  vertical-align: middle;
}
.ks-badge .ks-icon { width: calc(var(--ksc-icon-xs) + var(--ks-border-w)); height: calc(var(--ksc-icon-xs) + var(--ks-border-w)); }
.ks-badge__text { overflow: hidden; text-overflow: ellipsis; }
.ks-badge__pl { font-weight: var(--ks-weight-regular); opacity: 0.85; }
/* A badge may be the whole link (invoice list -> reconciliation report). */
a.ks-badge { text-decoration: none; }
a.ks-badge:hover { text-decoration: underline; }
a.ks-badge:focus-visible { outline: var(--ks-focus-w) solid var(--ks-focus-ring); outline-offset: var(--ks-focus-offset); }
.ks-badge--sm {
  gap: var(--ks-space-2);
  padding: 0 calc(var(--ks-space-3) + var(--ks-border-w));
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-caption);
}
.ks-badge--sm .ks-icon { width: var(--ksc-icon-xs); height: var(--ksc-icon-xs); }
.ks-badge--outline { background: transparent; border-color: currentColor; }

.ks-badge--neutral  { --ksc-badge-fg: var(--ks-status-neutral-fg);  --ksc-badge-bg: var(--ks-status-neutral-bg); }
.ks-badge--info     { --ksc-badge-fg: var(--ks-status-info-fg);     --ksc-badge-bg: var(--ks-status-info-bg); }
.ks-badge--success  { --ksc-badge-fg: var(--ks-status-success-fg);  --ksc-badge-bg: var(--ks-status-success-bg); }
.ks-badge--warning  { --ksc-badge-fg: var(--ks-status-warning-fg);  --ksc-badge-bg: var(--ks-status-warning-bg); }
.ks-badge--danger   { --ksc-badge-fg: var(--ks-status-danger-fg);   --ksc-badge-bg: var(--ks-status-danger-bg); }
.ks-badge--progress { --ksc-badge-fg: var(--ks-status-progress-fg); --ksc-badge-bg: var(--ks-status-progress-bg); }
/* Draft: neutral text on the sunken fill (muted text there misses 4.5:1 in light). */
.ks-badge--draft    { --ksc-badge-fg: var(--ks-status-neutral-fg);  --ksc-badge-bg: var(--ks-surface-sunken); }

/* Counter pill (nav, tabs) */
.ks-count {
  display: inline-block;
  min-width: var(--ks-space-7);
  padding: 0 var(--ks-space-3);
  border-radius: var(--ks-radius-pill);
  background: var(--ks-surface-sunken);
  color: var(--ks-text-strong);
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-caption);
  font-weight: var(--ks-weight-semibold);
  text-align: center;
}

/* ---- Toast ------------------------------------------------------------------ */
.ks-toast {
  --ksc-toast-fg: var(--ks-status-success-fg);
  --ksc-toast-bg: var(--ks-status-success-bg);
  display: flex;
  align-items: flex-start;
  gap: var(--ks-space-5);
  width: calc(var(--ks-space-10) * 9.5);                 /* 380px */
  max-width: 100%;
  padding: var(--ks-space-5) calc(var(--ks-space-5) + var(--ks-space-1));
  background: var(--ks-surface-card);
  border: var(--ks-border-w) solid var(--ks-border);
  border-radius: var(--ks-radius-xl);
  box-shadow: var(--ks-shadow-lg);
  animation: ks-toast-in var(--ks-duration-base) var(--ks-ease-out);
}
.ks-toast--full { width: 100%; }
.ks-toast--success { --ksc-toast-fg: var(--ks-status-success-fg); --ksc-toast-bg: var(--ks-status-success-bg); }
.ks-toast--warning { --ksc-toast-fg: var(--ks-status-warning-fg); --ksc-toast-bg: var(--ks-status-warning-bg); }
.ks-toast--danger  { --ksc-toast-fg: var(--ks-status-danger-fg);  --ksc-toast-bg: var(--ks-status-danger-bg); }
.ks-toast--info    { --ksc-toast-fg: var(--ks-status-info-fg);    --ksc-toast-bg: var(--ks-status-info-bg); }
.ks-toast__glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--ks-control-h-sm);
  height: var(--ks-control-h-sm);
  border-radius: 50%;
  background: var(--ksc-toast-bg);
  color: var(--ksc-toast-fg);
}
.ks-toast__glyph .ks-icon { width: var(--ksc-icon-md); height: var(--ksc-icon-md); }
.ks-toast__body { display: flex; flex-direction: column; gap: var(--ks-space-1); flex: 1; min-width: 0; }
.ks-toast__title { margin: 0; font-size: var(--ks-text-small); line-height: var(--ks-lh-small); font-weight: var(--ks-weight-semibold); color: var(--ks-text-strong); }
.ks-toast__text { margin: 0; font-size: var(--ks-text-dense); line-height: var(--ks-lh-dense); color: var(--ks-text-muted); }
.ks-toast__action { margin-top: var(--ks-space-3); }
.ks-toast__close {
  display: inline-flex;
  flex: none;
  margin: calc(var(--ks-space-1) * -1) calc(var(--ks-space-1) * -1) 0 0;
  padding: var(--ks-space-1);
  border: 0;
  border-radius: var(--ks-radius-sm);
  background: transparent;
  color: var(--ks-text-muted);
  cursor: pointer;
}
.ks-toast__close:hover { background: var(--ks-surface-hover); color: var(--ks-text-strong); }
.ks-toast__close .ks-icon { width: var(--ksc-icon-md); height: var(--ksc-icon-md); }
.ks-toast[data-state="closing"] { opacity: 0; transform: translateY(var(--ks-space-4)); transition: opacity var(--ks-duration-base) var(--ks-ease-standard), transform var(--ks-duration-base) var(--ks-ease-standard); }

/* ---- ToastStack -------------------------------------------------------------- */
.ks-toast-stack {
  position: fixed;
  right: var(--ks-space-7);
  bottom: var(--ks-space-7);
  z-index: 80;
  display: flex;
  flex-direction: column;
  gap: calc(var(--ks-space-4) + var(--ks-space-1));
  max-width: calc(100vw - var(--ks-space-9));
  pointer-events: none;
}
.ks-toast-stack > * { pointer-events: auto; }
.ks-toast-stack--top-right { top: var(--ks-space-7); bottom: auto; }
.ks-toast-stack--top-center { top: var(--ks-space-7); bottom: auto; right: auto; left: 50%; transform: translateX(-50%); }
.ks-toast-stack--inline { position: static; transform: none; max-width: none; }
.ks-toast-stack:empty { display: none; }
@media (max-width: 480px) {
  .ks-toast-stack { left: var(--ks-space-5); right: var(--ks-space-5); bottom: var(--ks-space-5); transform: none; }
  .ks-toast-stack .ks-toast { width: 100%; }
}

/* ---- CopyBlock (details/summary + optional Kopiuj button) ---------------------
   Server-rendered text a user must hand to another system (issue body, KSeF id).
   Works without JavaScript: <details> opens and the text stays selectable. */
.ks-copy {
  border: var(--ks-border-w) solid var(--ks-border);
  border-radius: var(--ks-radius-lg);
  background: var(--ks-surface-card);
}
.ks-copy__summary {
  display: flex;
  align-items: center;
  gap: var(--ks-space-3);
  padding: var(--ks-space-4) var(--ks-space-5);
  border-radius: inherit;
  color: var(--ks-text-link);
  font-size: var(--ks-text-dense);
  line-height: var(--ks-lh-dense);
  font-weight: var(--ks-weight-medium);
  cursor: pointer;
  list-style: none;
}
.ks-copy__summary::-webkit-details-marker { display: none; }
.ks-copy__summary:hover { background: var(--ks-surface-hover); }
.ks-copy__summary:focus-visible { outline: var(--ks-focus-w) solid var(--ks-focus-ring); outline-offset: calc(var(--ks-focus-offset) * -1); }
.ks-copy__summary .ks-icon { width: var(--ksc-icon-sm); height: var(--ksc-icon-sm); color: var(--ks-text-muted); transition: var(--ks-transition-control); }
.ks-copy[open] > .ks-copy__summary { border-bottom: var(--ks-border-w) solid var(--ks-border); border-end-start-radius: 0; border-end-end-radius: 0; }
.ks-copy[open] > .ks-copy__summary .ks-copy__caret { transform: rotate(180deg); }
.ks-copy__body { display: flex; flex-direction: column; gap: var(--ks-space-4); padding: var(--ks-space-5); }
/* position: relative so this scroller is the containing block for what it scrolls: without
   it an absolutely positioned descendant escapes the clip and stretches the page (2026-09-25). */
.ks-copy__text {
  position: relative;
  margin: 0;
  max-height: calc(var(--ks-space-12) * 4);
  overflow: auto;
  padding: var(--ks-space-5);
  background: var(--ks-surface-sunken);
  border: var(--ks-border-w) solid var(--ks-border);
  border-radius: var(--ks-radius-md);
  font-family: var(--ks-font-mono);
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-small);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  color: var(--ks-text-default);
  -webkit-user-select: all;
  user-select: all;
}
.ks-copy__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ks-space-4); }
.ks-copy__hint { font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); color: var(--ks-text-muted); }
/* The button is server-rendered hidden; ksiego.js reveals it when the clipboard works. */
.ks-copy__btn .ks-copy__done { display: none; }
.ks-copy__btn[data-state="copied"] { color: var(--ks-status-success-fg); border-color: var(--ks-status-success-fg); }
.ks-copy__btn[data-state="copied"] .ks-copy__label { display: none; }
.ks-copy__btn[data-state="copied"] .ks-copy__done { display: inline; }

/* ---- Drawer (side sheet on a native <dialog>) ---------------------------------
   Opens from the right edge with showModal(): focus stays inside, Esc closes,
   the page behind is inert. Full width on phones. */
.ks-drawer {
  width: calc(var(--ks-space-10) * 11);                 /* 440px */
  max-width: 100vw;
  height: 100dvh;
  max-height: 100dvh;
  margin: 0 0 0 auto;
  padding: 0;
  border: 0;
  border-left: var(--ks-border-w) solid var(--ks-border);
  background: var(--ks-surface-card);
  color: var(--ks-text-default);
  box-shadow: var(--ks-shadow-modal);
  overflow: hidden;
}
.ks-drawer[open] { display: flex; flex-direction: column; animation: ks-drawer-in var(--ks-duration-base) var(--ks-ease-out); }
.ks-drawer::backdrop { background: var(--ksc-overlay); backdrop-filter: blur(var(--ksc-overlay-blur)); }
.ks-drawer__header {
  display: flex;
  align-items: flex-start;
  gap: var(--ks-space-5);
  padding: var(--ks-space-6) var(--ks-space-6) var(--ks-space-5) var(--ks-space-7);
  border-bottom: var(--ks-border-w) solid var(--ks-border);
}
.ks-drawer__heading { display: flex; flex-direction: column; gap: var(--ks-space-1); flex: 1; min-width: 0; }
.ks-drawer__title { margin: 0; font-size: var(--ks-text-h4); line-height: var(--ks-lh-h4); font-weight: var(--ks-weight-h4); color: var(--ks-text-strong); }
.ks-drawer__subtitle { margin: 0; font-size: var(--ks-text-small); line-height: var(--ks-lh-small); color: var(--ks-text-muted); }
.ks-drawer__tools {
  display: flex;
  flex-direction: column;
  gap: var(--ks-space-3);
  padding: var(--ks-space-5) var(--ks-space-7);
  border-bottom: var(--ks-border-w) solid var(--ks-border);
}
.ks-drawer__status { margin: 0; font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); color: var(--ks-text-muted); }
/* position: relative so this scroller is the containing block for what it scrolls: without
   it an absolutely positioned descendant escapes the clip and stretches the page (2026-09-25). */
.ks-drawer__body { position: relative; flex: 1; min-height: 0; overflow-y: auto; padding: var(--ks-space-5) var(--ks-space-5) var(--ks-space-7); }
.ks-drawer__footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ks-space-4);
  padding: var(--ks-space-5) var(--ks-space-7);
  border-top: var(--ks-border-w) solid var(--ks-border);
  background: var(--ks-surface-sunken);
}
.ks-drawer__footer form { margin: 0; }
@media (max-width: 480px) {
  .ks-drawer { width: 100vw; border-left: 0; }
}
/* In-flow rendering for documentation and for the no-JS fallback page. */
.ks-drawer--static {
  position: static;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 100%;
  height: auto;
  max-height: none;
  margin: 0;
  border: var(--ks-border-w) solid var(--ks-border);
  border-radius: var(--ks-radius-xl);
  box-shadow: var(--ks-shadow-sm);
  animation: none;
}
.ks-drawer--static .ks-drawer__footer { border-radius: 0 0 var(--ks-radius-xl) var(--ks-radius-xl); }

/* ---- Modal (native <dialog>) ------------------------------------------------ */
.ks-modal {
  width: calc(var(--ks-space-10) * 14);                 /* 560px */
  max-width: calc(100vw - var(--ks-space-8) * 2);
  max-height: calc(100dvh - var(--ks-space-8) * 2);
  margin: auto;
  padding: 0;
  border: 0;
  border-radius: var(--ks-radius-2xl);
  background: var(--ks-surface-card);
  color: var(--ks-text-default);
  box-shadow: var(--ks-shadow-modal);
  overflow: hidden;
}
.ks-modal[open] { display: flex; flex-direction: column; animation: ks-fade-in var(--ks-duration-fast) var(--ks-ease-out); }
/* No script (js/ksiego.js blocked or failed): a dialog htmx inserted with data-ks-open would stay
   closed, because only the script opens it. Without data-ks-js on <html> it is shown over the
   page instead, so its form is still reachable and submits as usual. */
:root:not([data-ks-js]) .ks-modal[data-ks-open]:not([open]) {
  display: flex;
  flex-direction: column;
  position: fixed;
  inset: 0;
  z-index: 70;
  height: fit-content;
  box-shadow: var(--ks-shadow-lg), 0 0 0 100vmax var(--ksc-overlay);
}
.ks-modal::backdrop {
  background: var(--ksc-overlay);
  backdrop-filter: blur(var(--ksc-overlay-blur));
}
.ks-modal--sm { width: calc(var(--ks-space-10) * 11.5); }  /* 460px */
.ks-modal--lg { width: calc(var(--ks-space-10) * 18); }    /* 720px */
.ks-modal--warning { border-top: calc(var(--ks-border-w) * 3) solid var(--ks-amber-500); }
.ks-modal--danger { border-top: calc(var(--ks-border-w) * 3) solid var(--ks-red-600); }
.ks-modal__form { display: flex; flex-direction: column; min-height: 0; margin: 0; }
.ks-modal__header {
  display: flex;
  align-items: flex-start;
  gap: var(--ks-space-6);
  padding: calc(var(--ks-space-6) + var(--ks-space-1)) var(--ks-space-7) calc(var(--ks-space-5) + var(--ks-space-1));
  border-bottom: var(--ks-border-w) solid var(--ks-border);
}
.ks-modal__heading { flex: 1; min-width: 0; }
.ks-modal__title { font-size: var(--ks-text-h4); line-height: var(--ks-lh-h4); }
.ks-modal__subtitle { margin-top: var(--ks-space-2); font-size: var(--ks-text-small); line-height: var(--ks-lh-small); color: var(--ks-text-muted); }
.ks-modal__close {
  display: inline-flex;
  flex: none;
  padding: var(--ks-space-2);
  border: 0;
  border-radius: var(--ks-radius-md);
  background: transparent;
  color: var(--ks-text-muted);
  cursor: pointer;
}
.ks-modal__close:hover { background: var(--ks-surface-hover); color: var(--ks-text-strong); }
/* position: relative so this scroller is the containing block for what it scrolls: without
   it an absolutely positioned descendant escapes the clip and stretches the page (2026-09-25). */
.ks-modal__body {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--ks-space-6);
  padding: calc(var(--ks-space-6) + var(--ks-space-1)) var(--ks-space-7);
  overflow-y: auto;
  font-size: var(--ks-text-small);
  line-height: var(--ks-lh-small);
  color: var(--ks-text-default);
}
.ks-modal__footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--ks-space-4);
  padding: calc(var(--ks-space-5) + var(--ks-space-1)) var(--ks-space-7);
  border-top: var(--ks-border-w) solid var(--ks-border);
  background: var(--ks-surface-sunken);
}
/* Static rendering for documentation: an always-open, in-flow dialog. */
.ks-modal--static { position: static; display: flex; flex-direction: column; margin: 0; max-width: 100%; }

/* ---- EmptyState -------------------------------------------------------------- */
.ks-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--ks-space-4) + var(--ks-space-1));
  padding: var(--ks-space-11) var(--ks-space-8);
  text-align: center;
  background: var(--ks-surface-card);
  border: var(--ks-border-w) dashed var(--ks-border-strong);
  border-radius: var(--ks-radius-xl);
}
.ks-empty--compact { padding: calc(var(--ks-space-9) - var(--ks-space-2)) var(--ks-space-7); }
.ks-empty--plain { border: 0; background: transparent; }
.ks-empty__icon { width: var(--ks-control-h-lg); height: var(--ks-control-h-lg); }
.ks-empty__icon .ks-icon { width: calc(var(--ks-space-7) + var(--ks-space-1)); height: calc(var(--ks-space-7) + var(--ks-space-1)); }
.ks-empty__title {
  margin: 0;
  font-size: var(--ks-text-body);
  line-height: var(--ks-lh-body);
  font-weight: var(--ks-weight-semibold);
  letter-spacing: var(--ks-tracking-normal);
  color: var(--ks-text-strong);
}
.ks-empty__text {
  max-width: calc(var(--ks-space-10) * 10.5);
  font-size: var(--ks-text-small);
  line-height: var(--ks-lh-small);
  color: var(--ks-text-muted);
}
.ks-empty__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--ks-space-4); margin-top: var(--ks-space-2); }
.ks-empty--danger .ks-icon-tile { background: var(--ks-status-danger-bg); color: var(--ks-status-danger-fg); }

/* ---- ServiceErrorBanner ------------------------------------------------------- */
.ks-banner {
  --ksc-banner-fg: var(--ks-status-danger-fg);
  --ksc-banner-bg: var(--ks-status-danger-bg);
  --ksc-banner-edge: var(--ksc-edge-danger);
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--ks-space-5);
  padding: var(--ks-space-5) calc(var(--ks-space-5) + var(--ks-space-1));
  background: var(--ksc-banner-bg);
  border: var(--ks-border-w) solid var(--ksc-banner-edge);
  border-radius: var(--ks-radius-xl);
}
.ks-banner--warning { --ksc-banner-fg: var(--ks-status-warning-fg); --ksc-banner-bg: var(--ks-status-warning-bg); --ksc-banner-edge: var(--ksc-edge-warning); }
.ks-banner--info { --ksc-banner-fg: var(--ks-status-info-fg); --ksc-banner-bg: var(--ks-status-info-bg); --ksc-banner-edge: var(--ksc-edge-info); }
.ks-banner--success { --ksc-banner-fg: var(--ks-status-success-fg); --ksc-banner-bg: var(--ks-status-success-bg); --ksc-banner-edge: var(--ksc-edge-success); }
.ks-banner--compact { padding: calc(var(--ks-space-5) - var(--ks-space-1)) var(--ks-space-5); border-radius: var(--ks-radius-lg); }
.ks-banner__icon { flex: none; margin-top: var(--ks-border-w); color: var(--ksc-banner-fg); }
.ks-banner__body { display: flex; flex-direction: column; gap: var(--ks-border-w); flex: 1; min-width: calc(var(--ks-space-12) * 3); }
.ks-banner__title {
  margin: 0;
  font-size: var(--ks-text-small);
  line-height: var(--ks-lh-small);
  font-weight: var(--ks-weight-semibold);
  letter-spacing: var(--ks-tracking-normal);
  color: var(--ksc-banner-fg);
}
.ks-banner__service {
  display: inline-block;
  margin-right: var(--ks-space-3);
  padding: var(--ks-border-w) calc(var(--ks-space-2) + var(--ks-border-w));
  border-radius: var(--ks-radius-xs);
  background: var(--ksc-chip-on-tint);
  font-family: var(--ks-font-mono);
  font-size: var(--ks-text-dense);
}
.ks-banner__text { margin: 0; font-size: var(--ks-text-dense); line-height: var(--ks-lh-dense); color: var(--ks-text-default); }
.ks-banner__meta { margin: 0; font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); color: var(--ks-text-muted); }
.ks-banner__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ks-space-4); flex: none; }

/* ---- Tooltip ------------------------------------------------------------------
   Replaces the browser's native title= wherever an icon carries meaning a sighted
   person cannot get any other way (a compact icon-only button, a status icon with
   no visible words). The wrapper adds no accessible relationship: the bubble is
   `aria-hidden`, because the text it shows is already in the page for a screen
   reader — the trigger's own accessible name (an icon button's visually-hidden
   label) or a sibling visually-hidden span (ClientMarker, ProfileBadge's icon
   form). Tooltip is a purely visual echo of text that already exists, shown to a
   mouse on hover, to a keyboard on focus, and to a touch screen on tap (the one
   thing title= could never do) — see js/ksiego.js "Tooltip" for the tap handling;
   hover and focus work from this file alone. */
.ks-tooltip { position: relative; display: inline-flex; }
.ks-tooltip__bubble {
  position: absolute;
  z-index: 60;
  bottom: calc(100% + var(--ks-space-2));
  left: 50%;
  transform: translateX(-50%);
  width: max-content;
  max-width: calc(var(--ks-space-12) * 3.5);
  padding: var(--ks-space-2) var(--ks-space-3);
  background: var(--ks-surface-inverse);
  color: var(--ks-text-inverse);
  border-radius: var(--ks-radius-md);
  box-shadow: var(--ks-shadow-md);
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-caption);
  text-align: center;
  white-space: normal;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--ks-duration-fast) var(--ks-ease-standard);
}
.ks-tooltip:hover .ks-tooltip__bubble,
.ks-tooltip:focus-within .ks-tooltip__bubble,
.ks-tooltip[data-tooltip-open] .ks-tooltip__bubble {
  opacity: 1;
  transition-delay: var(--ks-duration-slow);
}
/* Above the invoker by default; a caller near the top of a clipping container (the first
   table row under a sticky <thead>, a page header) asks for below instead - the same bubble,
   no second component. */
.ks-tooltip--below .ks-tooltip__bubble { bottom: auto; top: calc(100% + var(--ks-space-2)); }
/* Centred on the invoker by default, which overflows the LEFT edge of a clipping container
   (.ks-table__scroll's overflow-x: auto, .ks-app__main's overflow-y: auto) when the invoker
   sits near that edge. --start aligns the bubble's own left edge to the invoker's instead;
   ClientMarker gives every item in the strip --start unconditionally (see its own Do) because
   how many items actually clip is a property of wherever the strip is mounted, not of the strip
   itself, and the strip's own right-edge slack makes left-aligning free everywhere it is used. */
.ks-tooltip--start .ks-tooltip__bubble { left: 0; transform: none; text-align: left; }

/* ---- css/src/40-domain.css ---- */
/* ==========================================================================
   40 · Domain (PL regulatory) — PolishTerm, NipField, RegistrySourceTag,
   RegistryField, RegistryBlock, EffectivePeriods, AuditTimeline, StepList,
   DelegationStatus, ProfileBadge, EditConflict
   ========================================================================== */

/* ---- PolishTerm ---------------------------------------------------------------
   Translation first, Polish original attached. Three permitted forms.
   Inline form writes the parentheses in the markup: (Ulga na start).        */
.ks-term { font-size: inherit; }
.ks-term__pl { color: var(--ks-text-muted); white-space: nowrap; }
.ks-term--small { font-size: var(--ks-text-small); line-height: var(--ks-lh-small); }
.ks-term--dense { font-size: var(--ks-text-dense); line-height: var(--ks-lh-dense); }
.ks-term[title] { text-decoration: underline dotted var(--ks-text-muted); text-underline-offset: var(--ks-space-1); cursor: help; }

.ks-term--stacked { display: inline-flex; flex-direction: column; line-height: var(--ks-lh-dense); }
.ks-term--stacked .ks-term__pl { font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); white-space: normal; }

.ks-term--chip {
  display: inline-flex;
  align-items: baseline;
  gap: calc(var(--ks-space-2) + var(--ks-border-w));
  padding: var(--ks-space-1) var(--ks-space-4);
  background: var(--ks-surface-section);
  border: var(--ks-border-w) solid var(--ks-blue-200);
  border-radius: var(--ks-radius-pill);
  font-size: var(--ks-text-dense);
  line-height: var(--ks-lh-dense);
}
[data-theme="dark"] .ks-term--chip { border-color: var(--ks-registry-border); }
@media (prefers-color-scheme: dark) { :where(:root:not([data-ks-theme-fixed])):not([data-theme]) .ks-term--chip { border-color: var(--ks-registry-border); } }
.ks-term--chip .ks-term__tr { color: var(--ks-text-strong); font-weight: var(--ks-weight-medium); }
.ks-term--chip .ks-term__pl { color: var(--ks-text-link); }

/* ---- NipField ------------------------------------------------------------------
   An Input + checksum state on data-state="idle|checking|valid|invalid".     */
.ks-nip { display: flex; flex-direction: column; gap: var(--ks-space-4); min-width: 0; }
.ks-nip__row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--ks-space-4); }
/* Align the lookup button with the input, not with the hint below it. */
.ks-nip__row > .ks-nip__lookup { margin-top: calc(var(--ks-lh-small) + var(--ks-space-3)); }
.ks-nip__row > .ks-field { flex: 1; min-width: calc(var(--ks-space-12) * 3); }
.ks-nip__state { display: none; }
.ks-nip[data-state="checking"] .ks-nip__state--checking,
.ks-nip[data-state="valid"] .ks-nip__state--valid,
.ks-nip[data-state="invalid"] .ks-nip__state--invalid { display: inline-block; }
.ks-nip__state--checking { color: var(--ks-text-muted); animation: ks-spin var(--ksc-spin) linear infinite; }
.ks-nip__state--valid { color: var(--ks-status-success-fg); }
.ks-nip__state--invalid { color: var(--ks-status-danger-fg); }
/* Messages: the hint shows while idle, the error only when invalid. */
.ks-nip .ks-field__error { display: none; }
.ks-nip[data-state="invalid"] .ks-field__error { display: flex; }
.ks-nip[data-state="invalid"] .ks-nip__hint,
.ks-nip[data-state="valid"] .ks-nip__hint { display: none; }
.ks-nip[data-state="invalid"] .ks-field__control { border-color: var(--ks-status-danger-fg); }
.ks-nip[data-state="valid"] .ks-field__control { border-color: var(--ks-status-success-fg); }
.ks-nip__lookup:disabled { cursor: not-allowed; }
/* Ten bare digits with no hyphens (founders' decision) are harder to proof-read by eye than
   four grouped ones; a little letter-spacing on top of the mono font's own tabular figures
   is the whole mitigation - it costs no markup, since every place a NIP appears already
   carries one of these hooks. Reuses --ks-tracking-caps (not about caps here, just the
   system's one "a bit of extra room between characters" value) rather than add a token
   for one digit-only use. */
input[data-ks-nip],
.ks-clientbar__nip,
.ks-clientswitcher__nip,
.ks-clientswitcher__option-nip,
.ks-clientpicker__option-nip,
td[data-label="NIP"] { letter-spacing: var(--ks-tracking-caps); }

.ks-notice {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: calc(var(--ks-space-4) + var(--ks-space-1));
  padding: calc(var(--ks-space-4) + var(--ks-border-w)) var(--ks-space-5);
  background: var(--ks-status-info-bg);
  border: var(--ks-border-w) solid var(--ksc-edge-info);
  border-radius: var(--ks-radius-lg);
  font-size: var(--ks-text-dense);
  line-height: var(--ks-lh-dense);
  color: var(--ks-text-default);
}
.ks-notice > .ks-icon { width: var(--ksc-icon-md); height: var(--ksc-icon-md); color: var(--ks-text-link); }
.ks-notice__text { flex: 1; min-width: calc(var(--ks-space-12) * 2.5); }
.ks-notice strong { color: var(--ks-text-strong); }
.ks-notice--warning { background: var(--ks-status-warning-bg); border-color: var(--ksc-edge-warning); }
.ks-notice--warning > .ks-icon { color: var(--ks-status-warning-fg); }

/* ---- RegistrySourceTag ------------------------------------------------------------ */
.ks-source {
  display: inline-flex;
  align-items: center;
  gap: var(--ks-space-2);
  padding: 0 calc(var(--ks-space-3) + var(--ks-border-w));
  background: var(--ks-registry-bg);
  border: var(--ks-border-w) solid var(--ks-registry-border);
  border-radius: var(--ks-radius-pill);
  color: var(--ks-registry-fg);
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-caption);
  font-weight: var(--ks-weight-medium);
  white-space: nowrap;
}
.ks-source .ks-icon { width: calc(var(--ksc-icon-xs) - var(--ks-border-w)); height: calc(var(--ksc-icon-xs) - var(--ks-border-w)); }
.ks-source--manual { background: var(--ks-manual-bg); border-color: transparent; color: var(--ks-manual-fg); }
.ks-source--unverified { background: var(--ks-status-warning-bg); border-color: transparent; color: var(--ks-status-warning-fg); }

/* ---- RegistryField -------------------------------------------------------------- */
.ks-regfield {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--ks-space-2);
  padding: var(--ks-space-4) var(--ks-space-5);
  background: var(--ks-registry-bg);
  border: var(--ks-border-w) solid var(--ks-registry-border);
  border-radius: var(--ks-radius-lg);
  min-width: 0;
}
.ks-regfield--manual,
.ks-regfield--unverified { background: var(--ks-surface-card); border-color: var(--ks-border); }
.ks-regfield__label { margin: 0; }
.ks-regfield__value {
  margin: 0;
  font-size: var(--ks-text-small);
  line-height: var(--ks-lh-small);
  font-weight: var(--ks-weight-medium);
  color: var(--ks-text-strong);
  overflow-wrap: anywhere;
}
.ks-regfield__value--mono { font-family: var(--ks-font-mono); }

/* ---- RegistryBlock -------------------------------------------------------------- */
.ks-regblock {
  display: flex;
  flex-direction: column;
  gap: var(--ks-space-5);
  padding: var(--ks-space-6);
  background: var(--ks-surface-card);
  border: var(--ks-border-w) solid var(--ks-registry-border);
  border-radius: var(--ks-radius-xl);
}
.ks-regblock__header { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ks-space-4); }
.ks-regblock__header > .ks-icon { width: var(--ksc-icon-md); height: var(--ksc-icon-md); color: var(--ks-registry-fg); }
.ks-regblock__title { margin: 0; font-size: var(--ks-text-small); line-height: var(--ks-lh-small); font-weight: var(--ks-weight-semibold); letter-spacing: var(--ks-tracking-normal); color: var(--ks-text-strong); }
.ks-regblock__time { font-size: var(--ks-text-caption); color: var(--ks-text-muted); }
.ks-regblock__note { font-size: var(--ks-text-dense); line-height: var(--ks-lh-dense); color: var(--ks-text-muted); }
.ks-regblock__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(calc(var(--ks-space-12) * 3.125), 1fr)); gap: calc(var(--ks-space-4) + var(--ks-space-1)); }
.ks-regblock__footer { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ks-space-4); }

/* ---- EffectivePeriods ------------------------------------------------------------ */
.ks-periods { display: flex; flex-direction: column; gap: calc(var(--ks-space-4) + var(--ks-space-1)); min-width: 0; }
.ks-periods__header { display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--ks-space-4) + var(--ks-space-1)); }
.ks-periods__title { flex: 1 1 calc(var(--ks-space-12) * 3); margin: 0; font-size: var(--ks-text-small); line-height: var(--ks-lh-small); font-weight: var(--ks-weight-semibold); letter-spacing: var(--ks-tracking-normal); color: var(--ks-text-strong); }
.ks-periods__title-note { font-weight: var(--ks-weight-regular); color: var(--ks-text-muted); }
.ks-periods__note { font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); color: var(--ks-text-muted); }
.ks-periods__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--ks-space-3); }
.ks-period {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--ks-space-2) var(--ks-space-5);
  padding: var(--ks-space-4) var(--ks-space-5);
  background: var(--ks-surface-card);
  border: var(--ks-border-w) solid var(--ks-border);
  border-radius: var(--ks-radius-lg);
}
.ks-period[aria-current="true"],
.ks-period[data-state="current"] { background: var(--ks-surface-selected); border-color: var(--ks-blue-200); }
[data-theme="dark"] .ks-period[aria-current="true"],
[data-theme="dark"] .ks-period[data-state="current"] { border-color: var(--ks-registry-border); }
@media (prefers-color-scheme: dark) { :where(:root:not([data-ks-theme-fixed])):not([data-theme]) .ks-period[aria-current="true"], :where(:root:not([data-ks-theme-fixed])):not([data-theme]) .ks-period[data-state="current"] { border-color: var(--ks-registry-border); } }
.ks-period__dates { grid-column: 1; display: flex; flex-wrap: wrap; align-items: center; gap: var(--ks-space-1) var(--ks-space-4); min-width: 0; }
.ks-period__range {
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: var(--ks-space-3);
  font-family: var(--ks-font-mono);
  font-size: var(--ks-text-dense);
  line-height: var(--ks-lh-dense);
  color: var(--ks-text-strong);
}
.ks-period__range .ks-icon { width: var(--ksc-icon-xs); height: var(--ksc-icon-xs); color: var(--ks-text-muted); }
.ks-period__value { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ks-space-1) var(--ks-space-4); grid-column: 1 / -1; min-width: 0; font-size: var(--ks-text-small); line-height: var(--ks-lh-small); color: var(--ks-text-default); }
.ks-period__meta { font-size: var(--ks-text-caption); color: var(--ks-text-muted); }
.ks-period__actions { grid-column: 2; grid-row: 1; display: flex; flex-wrap: wrap; align-items: center; gap: var(--ks-space-2); }
/* The form for ONE period (add or change), in a Modal. The rate set belongs to ryczałt and to
   nothing else, so it exists only while "ryczalt" is the chosen regime - :has() on the checked
   option, so it needs no script. */
.ks-periodform { display: flex; flex-direction: column; gap: var(--ks-space-5); min-width: 0; }
.ks-periodform__rates {
  display: none;
  margin: 0;
  min-width: 0;
  padding: var(--ks-space-5);
  background: var(--ks-surface-sunken);
  border: var(--ks-border-w) solid var(--ks-border);
  border-radius: var(--ks-radius-lg);
}
.ks-periodform:has(option[value="ryczalt"]:checked) .ks-periodform__rates { display: block; }
.ks-periodform__rates > legend { padding: 0 var(--ks-space-2); }
.ks-periods__empty {
  padding: var(--ks-space-5) calc(var(--ks-space-5) + var(--ks-space-1));
  border: var(--ks-border-w) dashed var(--ks-border-strong);
  border-radius: var(--ks-radius-lg);
  font-size: var(--ks-text-dense);
  color: var(--ks-text-muted);
}

/* ---- AuditTimeline ------------------------------------------------------------------ */
.ks-audit { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.ks-audit__item {
  --ksc-audit-tone: var(--ks-text-accent);
  display: grid;
  grid-template-columns: calc(var(--ks-space-8) + var(--ks-space-1)) minmax(0, 1fr);
  gap: var(--ks-space-5);
}
.ks-audit__item--created,
.ks-audit__item--changed { --ksc-audit-tone: var(--ks-text-accent); }
.ks-audit__item--accepted { --ksc-audit-tone: var(--ks-status-success-fg); }
.ks-audit__item--rejected { --ksc-audit-tone: var(--ks-status-danger-fg); }
.ks-audit__item--sent { --ksc-audit-tone: var(--ks-status-progress-fg); }
.ks-audit__item--system { --ksc-audit-tone: var(--ks-text-muted); }
.ks-audit__rail { display: flex; flex-direction: column; align-items: center; }
.ks-audit__dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: calc(var(--ks-space-8) + var(--ks-space-1));
  height: calc(var(--ks-space-8) + var(--ks-space-1));
  border-radius: 50%;
  background: var(--ks-surface-card);
  border: var(--ks-border-w) solid var(--ks-border);
  color: var(--ksc-audit-tone);
}
.ks-audit__dot .ks-icon { width: calc(var(--ksc-icon-xs) + var(--ks-border-w)); height: calc(var(--ksc-icon-xs) + var(--ks-border-w)); }
.ks-audit__line { flex: 1; width: var(--ks-border-w); min-height: var(--ks-space-7); background: var(--ks-border); }
.ks-audit__item:last-child .ks-audit__line { display: none; }
.ks-audit__content { display: flex; flex-direction: column; gap: calc(var(--ks-space-1) + var(--ks-border-w)); padding-bottom: calc(var(--ks-space-6) + var(--ks-space-1)); min-width: 0; }
.ks-audit__item:last-child .ks-audit__content { padding-bottom: 0; }
.ks-audit--compact .ks-audit__line { min-height: calc(var(--ks-space-5) + var(--ks-space-1)); }
.ks-audit--compact .ks-audit__content { padding-bottom: var(--ks-space-5); }
.ks-audit__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--ks-space-4); }
.ks-audit__title { margin: 0; font-size: var(--ks-text-small); line-height: var(--ks-lh-small); font-weight: var(--ks-weight-medium); color: var(--ks-text-strong); }
.ks-audit__time { font-family: var(--ks-font-mono); font-size: var(--ks-text-caption); color: var(--ks-text-muted); }
.ks-audit__actor { font-size: var(--ks-text-caption); color: var(--ks-text-muted); }
.ks-audit__change { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ks-space-3); font-size: var(--ks-text-dense); color: var(--ks-text-default); }
.ks-audit__field { color: var(--ks-text-muted); }
.ks-audit__before,
.ks-audit__after { padding: var(--ks-border-w) var(--ks-space-3); border-radius: var(--ks-radius-xs); }
.ks-audit__before { background: var(--ks-status-danger-bg); color: var(--ks-status-danger-fg); text-decoration: line-through; }
.ks-audit__after { background: var(--ks-status-success-bg); color: var(--ks-status-success-fg); text-decoration: none; }
.ks-audit__change .ks-icon { width: var(--ksc-icon-xs); height: var(--ksc-icon-xs); color: var(--ks-text-muted); }
.ks-audit__desc { margin: 0; font-size: var(--ks-text-dense); line-height: var(--ks-lh-dense); color: var(--ks-text-muted); }

/* ---- StepList --------------------------------------------------------------------
   The complete route through a record's required steps: done (reachable, shows
   what was entered), current (aria-current="step"), upcoming (muted, still a real
   link where one exists — founders allow finishing steps out of order). An upcoming
   step with nowhere to go yet (e.g. it needs a record id that a later step creates)
   is `<span aria-disabled="true">` with a visible reason, same non-link-with-reason
   pattern as SideNav's disabled items — never an `<a>` with no `href`. Always the
   full list, in the same order; no "step 2 of 5" counter, nothing hidden or
   reordered as steps complete. Whether the list renders at all — shown while
   something is missing, gone once the record is complete, back if something is
   later found missing — is a server decision, not a CSS state.                    */
.ks-steplist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.ks-steplist__item {
  --ksc-steplist-tone: var(--ks-text-muted);
  display: grid;
  grid-template-columns: calc(var(--ks-space-8) + var(--ks-space-1)) minmax(0, 1fr);
  gap: var(--ks-space-5);
}
.ks-steplist__item--done { --ksc-steplist-tone: var(--ks-status-success-fg); }
.ks-steplist__item--current { --ksc-steplist-tone: var(--ks-text-accent); }
/* The rail is decorative and sits visually first; explicit columns let the link
   (`__content`) come first in reading/DOM order without the rail's markup
   having to precede it every time it's used. */
.ks-steplist__rail { grid-column: 1; display: flex; flex-direction: column; align-items: center; }
.ks-steplist__dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: calc(var(--ks-space-8) + var(--ks-space-1));
  height: calc(var(--ks-space-8) + var(--ks-space-1));
  border-radius: 50%;
  background: var(--ks-surface-card);
  border: var(--ks-border-w) solid var(--ks-border);
  color: var(--ksc-steplist-tone);
}
.ks-steplist__item--done .ks-steplist__dot,
.ks-steplist__item--current .ks-steplist__dot { border-color: var(--ksc-steplist-tone); }
.ks-steplist__item--current .ks-steplist__dot::after { content: ""; width: var(--ks-space-3); height: var(--ks-space-3); border-radius: 50%; background: var(--ksc-steplist-tone); }
.ks-steplist__dot .ks-icon { width: calc(var(--ksc-icon-xs) + var(--ks-border-w)); height: calc(var(--ksc-icon-xs) + var(--ks-border-w)); }
.ks-steplist__line { flex: 1; width: var(--ks-border-w); min-height: var(--ks-space-7); background: var(--ks-border); }
.ks-steplist__item:last-child .ks-steplist__line { display: none; }
.ks-steplist__content {
  grid-column: 2;
  display: flex;
  flex-direction: column;
  gap: calc(var(--ks-space-1) + var(--ks-border-w));
  padding-bottom: calc(var(--ks-space-6) + var(--ks-space-1));
  min-width: 0;
  color: inherit;
  text-decoration: none;
}
.ks-steplist__item:last-child .ks-steplist__content { padding-bottom: 0; }
a.ks-steplist__content:hover .ks-steplist__title { text-decoration: underline; }
a.ks-steplist__content:focus-visible { outline: var(--ks-focus-w) solid var(--ks-focus-ring); outline-offset: var(--ks-focus-offset); border-radius: var(--ks-radius-sm); }
.ks-steplist__content[aria-disabled="true"] { cursor: not-allowed; }
.ks-steplist__title { font-size: var(--ks-text-small); line-height: var(--ks-lh-small); font-weight: var(--ks-weight-medium); color: var(--ks-text-strong); }
.ks-steplist__item--upcoming .ks-steplist__title { color: var(--ks-text-muted); font-weight: var(--ks-weight-regular); }
.ks-steplist__content[aria-disabled="true"] .ks-steplist__title { color: var(--ks-text-subtle); }
.ks-steplist__item--current .ks-steplist__title { color: var(--ksc-steplist-tone); }
.ks-steplist__summary,
.ks-steplist__reason { font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); color: var(--ks-text-muted); }

/* ---- DelegationStatus ------------------------------------------------------------- */
.ks-deleg { display: flex; flex-direction: column; gap: var(--ks-space-3); }
.ks-deleg__list { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--ks-space-3); }
.ks-deleg__item {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--ks-space-2) + var(--ks-border-w));
  padding: var(--ks-space-1) var(--ks-space-4);
  border-radius: var(--ks-radius-pill);
  background: var(--ks-status-warning-bg);
  color: var(--ks-status-warning-fg);
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-caption);
  font-weight: var(--ks-weight-medium);
  white-space: nowrap;
}
.ks-deleg__item[data-state="signed"] { background: var(--ks-status-success-bg); color: var(--ks-status-success-fg); }
.ks-deleg__item .ks-icon { width: calc(var(--ksc-icon-xs) - var(--ks-border-w)); height: calc(var(--ksc-icon-xs) - var(--ks-border-w)); }
.ks-deleg__date { font-family: var(--ks-font-mono); }
.ks-deleg__access { font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); color: var(--ks-text-muted); }
.ks-deleg__access strong { color: var(--ks-text-default); }
.ks-deleg-summary {
  display: inline-flex;
  align-items: center;
  gap: var(--ks-space-3);
  font-size: var(--ks-text-dense);
  line-height: var(--ks-lh-dense);
  color: var(--ks-text-default);
  white-space: normal;
}
.ks-deleg-summary .ks-icon { width: var(--ksc-icon-sm); height: var(--ksc-icon-sm); color: var(--ks-status-warning-fg); }
.ks-deleg-summary[data-state="complete"] .ks-icon { color: var(--ks-status-success-fg); }

/* ---- ProfileBadge ---------------------------------------------------------------- */
.ks-profile { display: inline-flex; flex-direction: column; align-items: flex-start; gap: var(--ks-space-1); min-width: 0; max-width: 100%; }
.ks-profile__badge {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--ks-space-2) + var(--ks-border-w));
  padding: var(--ks-space-1) calc(var(--ks-space-4) + var(--ks-border-w));
  border-radius: var(--ks-radius-pill);
  background: var(--ks-status-info-bg);
  color: var(--ks-status-info-fg);
  font-size: var(--ks-text-dense);
  line-height: var(--ks-lh-dense);
  font-weight: var(--ks-weight-medium);
  white-space: nowrap;
}
.ks-profile__badge .ks-icon { width: calc(var(--ksc-icon-xs) + var(--ks-border-w)); height: calc(var(--ksc-icon-xs) + var(--ks-border-w)); }
.ks-profile--out .ks-profile__badge { background: var(--ks-status-neutral-bg); color: var(--ks-status-neutral-fg); }
.ks-profile--sm .ks-profile__badge { padding: 0 calc(var(--ks-space-3) + var(--ks-border-w)); font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); }
.ks-profile--sm .ks-profile__badge .ks-icon { width: calc(var(--ksc-icon-xs) - var(--ks-border-w)); height: calc(var(--ksc-icon-xs) - var(--ks-border-w)); }
.ks-profile__label { display: inline; }
/* The Ksiego mark is the glyph in every form now (founders, 2026-09-28: a stated exception to
   "never recolour the mark" — see Logo). The old check/book svg icon, if a page still sends one,
   is always hidden; the mark alone carries "in profile" (full colour) vs "out of profile" (the
   SAME file, muted — one token, never a second drawing). */
.ks-profile__mark { display: block; width: auto; height: calc(var(--ksc-icon-md) + var(--ks-space-2)); }
.ks-profile__badge > .ks-icon { display: none; }
.ks-profile--out .ks-profile__mark { filter: grayscale(1); opacity: var(--ksc-mark-muted); }
/* Icon-only form, standalone: the badge shrinks to a circle around the mark alone; label and
   reason stay in the DOM, visually hidden, as the accessible name (also in `title`). In a table
   the SAME form applies by itself at card-list widths (see DataTable). Item 1 of every
   ClientMarker strip is always this form too (founders, 2026-09-28), sized to match a
   ".ks-markers__badge" so the profile mark reads as one icon among the others, not a wider,
   worded one. */
.ks-profile--icon .ks-profile__badge {
  justify-content: center;
  width: calc(var(--ksc-icon-md) + var(--ks-space-3));
  height: calc(var(--ksc-icon-md) + var(--ks-space-3));
  padding: 0;
  background: transparent;
}
.ks-profile--icon .ks-profile__mark { height: var(--ksc-icon-sm); }
.ks-profile--icon.ks-profile--out .ks-profile__badge { background: var(--ks-status-neutral-bg); }
.ks-profile--icon .ks-profile__label,
.ks-profile--icon .ks-profile__reason {
  position: absolute;
  width: var(--ks-border-w);
  height: var(--ks-border-w);
  margin: calc(var(--ks-border-w) * -1);
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.ks-profile__reason {
  position: absolute;
  width: var(--ks-border-w);
  height: var(--ks-border-w);
  margin: calc(var(--ks-border-w) * -1);
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.ks-profile__reason {
  max-width: calc(var(--ks-space-12) * 3.125);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-caption);
  color: var(--ks-text-muted);
}

/* ---- EditConflict ---------------------------------------------------------------- */
.ks-conflict { display: flex; flex-direction: column; gap: var(--ks-space-5); }
.ks-conflict__table {
  width: 100%;
  border: var(--ks-border-w) solid var(--ks-border);
  border-radius: var(--ks-radius-lg);
  border-collapse: separate;
  border-spacing: 0;
  overflow: hidden;
  font-size: var(--ks-text-dense);
  line-height: var(--ks-lh-dense);
}
.ks-conflict__table th {
  padding: var(--ks-space-4) var(--ks-space-5);
  background: var(--ks-surface-sunken);
  border-bottom: var(--ks-border-w) solid var(--ks-border);
  text-align: left;
  font-size: var(--ks-text-caption);
  font-weight: var(--ks-weight-semibold);
  letter-spacing: var(--ks-tracking-caps);
  text-transform: uppercase;
  color: var(--ksc-text-muted-on-tint);
}
.ks-conflict__table td,
.ks-conflict__table tbody th {
  padding: calc(var(--ks-space-4) + var(--ks-border-w)) var(--ks-space-5);
  border-bottom: var(--ks-border-w) solid var(--ks-border);
  background: var(--ks-surface-card);
  color: var(--ks-text-default);
  vertical-align: top;
}
.ks-conflict__table tbody th { font-size: var(--ks-text-dense); font-weight: var(--ks-weight-regular); letter-spacing: var(--ks-tracking-normal); text-transform: none; color: var(--ks-text-muted); }
.ks-conflict__table tbody tr:last-child > * { border-bottom: 0; }
.ks-conflict__theirs { background: var(--ks-surface-sunken) !important; }
.ks-conflict__yours { color: var(--ks-text-strong) !important; font-weight: var(--ks-weight-medium); }
@media (max-width: 480px) {
  .ks-conflict__table thead { display: none; }
  .ks-conflict__table tr { display: grid; grid-template-columns: 1fr 1fr; }
  .ks-conflict__table tbody th { grid-column: 1 / -1; padding-bottom: 0; border: 0; }
  .ks-conflict__table td::before { content: attr(data-label); display: block; font-size: var(--ks-text-caption); color: var(--ks-text-muted); }
}

@media (max-width: 600px) {
  .ks-period { grid-template-columns: minmax(0, 1fr); }
  .ks-period__actions { grid-column: 1; grid-row: auto; margin-inline-start: calc(var(--ks-space-3) * -1); }
}

/* ---- ClientMarker ------------------------------------------------------------------------
   Strip of small icons beside a client's name (US11, FR-085 - FR-090). Item 1 is always the
   profile mark (see ProfileBadge, a ".ks-profile" reused as-is); the rest are ".ks-markers__item"
   - system findings (read-only, computed) and the firm's own markers (catalogue), rendered by the
   SAME markup either way (FR-086: "never edited" is a server rule, not a visual one). Every item
   carries its name as visually hidden text and as `title`; a custom marker's title also carries
   its note. The strip caps at four icons then "+N" inside a table row, three then "+N" on a phone
   card (@container ks-table, same technique ProfileBadge and DataTable's icon cells use) - outside
   a table (the client card header) every marker shows, no cap, no "+N". */
.ks-markers { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ks-space-2); list-style: none; margin: 0; padding: 0; }
.ks-markers__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: calc(var(--ksc-icon-md) + var(--ks-space-3));
  height: calc(var(--ksc-icon-md) + var(--ks-space-3));
  border-radius: var(--ks-radius-pill);
  background: var(--ks-surface-sunken);
  color: var(--ks-text-muted);
}
.ks-markers__badge .ks-icon { width: var(--ksc-icon-sm); height: var(--ksc-icon-sm); }
.ks-markers__item--success .ks-markers__badge  { background: var(--ks-status-success-bg);  color: var(--ks-status-success-fg); }
.ks-markers__item--info .ks-markers__badge     { background: var(--ks-status-info-bg);     color: var(--ks-status-info-fg); }
.ks-markers__item--warning .ks-markers__badge  { background: var(--ks-status-warning-bg);  color: var(--ks-status-warning-fg); }
.ks-markers__item--danger .ks-markers__badge   { background: var(--ks-status-danger-bg);   color: var(--ks-status-danger-fg); }
.ks-markers__item--progress .ks-markers__badge { background: var(--ks-status-progress-bg); color: var(--ks-status-progress-fg); }
.ks-markers__more > .ks-markers__badge { width: auto; min-width: calc(var(--ksc-icon-md) + var(--ks-space-3)); padding: 0 var(--ks-space-2); font-size: var(--ks-text-caption); font-weight: var(--ks-weight-semibold); }
.ks-markers__more--card { display: none; }
@container ks-table (max-width: 480px) {
  .ks-markers__item:nth-of-type(n+4) { display: none; }
  .ks-markers__more--table { display: none; }
  .ks-markers__more--card { display: inline-flex; }
}
/* The uncapped card-header strip on a phone: an item's --start bubble has (row width - 24 - 26k)
   of room, so past the first few items no alignment fits a 224px bubble. As in the card list
   (20-data.css), the bubble anchors to the meta row instead of the item and is capped at its
   width. Bubbles are laid out while hidden, so without this they also scroll .ks-app__main sideways. */
@media (max-width: 600px) {
  .ks-pagehead__meta:has(.ks-markers) { position: relative; }
  .ks-pagehead__meta .ks-markers .ks-tooltip { position: static; }
  .ks-pagehead__meta .ks-markers .ks-tooltip__bubble {
    left: 0;
    transform: none;
    text-align: left;
    max-width: min(calc(var(--ks-space-12) * 3.5), 100%);
  }
}

/* One marker, icon-plus-note form: the catalogue row (Settings) and each ticked row of the
   "Znaczniki" dialog. Same tone classes as the strip. */
.ks-marker { display: flex; align-items: flex-start; gap: var(--ks-space-4); min-width: 0; }
.ks-marker__badge {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: calc(var(--ksc-icon-md) + var(--ks-space-4));
  height: calc(var(--ksc-icon-md) + var(--ks-space-4));
  border-radius: var(--ks-radius-pill);
  background: var(--ks-surface-sunken);
  color: var(--ks-text-muted);
}
.ks-marker__badge .ks-icon { width: var(--ksc-icon-md); height: var(--ksc-icon-md); }
.ks-marker--success .ks-marker__badge  { background: var(--ks-status-success-bg);  color: var(--ks-status-success-fg); }
.ks-marker--info .ks-marker__badge     { background: var(--ks-status-info-bg);     color: var(--ks-status-info-fg); }
.ks-marker--warning .ks-marker__badge  { background: var(--ks-status-warning-bg);  color: var(--ks-status-warning-fg); }
.ks-marker--danger .ks-marker__badge   { background: var(--ks-status-danger-bg);   color: var(--ks-status-danger-fg); }
.ks-marker--neutral .ks-marker__badge  { background: var(--ks-status-neutral-bg);  color: var(--ks-status-neutral-fg); }
.ks-marker--progress .ks-marker__badge { background: var(--ks-status-progress-bg); color: var(--ks-status-progress-fg); }
.ks-marker__body { min-width: 0; flex: 1; }
.ks-marker__name { margin: 0; overflow-wrap: anywhere; font-size: var(--ks-text-small); font-weight: var(--ks-weight-medium); color: var(--ks-text-strong); }
.ks-marker__note { margin: 0; font-size: var(--ks-text-caption); color: var(--ks-text-muted); }
.ks-marker__actions { flex: none; display: flex; align-items: center; gap: var(--ks-space-2); }
/* A catalogue row: the chip keeps its natural width (never shrunk under the buttons) and the
   actions take a line of their own when both do not fit, whatever the name's length; on a very
   narrow row the actions wrap among themselves too. */
.ks-markertypes > li { flex-wrap: wrap; row-gap: var(--ks-space-2); }
.ks-markertypes > li > .ks-marker { flex: 1 0 auto; max-width: 100%; }
.ks-markertypes > li > .ks-marker__actions { flex: 0 1 auto; min-width: 0; flex-wrap: wrap; justify-content: flex-end; margin-left: auto; }
.ks-marker--archived { opacity: var(--ksc-disabled-opacity); }

/* Marker-catalogue picker (the "Znaczniki" dialog): one ".ks-marker" per row, its checkbox first,
   the note field showing only beside a ticked type - CSS only, :has() on the checked input. */
.ks-markerpicker { display: flex; flex-direction: column; gap: var(--ks-space-5); }
.ks-markerpicker__row { display: flex; align-items: flex-start; gap: var(--ks-space-4); padding: var(--ks-space-3) 0; border-bottom: var(--ks-border-w) solid var(--ks-border); }
.ks-markerpicker__row:last-child { border-bottom: 0; }
.ks-markerpicker__row .ks-marker { flex: 1; min-width: 0; }
.ks-markerpicker__note { display: none; margin-top: var(--ks-space-2); }
.ks-markerpicker__row:has(.ks-check__input:checked) .ks-markerpicker__note { display: block; }

/* ---- Alert block (FR-090): above the client card's tabs, on every tab, newest first. --------- */
.ks-alerts { display: flex; flex-direction: column; gap: var(--ks-space-3); margin-bottom: var(--ks-space-6); }
.ks-alert {
  display: flex;
  align-items: flex-start;
  gap: var(--ks-space-4);
  padding: var(--ks-space-4) var(--ks-space-5);
  background: var(--ks-status-danger-bg);
  border: var(--ks-border-w) solid var(--ksc-edge-danger);
  border-radius: var(--ks-radius-lg);
}
.ks-alert > .ks-icon { flex: none; width: var(--ksc-icon-md); height: var(--ksc-icon-md); color: var(--ks-status-danger-fg); }
.ks-alert__body { flex: 1; min-width: 0; }
.ks-alert__text { margin: 0; color: var(--ks-text-strong); white-space: pre-line; }
.ks-alert__meta { margin: var(--ks-space-1) 0 0; font-size: var(--ks-text-caption); color: var(--ks-text-muted); }
.ks-alert__actions { flex: none; margin: 0; }

/* ---- Notes tab (FR-089): newest first, author, date, "zmieniono" mark. ------------------------ */
.ks-notes { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--ks-space-4); }
.ks-markertypes { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--ks-space-3); }
.ks-note { padding: var(--ks-space-4) var(--ks-space-5); background: var(--ks-surface-card); border: var(--ks-border-w) solid var(--ks-border); border-radius: var(--ks-radius-lg); }
.ks-note__head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ks-space-3); margin-bottom: var(--ks-space-2); font-size: var(--ks-text-caption); color: var(--ks-text-muted); }
.ks-note__edited { font-style: italic; }
.ks-note__text { margin: 0; color: var(--ks-text-default); white-space: pre-line; }
.ks-note__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ks-space-2); margin-top: var(--ks-space-3); }

/* ---- css/src/50-shell.css ---- */
/* ==========================================================================
   50 · Shell — AppShell, TopBar, SideNav, ClientSwitcher, LanguageSwitcher,
   PageHeader, Logo, ThemeToggle, Breadcrumbs
   ========================================================================== */

/* ---- AppShell ----------------------------------------------------------------
   56px bar that never scrolls away · 248px rail · centred 1440px column.     */
.ks-app {
  display: flex;
  flex-direction: column;
  height: 100dvh;
  min-height: 0;
  background: var(--ks-surface-app);
  color: var(--ks-text-default);
  overflow: hidden;
}
.ks-app__body { display: flex; flex: 1; min-height: 0; }
/* position: relative is load-bearing, not decoration. Without it this scroller is not the
   containing block for its absolutely positioned descendants — every .ks-visually-hidden label deep
   in a long page is then laid out against the page itself, escapes this element's clipping, and
   stretches the document: the app grew a second scrollbar beside this one, scrolling the whole
   shell (founders, 2026-09-25). */
.ks-app__main { position: relative; flex: 1; min-width: 0; overflow-y: auto; }
.ks-app__main:focus-visible { outline-offset: calc(var(--ks-focus-offset) * -1); }
.ks-app__content {
  display: flex;
  flex-direction: column;
  gap: var(--ks-space-6);
  max-width: var(--ks-page-max);
  margin: 0 auto;
  padding: var(--ks-space-7) var(--ks-page-pad-x) var(--ks-space-10);
}
.ks-app__content--narrow { max-width: var(--ks-content-max); }
/* Framed variant for documentation: fixed height instead of the viewport. */
.ks-app--framed { height: calc(var(--ks-space-12) * 9); border: var(--ks-border-w) solid var(--ks-border); border-radius: var(--ks-radius-xl); }

/* ---- TopBar ---------------------------------------------------------------------- */
.ks-topbar {
  display: flex;
  align-items: center;
  gap: var(--ks-space-6);
  flex: none;
  height: var(--ks-topbar-h);
  padding: 0 var(--ks-space-6);
  background: var(--ks-navy-900);
  color: var(--ks-white);
}
.ks-topbar a:not(.ks-btn) { color: var(--ks-white); }
.ks-topbar :focus-visible { outline-color: var(--ks-white); }
.ks-topbar__firm {
  display: flex;
  align-items: center;
  gap: var(--ks-space-4);
  min-width: 0;
  padding-left: var(--ks-space-6);
  border-left: var(--ks-border-w) solid var(--ksc-on-navy-line);
  font-size: var(--ks-text-small);
  font-weight: var(--ks-weight-medium);
}
.ks-topbar__firm .ks-icon { width: calc(var(--ksc-icon-sm) + var(--ks-border-w)); height: calc(var(--ksc-icon-sm) + var(--ks-border-w)); color: var(--ksc-on-navy-muted); }
.ks-topbar__firm-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ks-topbar__tools { display: flex; align-items: center; gap: var(--ks-space-5); margin-left: auto; }
.ks-topbar__user {
  display: flex;
  align-items: center;
  gap: calc(var(--ks-space-4) + var(--ks-border-w));
  padding-left: var(--ks-space-5);
  border-left: var(--ks-border-w) solid var(--ksc-on-navy-line);
}
.ks-topbar__who { display: flex; flex-direction: column; line-height: var(--ks-lh-caption); }
.ks-topbar__name { font-size: var(--ks-text-dense); font-weight: var(--ks-weight-medium); }
.ks-topbar__role { font-size: var(--ks-text-caption); color: var(--ksc-on-navy-muted); }
.ks-topbar__form { margin: 0; }
/* Narrow frames (tablet, docs panes): drop secondary text before anything overflows. */
.ks-topbar { container: ks-topbar / inline-size; }
.ks-topbar .ks-lang { flex-wrap: nowrap; }
.ks-topbar__who { white-space: nowrap; }
@container ks-topbar (max-width: 900px) {
  .ks-topbar__who { display: none; }
  .ks-topbar .ks-lang > .ks-icon { display: none; }
}
@container ks-topbar (max-width: 600px) {
  .ks-topbar__user .ks-avatar { display: none; }
}
.ks-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--ks-control-h-sm);
  height: var(--ks-control-h-sm);
  border-radius: 50%;
  background: var(--ksc-on-navy-fill);
  color: var(--ks-white);
  font-size: var(--ks-text-caption);
  font-weight: var(--ks-weight-semibold);
}
.ks-avatar--light { background: var(--ks-surface-section); color: var(--ks-text-link); }
.ks-avatar--lg { width: var(--ks-control-h-lg); height: var(--ks-control-h-lg); font-size: var(--ks-text-small); }
@media (max-width: 900px) {
  .ks-topbar__who, .ks-topbar__firm-name { display: none; }
}

/* ---- ThemeToggle ------------------------------------------------------------------ */
.ks-theme-toggle .ks-theme-toggle__sun { display: none; }
:root[data-theme="dark"] .ks-theme-toggle .ks-theme-toggle__sun { display: inline-block; }
@media (prefers-color-scheme: dark) { :root:where(:root:not([data-ks-theme-fixed])):not([data-theme]) .ks-theme-toggle .ks-theme-toggle__sun { display: inline-block; } }
:root[data-theme="dark"] .ks-theme-toggle .ks-theme-toggle__moon { display: none; }
@media (prefers-color-scheme: dark) { :root:where(:root:not([data-ks-theme-fixed])):not([data-theme]) .ks-theme-toggle .ks-theme-toggle__moon { display: none; } }

/* ---- SideNav ------------------------------------------------------------------------ */
/* position: relative so this scroller is the containing block for what it scrolls: without
   it an absolutely positioned descendant escapes the clip and stretches the page (2026-09-25). */
.ks-sidenav {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--ks-space-2);
  flex: none;
  width: var(--ks-sidenav-w);
  padding: var(--ks-space-5) calc(var(--ks-space-4) + var(--ks-space-1));
  background: var(--ks-surface-card);
  border-right: var(--ks-border-w) solid var(--ks-border);
  overflow-y: auto;
}
.ks-sidenav__section { display: flex; flex-direction: column; gap: var(--ks-space-1); margin-top: var(--ks-space-4); }
.ks-sidenav__heading {
  margin: 0;
  padding: var(--ks-space-2) calc(var(--ks-space-4) + var(--ks-space-1));
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-caption);
  font-weight: var(--ks-weight-semibold);
  letter-spacing: var(--ks-tracking-caps);
  text-transform: uppercase;
  color: var(--ks-text-muted);
}
.ks-sidenav__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--ks-space-1); }
.ks-sidenav__item {
  display: flex;
  align-items: center;
  gap: calc(var(--ks-space-4) + var(--ks-space-1));
  min-height: var(--ks-control-h);
  padding: var(--ks-space-2) calc(var(--ks-space-4) + var(--ks-space-1));
  border-radius: var(--ks-radius-lg);
  color: var(--ks-text-default);
  font-size: var(--ks-text-small);
  line-height: var(--ks-lh-small);
  font-weight: var(--ks-weight-regular);
  text-decoration: none;
  transition: var(--ks-transition-control);
}
.ks-sidenav__item > .ks-icon { width: calc(var(--ksc-icon) - var(--ks-border-w)); height: calc(var(--ksc-icon) - var(--ks-border-w)); color: var(--ks-text-muted); }
a.ks-sidenav__item:hover { background: var(--ks-surface-hover); color: var(--ks-text-strong); text-decoration: none; }
.ks-sidenav__item[aria-current="page"] {
  background: var(--ks-surface-selected);
  color: var(--ks-text-link);
  font-weight: var(--ks-weight-semibold);
}
.ks-sidenav__item[aria-current="page"] > .ks-icon { color: var(--ks-text-link); }
.ks-sidenav__item:focus-visible { border-radius: var(--ks-radius-lg); outline-offset: calc(var(--ks-focus-offset) * -1); }
.ks-sidenav__label { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.ks-sidenav__text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ks-sidenav__reason {
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-caption);
  color: var(--ks-text-muted);
  white-space: normal;
}
.ks-sidenav__scope { width: var(--ksc-icon-xs) !important; height: var(--ksc-icon-xs) !important; color: var(--ks-text-muted) !important; }
.ks-sidenav__tag {
  padding: 0 var(--ks-space-3);
  border-radius: var(--ks-radius-pill);
  background: var(--ks-surface-sunken);
  color: var(--ks-status-neutral-fg);
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-caption);
}
/* Disabled items stay visible: "wkrótce" or client-scoped without a client. */
.ks-sidenav__item[aria-disabled="true"] { color: var(--ks-text-subtle); cursor: not-allowed; }
.ks-sidenav__item[aria-disabled="true"] > .ks-icon { color: var(--ks-text-subtle); }
.ks-sidenav__footer { margin-top: auto; padding-top: var(--ks-space-4); border-top: var(--ks-border-w) solid var(--ks-border); }

/* Icon rail below 900px */
@media (max-width: 900px) {
  .ks-sidenav { width: var(--ks-sidenav-w-collapsed); padding-inline: var(--ks-space-4); }
  .ks-sidenav__heading,
  .ks-sidenav__label,
  .ks-sidenav__tag,
  .ks-sidenav__scope,
  .ks-sidenav .ks-clientswitcher,
  .ks-sidenav__footer { display: none; }
  .ks-sidenav__item { justify-content: center; padding-inline: 0; }
}

/* ---- ClientSwitcher --------------------------------------------------------------- */
.ks-clientswitcher {
  display: flex;
  align-items: center;
  gap: calc(var(--ks-space-4) + var(--ks-space-1));
  width: 100%;
  min-height: calc(var(--ks-space-11) + var(--ks-space-2));
  padding: var(--ks-space-4) calc(var(--ks-space-4) + var(--ks-space-1));
  background: var(--ks-surface-selected);
  border: var(--ks-border-w) solid var(--ks-blue-200);
  border-radius: var(--ks-radius-lg);
  color: var(--ks-text-default);
  font-family: var(--ks-font-sans);
  text-align: left;
  cursor: pointer;
  transition: var(--ks-transition-control);
}
[data-theme="dark"] .ks-clientswitcher { border-color: var(--ks-registry-border); }
@media (prefers-color-scheme: dark) { :where(:root:not([data-ks-theme-fixed])):not([data-theme]) .ks-clientswitcher { border-color: var(--ks-registry-border); } }
.ks-clientswitcher:hover { border-color: var(--ks-focus-ring); }
.ks-clientswitcher[data-state="empty"] { background: var(--ks-surface-sunken); border-color: var(--ks-border-strong); }
.ks-clientswitcher[data-state="empty"] .ks-clientswitcher__eyebrow,
.ks-clientswitcher .ks-clientswitcher__eyebrow { color: var(--ksc-text-muted-on-tint); }
.ks-clientswitcher__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--ksc-square-sm);
  height: var(--ksc-square-sm);
  border-radius: var(--ks-radius-md);
  background: var(--ks-surface-card);
  border: var(--ks-border-w) solid var(--ks-border);
  color: var(--ks-text-accent);
}
.ks-clientswitcher__icon .ks-icon { width: calc(var(--ksc-icon-sm) + var(--ks-border-w)); height: calc(var(--ksc-icon-sm) + var(--ks-border-w)); }
.ks-clientswitcher__text { display: flex; flex-direction: column; gap: var(--ks-border-w); flex: 1; min-width: 0; }
.ks-clientswitcher__eyebrow { font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); color: var(--ks-text-muted); }
.ks-clientswitcher__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--ks-text-small);
  line-height: var(--ks-lh-small);
  font-weight: var(--ks-weight-semibold);
  color: var(--ks-text-strong);
}
.ks-clientswitcher__nip { font-family: var(--ks-font-mono); font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); color: var(--ks-text-muted); }
.ks-clientswitcher__caret { width: calc(var(--ksc-icon-sm) + var(--ks-border-w)); height: calc(var(--ksc-icon-sm) + var(--ks-border-w)); color: var(--ks-text-muted); transition: transform var(--ks-duration-fast) var(--ks-ease-standard); }
.ks-clientswitcher[aria-expanded="true"] .ks-clientswitcher__caret { transform: rotate(180deg); }
.ks-clientswitcher__menu { width: calc(var(--ks-sidenav-w) + var(--ks-space-12)); }
.ks-clientswitcher__option { justify-content: space-between; }
.ks-clientswitcher__option-text { display: flex; flex-direction: column; min-width: 0; }
.ks-clientswitcher__option-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ks-text-strong); }
.ks-clientswitcher__option-nip { font-family: var(--ks-font-mono); font-size: var(--ks-text-caption); color: var(--ks-text-muted); }

/* ---- ClientSwitcher: active client at the right end of the top bar + picker in a Drawer ---- */
/* The tenant firm gives up space before the active client does. */
.ks-topbar__firm { flex-shrink: 6; }
.ks-topbar__client {
  display: flex;
  flex: 0 1 auto;
  align-items: center;
  min-width: 0;
  padding-left: var(--ks-space-5);
  border-left: var(--ks-border-w) solid var(--ksc-on-navy-line);
}
/* The whole block is one link: name + NIP + the icon that opens the Drawer. */
.ks-clientbar {
  display: flex;
  align-items: center;
  gap: var(--ks-space-5);
  min-width: 0;
  padding: var(--ks-space-2) var(--ks-space-2) var(--ks-space-2) var(--ks-space-4);
  border-radius: var(--ks-radius-lg);
  color: var(--ks-white);
  text-decoration: none;
  transition: var(--ks-transition-control);
}
.ks-topbar a.ks-clientbar { color: var(--ks-white); }
.ks-clientbar:hover { background: var(--ksc-on-navy-fill); text-decoration: none; }
.ks-clientbar__text { display: flex; flex-direction: column; align-items: flex-end; min-width: 0; max-width: calc(var(--ks-space-12) * 4.5); text-align: right; }
.ks-clientbar__name {
  width: max-content;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--ks-text-dense);
  line-height: var(--ks-lh-dense);
  font-weight: var(--ks-weight-semibold);
}
/* Keep both lines inside the (shrinking) text column so the ellipsis works and nothing
   spills to the left over the avatar. */
.ks-clientbar__name,
.ks-clientbar__nip { min-width: 0; max-width: 100%; }
.ks-clientbar__nip { overflow: hidden; text-overflow: ellipsis; }
.ks-clientbar__nip { font-family: var(--ks-font-mono); font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); color: var(--ksc-on-navy-muted); white-space: nowrap; }
.ks-clientbar[data-state="empty"] .ks-clientbar__name { font-weight: var(--ks-weight-medium); color: var(--ksc-on-navy-muted); }
.ks-clientbar__icon {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: var(--ksc-square-sm);
  height: var(--ksc-square-sm);
  border: var(--ks-border-w) solid var(--ksc-on-navy-edge);
  border-radius: var(--ks-radius-lg);
}
.ks-clientbar__icon .ks-icon { width: var(--ksc-icon-md); height: var(--ksc-icon-md); }
.ks-clientbar:hover .ks-clientbar__icon { border-color: var(--ks-white); }
.ks-clientbar[data-state="empty"] .ks-clientbar__icon { background: var(--ks-action-bg); border-color: var(--ks-action-bg); }

/* ---- User menu (avatar -> popover with identity, profile, logout) ------------------- */
.ks-usermenu__trigger {
  display: inline-flex;
  padding: 0;
  border: 0;
  border-radius: var(--ks-radius-pill);
  background: transparent;
  cursor: pointer;
}
.ks-usermenu__trigger .ks-avatar { transition: var(--ks-transition-control); }
.ks-usermenu__trigger:hover .ks-avatar,
.ks-usermenu__trigger[aria-expanded="true"] .ks-avatar { box-shadow: 0 0 0 var(--ks-focus-w) var(--ksc-on-navy-edge); }
.ks-usermenu__trigger:focus-visible { outline-offset: var(--ks-focus-offset); }
.ks-usermenu { width: calc(var(--ks-space-12) * 4.5); }
.ks-usermenu__head { display: flex; align-items: center; gap: var(--ks-space-5); padding: var(--ks-space-4) var(--ks-space-4) var(--ks-space-5); }
.ks-usermenu__who { display: flex; flex-direction: column; gap: var(--ks-border-w); min-width: 0; }
.ks-usermenu__name { margin: 0; font-size: var(--ks-text-small); line-height: var(--ks-lh-small); font-weight: var(--ks-weight-semibold); color: var(--ks-text-strong); }
.ks-usermenu__role,
.ks-usermenu__email { margin: 0; font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); color: var(--ks-text-muted); overflow-wrap: anywhere; }
.ks-usermenu__form { margin: 0; }
/* The menu lives inside the navy bar in the DOM: undo the bar's white links and white focus ring. */
.ks-topbar .ks-menu .ks-menu__item { color: var(--ks-text-default); }
.ks-topbar .ks-menu .ks-menu__item:hover { color: var(--ks-text-strong); }
.ks-topbar .ks-menu :focus-visible { outline-color: var(--ks-focus-ring); }

/* Narrow bars: the tenant firm goes first, then the client text; the icons stay. */
@container ks-topbar (max-width: 900px) {
  .ks-clientbar__text { max-width: calc(var(--ks-space-12) * 3); }
}
@container ks-topbar (max-width: 600px) {
  .ks-topbar__firm { display: none; }
  .ks-topbar__client { padding-left: var(--ks-space-3); }
  .ks-clientbar__text { max-width: calc(var(--ks-space-12) * 1.75); }
  .ks-clientbar__nip { display: none; }
}
@container ks-topbar (max-width: 480px) {
  .ks-clientbar__text { display: none; }
  .ks-topbar .ks-lang__select { width: calc(var(--ks-space-12) + var(--ks-space-4)); }
}

.ks-clientpicker { display: flex; flex-direction: column; gap: var(--ks-space-6); margin: 0; }
.ks-clientpicker__group { display: flex; flex-direction: column; gap: var(--ks-space-2); }
.ks-clientpicker__heading {
  margin: 0;
  padding: 0 var(--ks-space-4);
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-caption);
  font-weight: var(--ks-weight-semibold);
  letter-spacing: var(--ks-tracking-caps);
  text-transform: uppercase;
  color: var(--ks-text-muted);
}
.ks-clientpicker__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--ks-space-1); }
.ks-clientpicker__option {
  display: flex;
  align-items: center;
  gap: var(--ks-space-5);
  width: 100%;
  min-height: var(--ks-touch-min);
  padding: var(--ks-space-4);
  border: var(--ks-border-w) solid transparent;
  border-radius: var(--ks-radius-md);
  background: transparent;
  color: var(--ks-text-default);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: var(--ks-transition-control);
}
.ks-clientpicker__option:hover { background: var(--ks-surface-hover); }
.ks-clientpicker__option:focus-visible { outline: var(--ks-focus-w) solid var(--ks-focus-ring); outline-offset: calc(var(--ks-focus-offset) * -1); }
.ks-clientpicker__option[aria-current="true"] { background: var(--ks-surface-selected); border-color: var(--ks-blue-200); }
[data-theme="dark"] .ks-clientpicker__option[aria-current="true"] { border-color: var(--ks-registry-border); }
@media (prefers-color-scheme: dark) { :where(:root:not([data-ks-theme-fixed])):not([data-theme]) .ks-clientpicker__option[aria-current="true"] { border-color: var(--ks-registry-border); } }
.ks-clientpicker__option-text { display: flex; flex-direction: column; gap: var(--ks-border-w); flex: 1; min-width: 0; }
.ks-clientpicker__option-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--ks-text-small);
  line-height: var(--ks-lh-small);
  font-weight: var(--ks-weight-medium);
  color: var(--ks-text-strong);
}
.ks-clientpicker__option-nip { font-family: var(--ks-font-mono); font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); color: var(--ksc-text-muted-on-tint); }
.ks-clientpicker__option-meta { display: flex; flex: none; align-items: center; gap: var(--ks-space-3); }
.ks-clientpicker__check { display: none; color: var(--ks-text-link); }
.ks-clientpicker__option[aria-current="true"] .ks-clientpicker__check { display: inline-block; }
.ks-clientpicker__empty { margin: 0; padding: var(--ks-space-8) var(--ks-space-5); text-align: center; font-size: var(--ks-text-small); line-height: var(--ks-lh-small); color: var(--ks-text-muted); }
.ks-clientpicker__empty strong { color: var(--ks-text-strong); font-weight: var(--ks-weight-medium); overflow-wrap: anywhere; }
/* The part of the name (or the start of the NIP) the search matched, marked by the server. */
.ks-clientpicker__mark {
  padding: 0;
  background: none;
  color: inherit;
  font-weight: var(--ks-weight-semibold);
  text-decoration: underline var(--ks-space-1) var(--ks-amber-500);
  text-underline-offset: var(--ks-space-1);
}

/* The server search is in flight (hx-indicator="closest .ks-drawer" puts htmx-request on the
   panel). The list dims only after a moment, so a quick answer does not flash; the search icon
   turns into a spinner. */
.ks-drawer .ks-clientpicker { transition: opacity var(--ks-duration-base) linear; }
.ks-drawer.htmx-request .ks-clientpicker { opacity: var(--ksc-disabled-opacity); transition-delay: var(--ks-duration-base); }

/* The last row of a page of the list: the link to the next page, which the script replaces with
   the page itself as the row scrolls into view. While that request runs the row reads
   "Ładowanie…" with a spinner; if it fails the link is back and works without the script. */
.ks-clientpicker__more {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--ks-touch-min);
  padding: var(--ks-space-2) var(--ks-space-4);
}
.ks-clientpicker__loading {
  display: none;
  align-items: center;
  gap: var(--ks-space-3);
  font-size: var(--ks-text-dense);
  line-height: var(--ks-lh-dense);
  color: var(--ks-text-muted);
}
.ks-clientpicker__more.htmx-request > .ks-btn { display: none; }
.ks-clientpicker__more.htmx-request > .ks-clientpicker__loading { display: inline-flex; }

/* ---- LanguageSwitcher --------------------------------------------------------------- */
.ks-lang {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ks-space-3);
  margin: 0;
  color: var(--ks-text-muted);
}
.ks-lang > .ks-icon { width: calc(var(--ksc-icon-sm) + var(--ks-border-w)); height: calc(var(--ksc-icon-sm) + var(--ks-border-w)); }
.ks-lang__control { position: relative; display: inline-flex; align-items: center; }
.ks-lang__select {
  appearance: none;
  -webkit-appearance: none;
  height: var(--ksc-square-sm);
  padding: 0 var(--ks-space-8) 0 var(--ks-space-3);
  background: var(--ks-surface-card);
  border: var(--ks-border-w) solid var(--ksc-control-edge);
  border-radius: var(--ks-radius-md);
  color: var(--ks-text-default);
  font-family: var(--ks-font-sans);
  font-size: var(--ks-text-dense);
  font-weight: var(--ks-weight-medium);
  cursor: pointer;
}
.ks-lang__select:hover { border-color: var(--ksc-control-edge-hover); }
.ks-lang__select option { color: var(--ks-text-default); background: var(--ks-surface-card); }
.ks-lang__chevron {
  position: absolute;
  right: var(--ks-space-3);
  width: calc(var(--ksc-icon-xs) + var(--ks-border-w)) !important;
  height: calc(var(--ksc-icon-xs) + var(--ks-border-w)) !important;
  pointer-events: none;
}
.ks-lang__submit:not(:focus) {
  position: absolute;
  width: var(--ks-border-w);
  height: var(--ks-border-w);
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.ks-lang--on-dark { color: var(--ksc-on-navy-muted); }
.ks-lang--on-dark .ks-lang__select {
  background: transparent;
  border-color: var(--ksc-on-navy-edge);
  color: var(--ks-white);
}
.ks-lang--on-dark .ks-lang__select option { color: var(--ks-navy-900); background: var(--ks-white); }

/* ---- Breadcrumbs --------------------------------------------------------------------- */
.ks-breadcrumbs { min-width: 0; }
.ks-breadcrumbs__list { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; align-items: center; gap: var(--ks-space-3); }
.ks-breadcrumbs__item { display: inline-flex; align-items: center; gap: var(--ks-space-3); font-size: var(--ks-text-dense); line-height: var(--ks-lh-dense); color: var(--ks-text-muted); }
.ks-breadcrumbs__item a { font-weight: var(--ks-weight-regular); }
/* A crumb is a flex item sized by its longest word: a client name typed as one word ran 1500px past
   the page (2026-10-01). It may shrink to the row and break that word; ordinary crumbs still move
   to the next line whole, since a flex line wraps before its items shrink. Not an ellipsis: a
   crumb link's 44px touch area (70-touch.css) would be clipped by the overflow it needs. */
.ks-breadcrumbs__item { min-width: 0; max-width: 100%; overflow-wrap: anywhere; }
.ks-breadcrumbs__item > * { min-width: 0; }
.ks-breadcrumbs__item + .ks-breadcrumbs__item::before {
  content: "›";
  color: var(--ks-text-muted);
}
.ks-breadcrumbs__item [aria-current="page"] { color: var(--ks-text-muted); }

/* ---- PageHeader ------------------------------------------------------------------------ */
.ks-pagehead { display: flex; flex-direction: column; gap: var(--ks-space-5); min-width: 0; }
.ks-pagehead__main { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--ks-space-6); }
.ks-pagehead__titles { display: flex; flex-direction: column; gap: var(--ks-space-2); flex: 1 1 calc(var(--ks-space-12) * 4); min-width: 0; }
.ks-pagehead__title-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--ks-space-4); }
.ks-pagehead__title { font-size: var(--ks-text-h3); line-height: var(--ks-lh-h3); font-weight: var(--ks-weight-h3); }
.ks-pagehead__pl { font-size: var(--ks-text-body); color: var(--ks-text-muted); }
.ks-pagehead__subtitle { font-size: var(--ks-text-small); line-height: var(--ks-lh-small); color: var(--ks-text-muted); }
.ks-pagehead__meta { display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--ks-space-4) + var(--ks-space-1)); margin-top: var(--ks-space-1); }
/* A sibling of __main instead of a child of __titles (same shape ks-tabs already uses below it),
   so it can use the header's full width - the column's own gap replaces the margin-top tuned for
   sitting right under a title. For a meta row carrying a sentence, not just a couple of short
   badges: the badges-under-the-title case stays put, unchanged. */
.ks-pagehead__meta--wide { margin-top: 0; }
.ks-pagehead__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ks-space-4); }
/* An action that is a POST form: the <form> is only a wrapper around one button. */
.ks-pagehead__action { display: inline-flex; margin: 0; }

/* ---- Logo ------------------------------------------------------------------------------- */
.ks-logo { display: inline-flex; align-items: center; flex: none; }
.ks-logo:focus-visible { border-radius: var(--ks-radius-sm); }
.ks-logo__img { display: block; width: auto; height: calc(var(--ks-space-9) - var(--ks-space-1)); }       /* 30 */
.ks-logo--sm .ks-logo__img { height: calc(var(--ks-space-8) + var(--ks-space-1)); }                      /* 26 */
.ks-logo--xs .ks-logo__img { height: calc(var(--ks-space-7) + var(--ks-space-1)); }                      /* 22 */
.ks-logo--md .ks-logo__img { height: calc(var(--ks-space-9) + var(--ks-space-1)); }                      /* 34 */
.ks-logo--lg .ks-logo__img { height: var(--ks-space-11); }                                               /* 48 */
.ks-logo--mark .ks-logo__img { height: var(--ks-space-9); }                                              /* 32 */
.ks-logo__img--dark { display: none; }
:root[data-theme="dark"] .ks-logo:not(.ks-logo--fixed) .ks-logo__img--light,
.ks-logo[data-theme="dark"] .ks-logo__img--light { display: none; }
@media (prefers-color-scheme: dark) { :root:where(:root:not([data-ks-theme-fixed])):not([data-theme]) .ks-logo:not(.ks-logo--fixed) .ks-logo__img--light { display: none; } }
:root[data-theme="dark"] .ks-logo:not(.ks-logo--fixed) .ks-logo__img--dark,
.ks-logo[data-theme="dark"] .ks-logo__img--dark { display: block; }
@media (prefers-color-scheme: dark) { :root:where(:root:not([data-ks-theme-fixed])):not([data-theme]) .ks-logo:not(.ks-logo--fixed) .ks-logo__img--dark { display: block; } }
.ks-logo--on-dark .ks-logo__img--light { display: none !important; }
.ks-logo--on-dark .ks-logo__img--dark { display: block !important; }

/* Icon-only actions on a phone. Opt in with --compact: the row stays on one line and is
   right-aligned; each button collapses to its icon by the same rule as .ks-btn--compact (see
   Button), so its text must sit in .ks-btn__label. */
@media (max-width: 600px) {
  .ks-pagehead__actions--compact { flex: 1 1 100%; flex-wrap: nowrap; justify-content: flex-end; gap: var(--ks-space-3); }
}

/* ---- css/src/60-patterns.css ---- */
/* ==========================================================================
   60 · Page patterns — sign-in, error pages, stat tiles, mobile (390px)
   layout, marketing site
   ========================================================================== */

/* ---- Sign-in ------------------------------------------------------------------ */
.ks-auth { display: flex; flex-direction: column; min-height: 100dvh; background: var(--ks-surface-app); }
.ks-auth__bar { display: flex; align-items: center; gap: var(--ks-space-6); padding: var(--ks-space-6) var(--ks-space-8); }
.ks-auth__main { display: flex; flex: 1; align-items: center; justify-content: center; padding: var(--ks-space-8); }
.ks-auth__column { display: flex; flex-direction: column; gap: var(--ks-space-6); width: calc(var(--ks-space-10) * 10.5); max-width: 100%; }
.ks-auth__card {
  display: flex;
  flex-direction: column;
  gap: var(--ks-space-6);
  padding: calc(var(--ks-space-8) + var(--ks-space-2));
  background: var(--ks-surface-card);
  border: var(--ks-border-w) solid var(--ks-border);
  border-radius: var(--ks-radius-2xl);
  box-shadow: var(--ks-shadow-sm);
}
.ks-auth__foot { text-align: center; font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); color: var(--ks-text-muted); }
@media (max-width: 480px) {
  .ks-auth__bar { padding: var(--ks-space-6) var(--ks-space-7); }
  .ks-auth__main { align-items: flex-start; padding: var(--ks-space-4) var(--ks-space-7) var(--ks-space-8); }
  .ks-auth__card { padding: 0; background: transparent; border: 0; box-shadow: var(--ks-shadow-none); }
}

/* ---- Error page ----------------------------------------------------------------- */
.ks-error-page { display: flex; justify-content: center; padding: var(--ks-space-11) var(--ks-space-6); }
.ks-error-page .ks-empty { width: calc(var(--ks-space-10) * 14); max-width: 100%; }
.ks-error-page__code { font-family: var(--ks-font-mono); color: var(--ks-text-muted); font-weight: var(--ks-weight-regular); }

/* ---- Stat tile ------------------------------------------------------------------- */
.ks-stat {
  display: flex;
  flex-direction: column;
  gap: var(--ks-space-1);
  padding: var(--ks-space-5) var(--ks-space-6);
  background: var(--ks-surface-card);
  border: var(--ks-border-w) solid var(--ks-border);
  border-radius: var(--ks-radius-xl);
}
.ks-stat__label { font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); color: var(--ks-text-muted); }
.ks-stat__value { font-family: var(--ks-font-mono); font-size: var(--ks-text-h4); line-height: var(--ks-lh-h4); font-weight: var(--ks-weight-semibold); color: var(--ks-text-strong); }
.ks-stat__delta { font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); color: var(--ks-text-muted); }
.ks-stat__delta--up { color: var(--ks-status-success-fg); }
.ks-stat__delta--down { color: var(--ks-status-danger-fg); }

/* Totals row under invoice lines */
.ks-totals { display: grid; grid-template-columns: auto auto; justify-content: end; gap: var(--ks-space-2) var(--ks-space-8); font-size: var(--ks-text-small); }
.ks-totals dt { color: var(--ks-text-muted); }
.ks-totals dd { margin: 0; text-align: right; font-family: var(--ks-font-mono); color: var(--ks-text-strong); }
.ks-totals__grand { font-weight: var(--ks-weight-semibold); font-size: var(--ks-text-body); }

/* Code / payload block */
.ks-codeblock {
  margin: 0;
  padding: var(--ks-space-5);
  overflow-x: auto;
  background: var(--ks-surface-sunken);
  border: var(--ks-border-w) solid var(--ks-border);
  border-radius: var(--ks-radius-lg);
  font-family: var(--ks-font-mono);
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-dense);
  color: var(--ks-text-default);
  white-space: pre;
}

/* ---- Mobile (390px) --------------------------------------------------------------- */
/* The ui_kits/ksiego-mobile reference pages only: class-only on purpose, never switched on by
   width. The application's phone layout is AppShell responding at <=480px, not this shell. */
.ks-m { display: flex; flex-direction: column; min-height: 100dvh; background: var(--ks-surface-app); }
.ks-m__bar {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: calc(var(--ks-space-4) + var(--ks-space-1));
  min-height: var(--ks-topbar-h);
  padding: 0 var(--ks-space-5);
  background: var(--ks-navy-900);
  color: var(--ks-white);
}
.ks-m__bar a,
.ks-m__bar button { color: var(--ks-white); }
.ks-m__bar :focus-visible { outline-color: var(--ks-white); }
.ks-m__iconbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--ks-touch-min);
  height: var(--ks-touch-min);
  margin: 0 calc(var(--ks-space-4) * -1);
  border: 0;
  border-radius: var(--ks-radius-lg);
  background: transparent;
  cursor: pointer;
}
.ks-m__iconbtn .ks-icon { width: var(--ksc-icon-lg); height: var(--ksc-icon-lg); }
.ks-m__titles { display: flex; flex-direction: column; flex: 1; min-width: 0; line-height: var(--ks-lh-caption); }
.ks-m__title { margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--ks-text-small); line-height: var(--ks-lh-small); font-weight: var(--ks-weight-semibold); letter-spacing: var(--ks-tracking-normal); color: var(--ks-white); }
.ks-m__sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--ks-text-caption); color: var(--ksc-on-navy-muted); }
.ks-m__toolbar {
  display: flex;
  flex-direction: column;
  gap: var(--ks-space-4);
  padding: var(--ks-space-5);
  background: var(--ks-surface-card);
  border-bottom: var(--ks-border-w) solid var(--ks-border);
}
.ks-m__chips { display: flex; gap: var(--ks-space-3); overflow-x: auto; padding-bottom: var(--ks-space-1); }
.ks-m__chips .ks-chip { flex: none; height: var(--ks-touch-min); }
.ks-m__main { display: flex; flex-direction: column; gap: var(--ks-space-4); flex: 1; padding: var(--ks-space-5); }
.ks-m__tabs {
  position: sticky;
  bottom: 0;
  display: flex;
  background: var(--ks-surface-card);
  border-top: var(--ks-border-w) solid var(--ks-border);
}
.ks-m__tab {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--ks-space-1);
  min-height: var(--ks-topbar-h);
  color: var(--ks-text-muted);
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-caption);
  font-weight: var(--ks-weight-regular);
  text-decoration: none;
}
.ks-m__tab .ks-icon { width: var(--ksc-icon-lg); height: var(--ksc-icon-lg); }
.ks-m__tab:hover { color: var(--ks-text-strong); text-decoration: none; }
.ks-m__tab[aria-current="page"] { color: var(--ks-text-link); font-weight: var(--ks-weight-semibold); }
.ks-m__tab:focus-visible { outline-offset: calc(var(--ks-focus-offset) * -1); }

.ks-mcard {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--ks-space-3);
  padding: var(--ks-space-5);
  background: var(--ks-surface-card);
  border: var(--ks-border-w) solid var(--ks-border);
  border-radius: var(--ks-radius-xl);
}
.ks-mcard:has(.ks-mcard__link:hover) { border-color: var(--ks-border-strong); background: var(--ks-surface-hover); }
.ks-mcard__head { display: flex; align-items: flex-start; gap: var(--ks-space-4); }
.ks-mcard__title { flex: 1; min-width: 0; margin: 0; font-size: var(--ks-text-small); line-height: var(--ks-lh-small); font-weight: var(--ks-weight-semibold); letter-spacing: var(--ks-tracking-normal); color: var(--ks-text-strong); }
.ks-mcard__title--mono { font-family: var(--ks-font-mono); }
.ks-mcard__link { color: inherit; font-weight: inherit; }
.ks-mcard__link::after { content: ""; position: absolute; inset: 0; border-radius: var(--ks-radius-xl); }
.ks-mcard__link:hover { color: inherit; text-decoration: none; }
.ks-mcard__link:focus-visible { outline: 0; }
.ks-mcard__link:focus-visible::after { outline: var(--ks-focus-w) solid var(--ks-focus-ring); outline-offset: var(--ks-focus-offset); }
.ks-mcard__chevron { width: var(--ksc-icon-md); height: var(--ksc-icon-md); color: var(--ks-text-muted); }
.ks-mcard__meta { font-family: var(--ks-font-mono); font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); color: var(--ks-text-muted); }
.ks-mcard__amount { font-family: var(--ks-font-mono); font-size: var(--ks-text-small); font-weight: var(--ks-weight-semibold); color: var(--ks-text-strong); }
.ks-mcard__text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--ks-text-dense); color: var(--ks-text-default); }
.ks-mcard .ks-cluster { position: relative; }

/* ---- Marketing site ------------------------------------------------------------------ */
.ks-site { background: var(--ks-surface-app); }
.ks-site__nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ks-space-9);
  padding: calc(var(--ks-space-5) + var(--ks-space-1)) var(--ks-space-9);
  background: var(--ks-surface-card);
  border-bottom: var(--ks-border-w) solid var(--ks-border);
}
.ks-site__links { display: flex; flex-wrap: wrap; gap: var(--ks-space-8); }
.ks-site__links a { color: var(--ks-text-default); font-size: var(--ks-text-small); }
.ks-site__hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  align-items: center;
  gap: var(--ks-space-11);
  padding: var(--ks-space-11) var(--ks-space-9) var(--ks-space-12);
  background: var(--ks-surface-section);
}
.ks-site__accent { color: var(--ks-blue-600); }
[data-theme="dark"] .ks-site__accent { color: var(--ks-text-accent); }
@media (prefers-color-scheme: dark) { :where(:root:not([data-ks-theme-fixed])):not([data-theme]) .ks-site__accent { color: var(--ks-text-accent); } }
.ks-site__lead { max-width: calc(var(--ks-space-10) * 11); font-size: var(--ks-text-body); line-height: var(--ks-lh-body); color: var(--ks-text-muted); }
.ks-site__preview { position: relative; }
.ks-site__toast { position: absolute; right: calc(var(--ks-space-5) * -1); bottom: calc(var(--ks-space-7) * -1); }
.ks-site__app {
  display: flex;
  height: calc(var(--ks-space-12) * 5.625);
  overflow: hidden;
  background: var(--ks-surface-card);
  border: var(--ks-border-w) solid var(--ks-border);
  border-radius: var(--ks-radius-2xl);
  box-shadow: var(--ks-shadow-lg);
}
.ks-site__app-nav { display: flex; flex-direction: column; gap: var(--ks-space-2); flex: none; width: calc(var(--ks-space-12) * 2.0625); padding: calc(var(--ks-space-5) + var(--ks-space-1)); border-right: var(--ks-border-w) solid var(--ks-border); }
.ks-site__app-nav .ks-sidenav__item { min-height: var(--ks-control-h-sm); font-size: var(--ks-text-caption); gap: var(--ks-space-3); padding: var(--ks-space-2) var(--ks-space-4); }
.ks-site__app-main { display: flex; flex-direction: column; gap: var(--ks-space-5); flex: 1; min-width: 0; padding: var(--ks-space-6); background: var(--ks-surface-app); }
.ks-bars { display: flex; flex: 1; align-items: flex-end; gap: var(--ks-space-4); min-height: calc(var(--ks-space-12) * 1.5); }
.ks-bars__bar { flex: 1; border-radius: var(--ks-radius-xs) var(--ks-radius-xs) 0 0; background: var(--ks-blue-600); }
.ks-bars__bar--alt { background: var(--ks-blue-400); }
.ks-bars__bar--h38 { height: 38%; } .ks-bars__bar--h52 { height: 52%; } .ks-bars__bar--h30 { height: 30%; }
.ks-bars__bar--h64 { height: 64%; } .ks-bars__bar--h46 { height: 46%; } .ks-bars__bar--h72 { height: 72%; }
.ks-bars__bar--h58 { height: 58%; } .ks-bars__bar--h80 { height: 80%; } .ks-bars__bar--h44 { height: 44%; }
.ks-bars__bar--h66 { height: 66%; }
.ks-site__features { display: flex; flex-direction: column; gap: var(--ks-space-9); padding: var(--ks-space-11) var(--ks-space-9) var(--ks-space-12); background: var(--ks-surface-card); }
.ks-feature {
  display: flex;
  flex-direction: column;
  gap: calc(var(--ks-space-4) + var(--ks-space-1));
  padding: var(--ks-space-7);
  background: var(--ks-surface-card);
  border: var(--ks-border-w) solid var(--ks-border);
  border-radius: var(--ks-radius-2xl);
  box-shadow: var(--ks-shadow-xs);
}
.ks-feature__title { margin: 0; font-size: var(--ks-text-body); line-height: var(--ks-lh-body); font-weight: var(--ks-weight-semibold); letter-spacing: var(--ks-tracking-normal); }
.ks-feature__text { font-size: var(--ks-text-small); line-height: var(--ks-lh-small); color: var(--ks-text-muted); }
.ks-site__cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ks-space-8);
  padding: var(--ks-space-10) var(--ks-space-9);
  background: var(--ks-gradient-dark);
  color: var(--ks-white);
}
.ks-site__cta-title { margin: 0; color: var(--ks-white); font-size: var(--ks-text-h3); line-height: var(--ks-lh-h3); }
.ks-site__cta-text { color: var(--ksc-on-navy-muted); font-size: var(--ks-text-small); }
.ks-site__footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ks-space-6);
  padding: var(--ks-space-8) var(--ks-space-9);
  background: var(--ks-surface-card);
  border-top: var(--ks-border-w) solid var(--ks-border);
  font-size: var(--ks-text-dense);
  color: var(--ks-text-muted);
}
@media (max-width: 900px) {
  .ks-site__hero { grid-template-columns: minmax(0, 1fr); padding: var(--ks-space-9) var(--ks-space-6); }
  .ks-site__nav, .ks-site__features, .ks-site__cta, .ks-site__footer { padding-inline: var(--ks-space-6); }
  .ks-site__app-nav { display: none; }
  .ks-site__toast { position: static; margin-top: var(--ks-space-5); }
  .ks-display { font-size: var(--ks-text-h2); line-height: var(--ks-lh-h2); }
}

/* ---- css/src/62-kit-invoices.css ---- */
/* ==========================================================================
   62 · UI kit — invoice screens (panels, inset tables, meter, rule cards)
   ========================================================================== */

/* Panel: a compact ks-card with a title row, optional note and stacked body. */
.ks-inv-panel { display: flex; flex-direction: column; gap: var(--ks-space-5); }
.ks-inv-panel__head { display: flex; align-items: center; gap: var(--ks-space-4); min-width: 0; }
.ks-inv-panel__title {
  flex: 1;
  margin: 0;
  font-size: var(--ks-text-small);
  line-height: var(--ks-lh-small);
  font-weight: var(--ks-weight-semibold);
  color: var(--ks-text-strong);
}
.ks-inv-panel__note {
  margin: calc(var(--ks-space-3) * -1) 0 0;
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-caption);
  color: var(--ks-text-muted);
}

/* Table nested in a panel: sunken header, frame kept but no extra shadow. */
.ks-inv-inset .ks-table__scroll { border-radius: var(--ks-radius-lg); }
.ks-inv-inset .ks-table__table thead th { background: var(--ks-surface-sunken); }

/* Totals that span the whole panel width (settlement summary). */
.ks-inv-totals--full { grid-template-columns: minmax(0, 1fr) auto; justify-content: stretch; }

/* Rule card inside a list. */
.ks-inv-rule { display: flex; flex-direction: column; gap: var(--ks-space-1); box-shadow: var(--ks-shadow-none); }

/* Progress meter on a native <progress>. */
.ks-inv-meter {
  display: block;
  width: 100%;
  height: var(--ks-space-4);
  border: 0;
  border-radius: var(--ks-radius-pill);
  overflow: hidden;
  background: var(--ks-surface-sunken);
  color: var(--ks-action-bg);
  appearance: none;
}
.ks-inv-meter::-webkit-progress-bar { background: var(--ks-surface-sunken); border-radius: var(--ks-radius-pill); }
.ks-inv-meter::-webkit-progress-value { background: var(--ks-action-bg); border-radius: var(--ks-radius-pill); }
.ks-inv-meter::-moz-progress-bar { background: var(--ks-action-bg); border-radius: var(--ks-radius-pill); }

/* The advances a settlement (or its correction) settles, in the parallel period (FR-076). Each is
   a sunken fieldset: a parallel advance is one select, an advance from before the run is four
   fields. The fields wrap; the remove button (a submit, so it works without script) stays last. */
.ks-inv-settles { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--ks-space-4); }
.ks-inv-settle {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--ks-space-4);
  min-width: 0;
  margin: 0;
  padding: var(--ks-space-4) var(--ks-space-5) var(--ks-space-5);
  background: var(--ks-surface-sunken);
  border: var(--ks-border-w) solid var(--ks-border);
  border-radius: var(--ks-radius-lg);
}
.ks-inv-settle > legend {
  padding: 0 var(--ks-space-2);
  font-size: var(--ks-text-dense);
  font-weight: var(--ks-weight-medium);
  color: var(--ks-text-strong);
}
.ks-inv-settle__fields {
  flex: 1 1 calc(var(--ks-space-12) * 5);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(calc(var(--ks-space-12) * 2.5), 1fr));
  gap: var(--ks-space-4);
  min-width: 0;
}
/* When the fields fill the width (a phone), the remove button drops to its own line: keep it at
   the end, where it sat. */
.ks-inv-settle > .ks-btn { margin-inline-start: auto; }
/* The KSeF number is 35 characters: it takes a whole row. */
.ks-inv-settle__wide { grid-column: 1 / -1; }
.ks-inv-settle:has([aria-invalid="true"]) { border-color: var(--ksc-edge-danger); }

/* Segmented switch inside a panel wraps instead of overflowing on narrow screens. */
.ks-inv-panel .ks-tabs--segmented .ks-tabs__list { flex-wrap: wrap; max-width: 100%; }

/* ---- css/src/63-kit-admin.css ---- */
/* ui_kits/ksiego-app — admin, contractor and catalog screens (kit_admin.py). */

/* Card header row: title + small action (JSX Panel `action`). */
.ks-cardhead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ks-space-3);
  margin-bottom: var(--ks-space-5);
}
.ks-cardhead .ks-card__title { margin: 0; }

/* A grid child spanning every column (full-width field in a 2-column form grid). */
.ks-span-all { grid-column: 1 / -1; }

/* Row action clusters stay on one line in the table, but wrap in the ≤480px card list. */
@container ks-table (max-width: 480px) {
  .ks-table__table .ks-cluster--nowrap { flex-wrap: wrap; justify-content: flex-start; }
}

/* ---- css/src/64-kit-mobile-site.css ---- */
/* ==========================================================================
   64 · UI kit helpers — mobile screens and marketing site
   ========================================================================== */

/* Quick-filter chips rendered as links (mobile toolbar) */
a.ks-chip:hover { background: var(--ks-surface-hover); text-decoration: none; }
.ks-m__chips .ks-chip[data-state="active"] .ks-chip__main,
.ks-m__chips .ks-chip[data-state="active"] .ks-chip__clear { text-decoration: none; }

/* Marketing site */
.ks-site__eyebrow { color: var(--ks-text-accent); }
.ks-site__cta-body { flex: 1 1 auto; min-width: min(100%, calc(var(--ks-space-10) * 7)); }
.ks-site__preview { margin: 0; }
.ks-site__range {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: var(--ks-space-2);
  padding: var(--ks-space-1) var(--ks-space-4);
  border: var(--ks-border-w) solid var(--ks-border);
  border-radius: var(--ks-radius-md);
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-caption);
  color: var(--ks-text-muted);
}
.ks-site__range .ks-icon { width: var(--ksc-icon-xs); height: var(--ksc-icon-xs); }
.ks-site__stats { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 600px) {
  .ks-site__app { height: auto; }
  .ks-site__app-main { padding: var(--ks-space-5); }
  .ks-site__stats .ks-stat { padding: var(--ks-space-4); }
  .ks-site__stats .ks-stat__value { font-size: var(--ks-text-dense); line-height: var(--ks-lh-dense); }
}

/* ---- css/src/70-touch.css ---- */
/* ---- Touch targets at phone width ----------------------------------------------------------
   README: "every tap target is at least ks-touch-min 44px" at 390px. The application has one
   shell that responds to width (not the ks-m kit shell), so this layer is width-driven.
   Controls grow through their height tokens; text links and small icons keep their drawn size
   and get an invisible 44px hit area (a pseudo-element), so the layout does not move.
   Deliberate exception: ClientMarker's strip icons (24px, 2px apart) stay as drawn. They open a
   tooltip and change nothing, and 44px each would push the strip past a card's width. */
@media (max-width: 480px) {
  :root {
    --ks-control-h: var(--ks-touch-min);
    --ks-control-h-sm: var(--ks-touch-min);
    --ksc-square-sm: var(--ks-touch-min);
  }

  .ks-sidenav__item,
  .ks-clientbar,
  .ks-usermenu__trigger { min-height: var(--ks-touch-min); }
  .ks-usermenu__trigger { min-width: var(--ks-touch-min); }

  .ks-check { min-width: var(--ks-touch-min); min-height: var(--ks-touch-min); justify-content: center; }
  /* A bare checkbox (a table's select cell has no label) keeps its 18px drawing; the invisible
     ::after is part of the input's box, so a tap on it toggles the input. */
  .ks-check__input::after {
    content: "";
    position: absolute;
    inset: calc((var(--ksc-check) - var(--ks-touch-min)) / 2);
  }
  .ks-table__table .ks-table__select { overflow: visible; }
  /* A card cell's children get min-width: 0 (20-data.css), which beat .ks-check's 44. The label
     grows around the checkbox, so the box itself stays where it was drawn. */
  .ks-table__table tbody td.ks-table__select > .ks-check {
    min-width: var(--ks-touch-min);
    margin-inline-start: calc((var(--ksc-check) - var(--ks-touch-min)) / 2);
  }
  /* The tab overlaps the list's bottom border by 1px and the list clips at that border (it
     scrolls sideways), so 1px of a 44px tab could not be reached. */
  .ks-tabs__tab { height: calc(var(--ks-touch-min) + var(--ks-border-w)); }
  /* The switch is 44 wide but 24 tall; ::before is its thumb, ::after the missing height. */
  .ks-switch { min-height: var(--ks-touch-min); }
  .ks-switch__input::after {
    content: "";
    position: absolute;
    inset: calc((var(--ksc-switch-h) - var(--ks-touch-min)) / 2) 0;
  }
  .ks-chip__clear { min-width: var(--ks-touch-min); justify-content: center; }

  /* Text links, the logo link and badge links: an invisible 44px box centred on the element (never
     smaller than the element). Unlike padding, it does not depend on display or line height: an
     inline link's box is the font's content height, not 1lh, and padding came out 2px short. */
  .ks-breadcrumbs a,
  .ks-table__primary,
  .ks-table__sort,
  .ks-btn--link,
  a.ks-logo,
  a.ks-badge,
  a.ks-link-quiet,
  .ks-auth a { position: relative; }
  .ks-breadcrumbs a::after,
  .ks-table__primary::after,
  .ks-table__sort::after,
  .ks-btn--link::after,
  a.ks-logo::after,
  a.ks-badge::after,
  a.ks-link-quiet::after,
  .ks-auth a::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: max(100%, var(--ks-touch-min));
    height: max(100%, var(--ks-touch-min));
    transform: translate(-50%, -50%);
  }
}

/* ---- css/src/90-docs.css ---- */
/* ==========================================================================
   90 · Documentation helpers — preview pages and guideline specimens only.
   Namespaced .ks-doc-*; safe to ship, never needed by product screens.
   ========================================================================== */
.ks-doc { padding: var(--ks-space-8); }
.ks-doc__header { display: flex; flex-direction: column; gap: var(--ks-space-3); max-width: var(--ks-content-max); margin: 0 auto var(--ks-space-8); }
.ks-doc__back { font-size: var(--ks-text-dense); }
.ks-doc__title { font-size: var(--ks-text-h3); line-height: var(--ks-lh-h3); }
.ks-doc__lead { font-size: var(--ks-text-small); line-height: var(--ks-lh-small); color: var(--ks-text-muted); max-width: calc(var(--ks-space-12) * 11); }
.ks-doc__panes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--ks-space-6); align-items: start; }
.ks-doc__panes--single { grid-template-columns: minmax(0, 1fr); }
@media (max-width: 1100px) { .ks-doc__panes { grid-template-columns: minmax(0, 1fr); } }
.ks-doc-pane {
  display: flex;
  flex-direction: column;
  gap: var(--ks-space-8);
  min-width: 0;
  padding: var(--ks-space-8);
  background: var(--ks-surface-app);
  color: var(--ks-text-default);
  border: var(--ks-border-w) solid var(--ks-border);
  border-radius: var(--ks-radius-xl);
}
.ks-doc-pane__label { align-self: flex-start; }
.ks-doc-pane[data-theme="dark"] .ks-logo:not(.ks-logo--on-dark) .ks-logo__img--light { display: none; }
.ks-doc-pane[data-theme="dark"] .ks-logo:not(.ks-logo--on-dark) .ks-logo__img--dark { display: block; }
.ks-doc-pane[data-theme="dark"] .ks-theme-toggle__sun { display: inline-block; }
.ks-doc-pane[data-theme="dark"] .ks-theme-toggle__moon { display: none; }
.ks-doc-section { display: flex; flex-direction: column; gap: var(--ks-space-5); min-width: 0; }
.ks-doc-section > .ks-btn { align-self: flex-start; }
.ks-doc-section__title {
  margin: 0;
  font-size: var(--ks-text-caption);
  line-height: var(--ks-lh-caption);
  font-weight: var(--ks-weight-semibold);
  letter-spacing: var(--ks-tracking-caps);
  text-transform: uppercase;
  color: var(--ks-text-muted);
}
.ks-doc-note { font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); color: var(--ks-text-muted); }
.ks-doc-frame { width: calc(var(--ks-space-12) * 5.75); max-width: 100%; }
.ks-doc-frame--wide { width: 100%; }
.ks-doc-stage { position: relative; min-height: calc(var(--ks-space-12) * 3.5); border: var(--ks-border-w) dashed var(--ks-border-strong); border-radius: var(--ks-radius-lg); overflow: hidden; }
.ks-doc-stage .ks-toast-stack { position: absolute; }
.ks-doc-index { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(calc(var(--ks-space-12) * 3.5), 1fr)); gap: var(--ks-space-4); }
.ks-doc-index > li { position: relative; display: flex; flex-direction: column; gap: var(--ks-space-1); padding: var(--ks-space-5) var(--ks-space-6); background: var(--ks-surface-card); border: var(--ks-border-w) solid var(--ks-border); border-radius: var(--ks-radius-lg); transition: var(--ks-transition-control); }
.ks-doc-index > li:hover { border-color: var(--ks-focus-ring); }
.ks-doc-index > li > a:first-child { font-weight: var(--ks-weight-semibold); }
.ks-doc-index > li > a:first-child::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.ks-doc-index > li > a:first-child:hover { text-decoration: none; }
.ks-doc-index__meta { position: relative; display: block; font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); font-weight: var(--ks-weight-regular); color: var(--ks-text-muted); }
a.ks-doc-index__meta { align-self: flex-start; color: var(--ks-text-link); }

/* ---- Guideline specimens ---------------------------------------------------- */
.ks-swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(calc(var(--ks-space-12) * 2), 1fr)); gap: var(--ks-space-4); }
.ks-swatch { display: flex; flex-direction: column; overflow: hidden; background: var(--ks-surface-card); border: var(--ks-border-w) solid var(--ks-border); border-radius: var(--ks-radius-md); }
.ks-swatch__chip { display: block; height: var(--ks-control-h-lg); border-bottom: var(--ks-border-w) solid var(--ks-border); }
.ks-swatch__name { padding: var(--ks-space-2) var(--ks-space-3) 0; font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); font-weight: var(--ks-weight-semibold); color: var(--ks-text-strong); }
.ks-swatch__token { padding: 0 var(--ks-space-3) var(--ks-space-2); font-family: var(--ks-font-mono); font-size: var(--ks-text-caption); line-height: var(--ks-lh-caption); color: var(--ks-text-muted); overflow-wrap: anywhere; }
.ks-pair { padding: var(--ks-space-4) var(--ks-space-5); border-radius: var(--ks-radius-md); font-size: var(--ks-text-dense); font-weight: var(--ks-weight-semibold); }
.ks-pair__token { display: block; margin-top: var(--ks-space-1); font-family: var(--ks-font-mono); font-size: var(--ks-text-caption); font-weight: var(--ks-weight-regular); }
.ks-pair--success { background: var(--ks-status-success-bg); color: var(--ks-status-success-fg); }
.ks-pair--warning { background: var(--ks-status-warning-bg); color: var(--ks-status-warning-fg); }
.ks-pair--danger { background: var(--ks-status-danger-bg); color: var(--ks-status-danger-fg); }
.ks-pair--info { background: var(--ks-status-info-bg); color: var(--ks-status-info-fg); }
.ks-pair--progress { background: var(--ks-status-progress-bg); color: var(--ks-status-progress-fg); }
.ks-pair--neutral { background: var(--ks-status-neutral-bg); color: var(--ks-status-neutral-fg); }
.ks-pair--registry { background: var(--ks-registry-bg); color: var(--ks-registry-fg); border: var(--ks-border-w) solid var(--ks-registry-border); }
.ks-pair--manual { background: var(--ks-manual-bg); color: var(--ks-manual-fg); }
.ks-gradient { height: calc(var(--ks-space-12) + var(--ks-space-4)); border-radius: var(--ks-radius-2xl); }
.ks-gradient--brand { background: var(--ks-gradient-brand); }
.ks-gradient--dark { background: var(--ks-gradient-dark); }
.ks-specimen-scale { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--ks-space-6); }
.ks-specimen-scale__item { display: flex; flex-direction: column; align-items: center; gap: var(--ks-space-2); font-family: var(--ks-font-mono); font-size: var(--ks-text-caption); color: var(--ks-text-muted); }
.ks-space-bar { display: block; height: var(--ks-space-9); background: var(--ks-blue-400); border-radius: var(--ks-space-1); }
.ks-radius-box { display: block; width: var(--ks-space-12); height: calc(var(--ks-space-11) + var(--ks-space-4)); background: var(--ks-surface-sunken); border: var(--ks-border-w) solid var(--ks-border-strong); }
.ks-shadow-box { display: block; width: calc(var(--ks-space-12) * 1.5); height: var(--ks-space-12); background: var(--ks-surface-card); border: var(--ks-border-w) solid var(--ks-border); border-radius: var(--ks-radius-xl); }
.ks-rails { overflow: hidden; border: var(--ks-border-w) solid var(--ks-border); border-radius: var(--ks-radius-lg); }
.ks-rails__bar { display: flex; align-items: center; height: var(--ks-space-9); padding: 0 var(--ks-space-4); background: var(--ks-navy-900); color: var(--ks-white); font-size: var(--ks-text-caption); }
.ks-rails__body { display: flex; min-height: calc(var(--ks-space-12) + var(--ks-space-6)); }
.ks-rails__nav { width: calc(var(--ks-space-12) * 2.3); padding: var(--ks-space-4); background: var(--ks-surface-card); border-right: var(--ks-border-w) solid var(--ks-border); font-size: var(--ks-text-caption); color: var(--ks-text-muted); }
.ks-rails__main { display: flex; flex-direction: column; gap: var(--ks-space-3); flex: 1; padding: var(--ks-space-4); background: var(--ks-surface-app); }
.ks-rails__row { display: flex; align-items: center; height: calc(var(--ks-space-8) + var(--ks-space-1)); padding: 0 var(--ks-space-4); background: var(--ks-surface-card); border: var(--ks-border-w) solid var(--ks-border); border-radius: var(--ks-radius-sm); font-size: var(--ks-text-caption); color: var(--ks-text-muted); }
.ks-logo-tile { display: flex; align-items: center; justify-content: center; min-height: calc(var(--ks-space-12) + var(--ks-space-11)); padding: var(--ks-space-6); border: var(--ks-border-w) solid var(--ks-border); border-radius: var(--ks-radius-lg); }
.ks-logo-tile--app { background: var(--ks-surface-app); }
.ks-logo-tile--white { background: var(--ks-white); }
.ks-logo-tile--navy { background: var(--ks-navy-900); }
.ks-logo-tile--sunken { background: var(--ks-surface-sunken); }
.ks-logo-tile img { height: var(--ks-space-11); width: auto; }
.ks-specimen-img { width: auto; height: calc(var(--ks-space-12) + var(--ks-space-6)); }
.ks-glyphs { display: grid; grid-template-columns: repeat(auto-fill, minmax(calc(var(--ks-space-12) * 1.4), 1fr)); gap: var(--ks-space-3); }
.ks-glyphs__item { display: flex; flex-direction: column; align-items: center; gap: var(--ks-space-2); padding: var(--ks-space-4) var(--ks-space-2); background: var(--ks-surface-card); border: var(--ks-border-w) solid var(--ks-border); border-radius: var(--ks-radius-xl); color: var(--ks-text-accent); }
.ks-glyphs__name { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--ks-font-mono); font-size: var(--ks-text-caption); color: var(--ks-text-muted); }

/* Generated from tokens.json */
.ks-swatch--navy-900 .ks-swatch__chip { background: var(--ks-navy-900); }
.ks-swatch--navy-800 .ks-swatch__chip { background: var(--ks-navy-800); }
.ks-swatch--navy-700 .ks-swatch__chip { background: var(--ks-navy-700); }
.ks-swatch--blue-700 .ks-swatch__chip { background: var(--ks-blue-700); }
.ks-swatch--blue-600 .ks-swatch__chip { background: var(--ks-blue-600); }
.ks-swatch--blue-500 .ks-swatch__chip { background: var(--ks-blue-500); }
.ks-swatch--blue-400 .ks-swatch__chip { background: var(--ks-blue-400); }
.ks-swatch--blue-200 .ks-swatch__chip { background: var(--ks-blue-200); }
.ks-swatch--blue-100 .ks-swatch__chip { background: var(--ks-blue-100); }
.ks-swatch--blue-50 .ks-swatch__chip { background: var(--ks-blue-50); }
.ks-swatch--gray-900 .ks-swatch__chip { background: var(--ks-gray-900); }
.ks-swatch--gray-700 .ks-swatch__chip { background: var(--ks-gray-700); }
.ks-swatch--gray-500 .ks-swatch__chip { background: var(--ks-gray-500); }
.ks-swatch--gray-400 .ks-swatch__chip { background: var(--ks-gray-400); }
.ks-swatch--gray-300 .ks-swatch__chip { background: var(--ks-gray-300); }
.ks-swatch--gray-200 .ks-swatch__chip { background: var(--ks-gray-200); }
.ks-swatch--gray-100 .ks-swatch__chip { background: var(--ks-gray-100); }
.ks-swatch--gray-50 .ks-swatch__chip { background: var(--ks-gray-50); }
.ks-swatch--white .ks-swatch__chip { background: var(--ks-white); }
.ks-swatch--green-700 .ks-swatch__chip { background: var(--ks-green-700); }
.ks-swatch--green-600 .ks-swatch__chip { background: var(--ks-green-600); }
.ks-swatch--green-50 .ks-swatch__chip { background: var(--ks-green-50); }
.ks-swatch--amber-700 .ks-swatch__chip { background: var(--ks-amber-700); }
.ks-swatch--amber-500 .ks-swatch__chip { background: var(--ks-amber-500); }
.ks-swatch--amber-50 .ks-swatch__chip { background: var(--ks-amber-50); }
.ks-swatch--red-700 .ks-swatch__chip { background: var(--ks-red-700); }
.ks-swatch--red-600 .ks-swatch__chip { background: var(--ks-red-600); }
.ks-swatch--red-50 .ks-swatch__chip { background: var(--ks-red-50); }
.ks-swatch--violet-700 .ks-swatch__chip { background: var(--ks-violet-700); }
.ks-swatch--violet-50 .ks-swatch__chip { background: var(--ks-violet-50); }
.ks-swatch--surface-app .ks-swatch__chip { background: var(--ks-surface-app); }
.ks-swatch--surface-card .ks-swatch__chip { background: var(--ks-surface-card); }
.ks-swatch--surface-sunken .ks-swatch__chip { background: var(--ks-surface-sunken); }
.ks-swatch--surface-section .ks-swatch__chip { background: var(--ks-surface-section); }
.ks-swatch--surface-inverse .ks-swatch__chip { background: var(--ks-surface-inverse); }
.ks-swatch--surface-hover .ks-swatch__chip { background: var(--ks-surface-hover); }
.ks-swatch--surface-selected .ks-swatch__chip { background: var(--ks-surface-selected); }
.ks-swatch--surface-disabled .ks-swatch__chip { background: var(--ks-surface-disabled); }
.ks-swatch--text-strong .ks-swatch__chip { background: var(--ks-text-strong); }
.ks-swatch--text-default .ks-swatch__chip { background: var(--ks-text-default); }
.ks-swatch--text-muted .ks-swatch__chip { background: var(--ks-text-muted); }
.ks-swatch--text-subtle .ks-swatch__chip { background: var(--ks-text-subtle); }
.ks-swatch--text-inverse .ks-swatch__chip { background: var(--ks-text-inverse); }
.ks-swatch--text-link .ks-swatch__chip { background: var(--ks-text-link); }
.ks-swatch--text-accent .ks-swatch__chip { background: var(--ks-text-accent); }
.ks-swatch--border .ks-swatch__chip { background: var(--ks-border); }
.ks-swatch--border-strong .ks-swatch__chip { background: var(--ks-border-strong); }
.ks-swatch--border-accent .ks-swatch__chip { background: var(--ks-border-accent); }
.ks-swatch--border-inverse .ks-swatch__chip { background: var(--ks-border-inverse); }
.ks-swatch--focus-ring .ks-swatch__chip { background: var(--ks-focus-ring); }
.ks-swatch--focus-ring-offset .ks-swatch__chip { background: var(--ks-focus-ring-offset); }
.ks-swatch--action-bg .ks-swatch__chip { background: var(--ks-action-bg); }
.ks-swatch--action-bg-hover .ks-swatch__chip { background: var(--ks-action-bg-hover); }
.ks-swatch--action-bg-active .ks-swatch__chip { background: var(--ks-action-bg-active); }
.ks-swatch--action-fg .ks-swatch__chip { background: var(--ks-action-fg); }
.ks-swatch--action-secondary-bg .ks-swatch__chip { background: var(--ks-action-secondary-bg); }
.ks-swatch--action-secondary-bg-hover .ks-swatch__chip { background: var(--ks-action-secondary-bg-hover); }
.ks-swatch--action-secondary-fg .ks-swatch__chip { background: var(--ks-action-secondary-fg); }
.ks-swatch--status-success-fg .ks-swatch__chip { background: var(--ks-status-success-fg); }
.ks-swatch--status-success-bg .ks-swatch__chip { background: var(--ks-status-success-bg); }
.ks-swatch--status-warning-fg .ks-swatch__chip { background: var(--ks-status-warning-fg); }
.ks-swatch--status-warning-bg .ks-swatch__chip { background: var(--ks-status-warning-bg); }
.ks-swatch--status-danger-fg .ks-swatch__chip { background: var(--ks-status-danger-fg); }
.ks-swatch--status-danger-bg .ks-swatch__chip { background: var(--ks-status-danger-bg); }
.ks-swatch--status-info-fg .ks-swatch__chip { background: var(--ks-status-info-fg); }
.ks-swatch--status-info-bg .ks-swatch__chip { background: var(--ks-status-info-bg); }
.ks-swatch--status-neutral-fg .ks-swatch__chip { background: var(--ks-status-neutral-fg); }
.ks-swatch--status-neutral-bg .ks-swatch__chip { background: var(--ks-status-neutral-bg); }
.ks-swatch--status-progress-fg .ks-swatch__chip { background: var(--ks-status-progress-fg); }
.ks-swatch--status-progress-bg .ks-swatch__chip { background: var(--ks-status-progress-bg); }
.ks-swatch--registry-bg .ks-swatch__chip { background: var(--ks-registry-bg); }
.ks-swatch--registry-fg .ks-swatch__chip { background: var(--ks-registry-fg); }
.ks-swatch--registry-border .ks-swatch__chip { background: var(--ks-registry-border); }
.ks-swatch--manual-bg .ks-swatch__chip { background: var(--ks-manual-bg); }
.ks-swatch--manual-fg .ks-swatch__chip { background: var(--ks-manual-fg); }
.ks-space-bar--space-0 { width: var(--ks-space-0); }
.ks-space-bar--space-1 { width: var(--ks-space-1); }
.ks-space-bar--space-2 { width: var(--ks-space-2); }
.ks-space-bar--space-3 { width: var(--ks-space-3); }
.ks-space-bar--space-4 { width: var(--ks-space-4); }
.ks-space-bar--space-5 { width: var(--ks-space-5); }
.ks-space-bar--space-6 { width: var(--ks-space-6); }
.ks-space-bar--space-7 { width: var(--ks-space-7); }
.ks-space-bar--space-8 { width: var(--ks-space-8); }
.ks-space-bar--space-9 { width: var(--ks-space-9); }
.ks-space-bar--space-10 { width: var(--ks-space-10); }
.ks-space-bar--space-11 { width: var(--ks-space-11); }
.ks-space-bar--space-12 { width: var(--ks-space-12); }
.ks-radius-box--radius-xs { border-radius: var(--ks-radius-xs); }
.ks-radius-box--radius-sm { border-radius: var(--ks-radius-sm); }
.ks-radius-box--radius-md { border-radius: var(--ks-radius-md); }
.ks-radius-box--radius-lg { border-radius: var(--ks-radius-lg); }
.ks-radius-box--radius-xl { border-radius: var(--ks-radius-xl); }
.ks-radius-box--radius-2xl { border-radius: var(--ks-radius-2xl); }
.ks-radius-box--radius-pill { border-radius: var(--ks-radius-pill); }
.ks-shadow-box--shadow-none { box-shadow: var(--ks-shadow-none); }
.ks-shadow-box--shadow-xs { box-shadow: var(--ks-shadow-xs); }
.ks-shadow-box--shadow-sm { box-shadow: var(--ks-shadow-sm); }
.ks-shadow-box--shadow-md { box-shadow: var(--ks-shadow-md); }
.ks-shadow-box--shadow-lg { box-shadow: var(--ks-shadow-lg); }
.ks-shadow-box--shadow-modal { box-shadow: var(--ks-shadow-modal); }
.ks-shadow-box--shadow-focus { box-shadow: var(--ks-shadow-focus); }
.ks-shadow-box--shadow-inset-top { box-shadow: var(--ks-shadow-inset-top); }
