/* ==========================================================================
   kvyk.css — the kvyk.ai design system
   --------------------------------------------------------------------------
   A single, framework-free stylesheet. No Tailwind, no build step.
   Drop it into any page with:  <link rel="stylesheet" href="kvyk.css">

   Contents
     1. Fonts          — self-hosted @font-face (Inter + JetBrains Mono)
     2. Tokens         — :root design variables (color, space, type, etc.)
     3. Reset & base   — minimal normalize + sensible element defaults
     4. Typography     — .kvyk-display / headline / body / label / overline
     5. Layout         — container, stack, cluster, grid, app-shell, surfaces
     6. Components      — buttons, fields, cards, nav, chat, stepper, …
     7. Utilities       — a small, deliberate helper set (not a framework)

   Conventions
     • Tokens are CSS custom properties prefixed  --kvyk-*
     • Components use a  kvyk-  prefix with BEM-style modifiers:
         block        .kvyk-btn
         element      .kvyk-card__header
         variant      .kvyk-btn--accent
         state        .is-active / [aria-current] / [disabled] / [aria-invalid]
     • Component colors are driven by local --_* vars so variants only
       re-map a few values instead of re-declaring every rule.
   ========================================================================== */

/* ==========================================================================
   1. FONTS
   ========================================================================== */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/Inter-Regular.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/Inter-Medium.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/Inter-SemiBold.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/Inter-Bold.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 900;
  font-display: swap;
  src: url("fonts/Inter-Black.woff2") format("woff2");
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/JetBrainsMono-Regular.woff2") format("woff2");
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/JetBrainsMono-Medium.woff2") format("woff2");
}

/* ==========================================================================
   2. TOKENS
   --------------------------------------------------------------------------
   The single source of truth. Everything below references these. Re-theming
   = override these variables (e.g. on a [data-theme] or a scoped container).
   ========================================================================== */
:root {
  color-scheme: light;

  /* ---- Brand --------------------------------------------------------- */
  --kvyk-brand-mark: #3b82f6;          /* logo triangle only */

  /* ---- Primary (near-black, the strong CTA / brand text) ------------- */
  --kvyk-primary: #000000;
  --kvyk-on-primary: #ffffff;
  --kvyk-primary-container: #131b2e;
  --kvyk-on-primary-container: #7c839b;
  --kvyk-primary-fixed: #dae2fd;
  --kvyk-primary-fixed-dim: #bec6e0;
  --kvyk-on-primary-fixed: #131b2e;
  --kvyk-on-primary-fixed-variant: #3f465c;

  /* ---- Secondary (electric blue — the action / accent color) --------- */
  --kvyk-secondary: #0058be;
  --kvyk-on-secondary: #ffffff;
  --kvyk-secondary-container: #2170e4;
  --kvyk-on-secondary-container: #fefcff;
  --kvyk-secondary-fixed: #d8e2ff;
  --kvyk-secondary-fixed-dim: #adc6ff;
  --kvyk-on-secondary-fixed: #001a42;
  --kvyk-on-secondary-fixed-variant: #004395;

  /* ---- Tertiary (mint green — positive / success accents) ------------ */
  --kvyk-tertiary: #000000;
  --kvyk-tertiary-container: #002113;
  --kvyk-on-tertiary-container: #009668;
  --kvyk-tertiary-fixed: #6ffbbe;
  --kvyk-tertiary-fixed-dim: #4edea3;
  --kvyk-on-tertiary-fixed: #002113;
  --kvyk-on-tertiary-fixed-variant: #005236;

  /* ---- Error --------------------------------------------------------- */
  --kvyk-error: #ba1a1a;
  --kvyk-on-error: #ffffff;
  --kvyk-error-container: #ffdad6;
  --kvyk-on-error-container: #93000a;

  /* ---- Surfaces & background (blue-tinted neutrals) ------------------ */
  --kvyk-background: #f8f9ff;
  --kvyk-on-background: #0b1c30;
  --kvyk-surface: #f8f9ff;
  --kvyk-surface-bright: #f8f9ff;
  --kvyk-surface-dim: #cbdbf5;
  --kvyk-surface-container-lowest: #ffffff;
  --kvyk-surface-container-low: #eff4ff;
  --kvyk-surface-container: #e5eeff;
  --kvyk-surface-container-high: #dce9ff;
  --kvyk-surface-container-highest: #d3e4fe;
  --kvyk-surface-variant: #d3e4fe;
  --kvyk-on-surface: #0b1c30;
  --kvyk-on-surface-variant: #45464d;

  /* ---- Lines --------------------------------------------------------- */
  --kvyk-outline: #76777d;
  --kvyk-outline-variant: #c6c6cd;

  /* ---- Inverse (dark accents on a light UI) -------------------------- */
  --kvyk-inverse-surface: #213145;
  --kvyk-inverse-on-surface: #eaf1ff;
  --kvyk-inverse-primary: #bec6e0;
  --kvyk-surface-tint: #565e74;

  /* ---- Semantic aliases (ergonomic shortcuts) ------------------------ */
  --kvyk-text: var(--kvyk-on-surface);
  --kvyk-text-muted: var(--kvyk-on-surface-variant);
  --kvyk-border: var(--kvyk-outline-variant);
  --kvyk-accent: var(--kvyk-secondary);
  /* A row or item under the pointer, and the one that is selected or open:
     the two palest steps of the neutral ramp (blue-tinted, as every neutral
     here is), so the accent blue stays for links, focus and the main action. */
  --kvyk-surface-hover: var(--kvyk-background);
  --kvyk-surface-selected: var(--kvyk-surface-container-low);
  /* A table's every other row, and the row under the pointer, a step darker
     (#225): see-through, so the shade of a table that scrolls sideways still
     shows on them. Over white they come to about #f1f6ff and #deebfe, where
     body and muted text both keep well over 4.5:1. */
  --kvyk-table-stripe: color-mix(in srgb, var(--kvyk-surface-container) 55%, transparent);
  --kvyk-table-hover: color-mix(in srgb, var(--kvyk-surface-container-highest) 75%, transparent);
  /* The shade at the edge of a table that scrolls sideways. */
  --kvyk-scroll-shadow: rgba(15, 23, 42, 0.14);

  /* ---- Typography ---------------------------------------------------- */
  --kvyk-font-sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --kvyk-font-mono: "JetBrains Mono", ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  --kvyk-weight-regular: 400;
  --kvyk-weight-medium: 500;
  --kvyk-weight-semibold: 600;
  --kvyk-weight-bold: 700;
  --kvyk-weight-black: 900;

  /* Line height: one for running text at every size, a tighter one for
     every heading. Labels, badges, buttons and table cells keep their own
     fixed lines, so the compact UI does not grow with them. */
  --kvyk-leading-body: 1.6;
  --kvyk-leading-heading: 1.25;

  /* ---- Spacing (4px base grid) --------------------------------------- */
  --kvyk-space-2xs: 2px;
  --kvyk-space-xs: 4px;
  --kvyk-space-sm: 8px;
  --kvyk-space-sm-md: 12px;
  --kvyk-space-md: 16px;
  --kvyk-space-lg: 24px;
  --kvyk-space-xl: 32px;
  --kvyk-space-2xl: 48px;
  --kvyk-space-3xl: 64px;
  /* Text after text: between paragraphs (or a paragraph and a list), and
     between a title and the line under it. */
  --kvyk-space-paragraph: var(--kvyk-space-md);
  --kvyk-space-lead: var(--kvyk-space-sm-md);
  --kvyk-gutter: 24px;
  --kvyk-margin-mobile: 16px;
  --kvyk-margin-desktop: 40px;

  /* ---- Radius (crisp, precise — small by design) --------------------- */
  --kvyk-radius-xs: 2px;
  --kvyk-radius-sm: 4px;
  --kvyk-radius-md: 8px;
  --kvyk-radius-lg: 12px;
  --kvyk-radius-xl: 16px;
  --kvyk-radius-pill: 999px;
  /* Cards and other framed blocks (tables, lists, empty states, option
     panels) are square-cornered rectangles, set apart by space. */
  --kvyk-radius-card: 0;
  --kvyk-radius-circle: 50%;

  /* ---- Elevation (soft slate shadows; light UI = restrained depth) --- */
  --kvyk-elevation-1: 0 1px 2px rgba(15, 23, 42, 0.04);
  --kvyk-elevation-2: 0 4px 12px rgba(15, 23, 42, 0.05);
  --kvyk-elevation-3: 0 12px 32px rgba(15, 23, 42, 0.10);
  --kvyk-elevation-accent: 0 4px 12px rgba(0, 88, 190, 0.20);
  --kvyk-elevation-accent-hover: 0 12px 32px rgba(0, 88, 190, 0.30);
  --kvyk-scrim: rgba(15, 23, 42, 0.32);

  /* ---- Focus ring ---------------------------------------------------- */
  --kvyk-ring-color: rgba(0, 88, 190, 0.35);
  --kvyk-ring: 0 0 0 3px var(--kvyk-ring-color);

  /* ---- Motion -------------------------------------------------------- */
  --kvyk-ease: cubic-bezier(0.4, 0, 0.2, 1);
  --kvyk-duration-fast: 120ms;
  --kvyk-duration: 200ms;
  --kvyk-duration-slow: 320ms;

  /* ---- Layout -------------------------------------------------------- */
  --kvyk-max-width: 1440px;
  --kvyk-sidebar-width: 256px;
  --kvyk-sidebar-width-collapsed: 64px;
  --kvyk-header-height: 64px;
  --kvyk-control-height: 40px;
  --kvyk-control-height-sm: 32px;
  /* The longest comfortable line of running text. */
  --kvyk-measure: 48rem;

  /* ---- Z-index ------------------------------------------------------- */
  --kvyk-z-base: 1;
  --kvyk-z-header: 30;
  --kvyk-z-nav: 40;
  --kvyk-z-overlay: 50;
  --kvyk-z-tooltip: 60;
  --kvyk-z-toast: 70;
}

/* ==========================================================================
   3. RESET & BASE
   ========================================================================== */
*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

/* The hidden attribute always hides. Components set their own display (flex,
   grid, …), which would otherwise beat the browser's [hidden] rule and show
   what a page marked hidden, such as a form's success message before submit. */
[hidden] {
  display: none !important;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  tab-size: 4;
}

body {
  font-family: var(--kvyk-font-sans);
  font-size: 16px;
  line-height: 1.5;
  font-weight: var(--kvyk-weight-regular);
  color: var(--kvyk-on-background);
  background-color: var(--kvyk-background);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

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

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

button {
  background: none;
  border: none;
  cursor: pointer;
}

a {
  color: var(--kvyk-secondary);
  text-decoration: none;
  transition: color var(--kvyk-duration) var(--kvyk-ease);
}
a:hover {
  text-decoration: underline;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--kvyk-font-sans);
  font-weight: var(--kvyk-weight-semibold);
  line-height: var(--kvyk-leading-heading);
  color: var(--kvyk-on-surface);
  text-wrap: balance;
}
h1 { font-size: 32px; letter-spacing: -0.01em; }
h2 { font-size: 24px; }
h3 { font-size: 20px; }
h4 { font-size: 16px; }

p { line-height: var(--kvyk-leading-body); }

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

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

::selection {
  background: var(--kvyk-secondary-container);
  color: var(--kvyk-on-secondary-container);
}

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

/* Thin, unobtrusive scrollbars (matches the "precise" tone) */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--kvyk-outline-variant) transparent;
}
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background-color: var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-pill);
  border: 2px solid transparent;
  background-clip: content-box;
}

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

/* ==========================================================================
   4. TYPOGRAPHY
   --------------------------------------------------------------------------
   Inter for prose and headings. JetBrains Mono for labels, metadata and UI
   chrome — the mono is a deliberate signature, not decoration.
   ========================================================================== */
.kvyk-display-lg {
  font-family: var(--kvyk-font-sans);
  font-weight: var(--kvyk-weight-bold);
  font-size: 48px;
  line-height: var(--kvyk-leading-heading);
  letter-spacing: -0.02em;
}
.kvyk-headline-lg {
  font-family: var(--kvyk-font-sans);
  font-weight: var(--kvyk-weight-semibold);
  font-size: 32px;
  line-height: var(--kvyk-leading-heading);
  letter-spacing: -0.01em;
}
.kvyk-headline-md {
  font-family: var(--kvyk-font-sans);
  font-weight: var(--kvyk-weight-semibold);
  font-size: 24px;
  line-height: var(--kvyk-leading-heading);
}
.kvyk-title {
  font-family: var(--kvyk-font-sans);
  font-weight: var(--kvyk-weight-semibold);
  font-size: 20px;
  line-height: var(--kvyk-leading-heading);
}
.kvyk-body-lg {
  font-family: var(--kvyk-font-sans);
  font-weight: var(--kvyk-weight-regular);
  font-size: 18px;
  line-height: 28px;
}
.kvyk-body-md {
  font-family: var(--kvyk-font-sans);
  font-weight: var(--kvyk-weight-regular);
  font-size: 16px;
  line-height: 24px;
}
.kvyk-body-sm {
  font-family: var(--kvyk-font-sans);
  font-weight: var(--kvyk-weight-regular);
  font-size: 14px;
  line-height: 20px;
}
.kvyk-label-md {
  font-family: var(--kvyk-font-mono);
  font-weight: var(--kvyk-weight-medium);
  font-size: 14px;
  line-height: 20px;
  letter-spacing: 0.02em;
}
.kvyk-label-sm {
  font-family: var(--kvyk-font-mono);
  font-weight: var(--kvyk-weight-medium);
  font-size: 12px;
  line-height: 16px;
}
.kvyk-overline {
  font-family: var(--kvyk-font-mono);
  font-weight: var(--kvyk-weight-medium);
  font-size: 12px;
  line-height: 16px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--kvyk-on-surface-variant);
}
.kvyk-mono { font-family: var(--kvyk-font-mono); }
/* A paragraph in a body size is running text, so it takes the body leading.
   The same class on a span in the UI (an option's hint) keeps its line. */
p:is(.kvyk-body-lg, .kvyk-body-md, .kvyk-body-sm) { line-height: var(--kvyk-leading-body); }

/* Fluid down-scaling of the largest type on small screens */
@media (max-width: 600px) {
  .kvyk-display-lg { font-size: 36px; }
  .kvyk-headline-lg { font-size: 26px; }
}

/* ==========================================================================
   5. LAYOUT PRIMITIVES
   ========================================================================== */
.kvyk-container {
  width: 100%;
  max-width: var(--kvyk-max-width);
  margin-inline: auto;
  padding-inline: var(--kvyk-margin-mobile);
}
@media (min-width: 768px) {
  .kvyk-container { padding-inline: var(--kvyk-margin-desktop); }
}

/* Vertical rhythm: stack children with a gap (default 16px). */
.kvyk-stack {
  --_flow-gap: var(--kvyk-stack-gap, var(--kvyk-space-md));
  display: flex;
  flex-direction: column;
  gap: var(--_flow-gap);
}
.kvyk-stack--xs { --kvyk-stack-gap: var(--kvyk-space-xs); }
.kvyk-stack--sm { --kvyk-stack-gap: var(--kvyk-space-sm); }
.kvyk-stack--lg { --kvyk-stack-gap: var(--kvyk-space-lg); }
.kvyk-stack--xl { --kvyk-stack-gap: var(--kvyk-space-xl); }

/* Text after text, the same everywhere, whatever stack holds it: paragraphs
   (and a paragraph and a list) --kvyk-space-paragraph apart, a title and the
   line under it --kvyk-space-lead. Each container below states its own gap as
   --_flow-gap (block ones 0), and the margin makes up only what that gap
   lacks, so gap and margin never add up past the value. A wider gap wins. */
:where(.kvyk-card, .kvyk-card__header, .kvyk-card__body, .kvyk-alert > div) { --_flow-gap: 0px; }
:where(.kvyk-stack, .kvyk-section, .kvyk-section__header, .kvyk-section__body, .kvyk-field, .kvyk-page-header__text, .kvyk-card, .kvyk-card__header, .kvyk-card__body, .kvyk-alert > div)
  > :where(p:not([class]), p:is(.kvyk-body-lg, .kvyk-body-md, .kvyk-body-sm, .kvyk-help, .kvyk-alert__body, .kvyk-section__lead):not(.kvyk-mono), ul:not([class]), ol:not([class]))
  + :where(p:not([class]), p:is(.kvyk-body-lg, .kvyk-body-md, .kvyk-body-sm, .kvyk-help, .kvyk-alert__body, .kvyk-section__lead):not(.kvyk-mono), ul:not([class]), ol:not([class])) {
  margin-top: max(0px, calc(var(--kvyk-space-paragraph) - var(--_flow-gap)));
}
:where(.kvyk-stack, .kvyk-section, .kvyk-section__header, .kvyk-section__body, .kvyk-field, .kvyk-page-header__text, .kvyk-card, .kvyk-card__header, .kvyk-card__body, .kvyk-alert > div)
  > :where(h1, h2, h3, h4, h5, h6, .kvyk-display-lg, .kvyk-headline-lg, .kvyk-headline-md, .kvyk-title, .kvyk-section__title)
  + :where(p:not([class]), p:is(.kvyk-body-lg, .kvyk-body-md, .kvyk-body-sm, .kvyk-help, .kvyk-section__lead):not(.kvyk-mono)) {
  margin-top: max(0px, calc(var(--kvyk-space-lead) - var(--_flow-gap)));
}

/* Horizontal group that wraps; vertically centered. */
.kvyk-cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--kvyk-cluster-gap, var(--kvyk-space-sm));
}
.kvyk-cluster--md { --kvyk-cluster-gap: var(--kvyk-space-md); }
.kvyk-cluster--lg { --kvyk-cluster-gap: var(--kvyk-space-lg); }
.kvyk-cluster--between { justify-content: space-between; flex-wrap: nowrap; }

/* Responsive auto grid; collapses to 1 column on small screens. */
.kvyk-grid {
  display: grid;
  gap: var(--kvyk-grid-gap, var(--kvyk-gutter));
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
}
@media (min-width: 768px) {
  .kvyk-grid--2 { grid-template-columns: repeat(2, 1fr); }
  .kvyk-grid--3 { grid-template-columns: repeat(3, 1fr); }
  .kvyk-grid--4 { grid-template-columns: repeat(4, 1fr); }
}

.kvyk-divider { border: none; border-top: 1px solid var(--kvyk-outline-variant); }
/* A divider across the whole scrolling column, edge to edge: it reaches far
   out both sides and the column (.kvyk-main) clips it. Under a page's title. */
.kvyk-divider--full { margin-inline: -100vw; }
.kvyk-divider--v {
  border-top: none;
  border-left: 1px solid var(--kvyk-outline-variant);
  align-self: stretch;
  width: 0;
}

/* Signature dot-grid texture for hero / canvas backgrounds. */
.kvyk-dotgrid {
  background-image: radial-gradient(var(--kvyk-outline-variant) 1px, transparent 1px);
  background-size: 24px 24px;
}
.kvyk-dotgrid--subtle {
  background-image: radial-gradient(var(--kvyk-on-surface) 1px, transparent 1px);
  background-size: 24px 24px;
  opacity: 0.03;
}

/* Frosted panel (used for the AI console over a textured canvas). */
.kvyk-glass {
  background: rgba(255, 255, 255, 0.7);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(198, 198, 205, 0.6);
}

/* ---- Application shell --------------------------------------------------- */
/* A white sidebar beside a scrolling main column. The sidebar's brand band and
   the app bar share the header height and its bottom rule, so the two read as
   one white header across the top, as on the public site. */
.kvyk-app-shell {
  display: flex;
  height: 100vh;
  width: 100%;
  overflow: hidden;
}
.kvyk-sidebar {
  /* Nav items pad their text 12px in from the body's edge; the brand, labels and
     footer line their text up with it. */
  --_edge: var(--kvyk-space-md);
  --_text: calc(var(--kvyk-space-md) + 12px);
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  width: var(--kvyk-sidebar-width);
  height: 100%;
  background: var(--kvyk-surface-container-lowest);
  border-right: 1px solid var(--kvyk-outline-variant);
  z-index: var(--kvyk-z-nav);
}
.kvyk-sidebar__brand {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  height: var(--kvyk-header-height);
  padding-inline: var(--_text);
  border-bottom: 1px solid var(--kvyk-outline-variant);
}
.kvyk-sidebar__body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--kvyk-space-lg);
  padding: var(--kvyk-space-lg) var(--_edge);
}
/* Lines content up with the nav items' text. */
.kvyk-sidebar__inset { padding-inline: 12px; }
.kvyk-sidebar__label {
  display: block;
  padding-inline: 12px;
  margin-bottom: var(--kvyk-space-sm);
}
.kvyk-sidebar__footer {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: var(--kvyk-space-sm);
  padding: var(--kvyk-space-md) var(--_text);
  border-top: 1px solid var(--kvyk-outline-variant);
}
.kvyk-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow-x: hidden;
  overflow-y: auto;
  background: var(--kvyk-background);
}
/* On a desktop the sidebar narrows to its icons and back, from the button in
   its brand band; each item then keeps its name for screen readers and shows
   it on hover. The organisation menu and the account's name step aside. */
.kvyk-sidebar__collapse { margin-left: auto; }
@media (min-width: 768px) {
  .kvyk-sidebar.is-collapsed {
    --_edge: var(--kvyk-space-sm);
    width: var(--kvyk-sidebar-width-collapsed);
  }
  .kvyk-sidebar.is-collapsed .kvyk-sidebar__brand { justify-content: center; padding-inline: 0; }
  .kvyk-sidebar.is-collapsed .kvyk-sidebar__brand .kvyk-brand { display: none; }
  .kvyk-sidebar.is-collapsed .kvyk-sidebar__collapse { margin-left: 0; }
  .kvyk-sidebar.is-collapsed .kvyk-sidebar__orgs > .kvyk-select { display: none; }
  .kvyk-sidebar.is-collapsed .kvyk-nav-item { justify-content: center; padding-inline: 0; }
  .kvyk-sidebar.is-collapsed .kvyk-nav-item > .kvyk-icon--sm { display: none; }
  .kvyk-sidebar.is-collapsed .kvyk-nav-item:has(> .kvyk-count) { position: relative; }
  .kvyk-sidebar.is-collapsed .kvyk-nav-item > .kvyk-count {
    position: absolute;
    top: 0;
    right: 2px;
  }
  .kvyk-sidebar.is-collapsed .kvyk-nav--nested { padding-left: 0; }
  .kvyk-sidebar.is-collapsed .kvyk-nav-item__label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
  }
  .kvyk-sidebar.is-collapsed .kvyk-sidebar__footer { padding-inline: 0; align-items: center; }
  .kvyk-sidebar.is-collapsed .kvyk-sidebar__footer .kvyk-cluster { flex-direction: column; }
  .kvyk-sidebar.is-collapsed .kvyk-sidebar__footer .kvyk-cluster > a { display: none; }
}
/* Below 768px the sidebar is a drawer: hidden until the app bar's menu button
   opens it over the page, a scrim behind it and a close button in its brand band. */
.kvyk-appbar .kvyk-appbar__menu,
.kvyk-sidebar .kvyk-sidebar__close { display: none; }
@media (max-width: 767px) {
  .kvyk-sidebar { display: none; }
  .kvyk-sidebar .kvyk-sidebar__collapse { display: none; }
  .kvyk-sidebar.is-open {
    display: flex;
    position: fixed;
    inset: 0 auto 0 0;
    width: min(var(--kvyk-sidebar-width), 85vw);
    z-index: var(--kvyk-z-overlay);
    box-shadow: var(--kvyk-elevation-3);
  }
  .kvyk-sidebar-scrim {
    position: fixed;
    inset: 0;
    z-index: calc(var(--kvyk-z-overlay) - 1);
    background: var(--kvyk-scrim);
  }
  .kvyk-appbar .kvyk-appbar__menu { display: inline-flex; }
  .kvyk-sidebar .kvyk-sidebar__close { display: inline-flex; margin-left: auto; }
}

/* App top bar: sticks to the top of the scrolling main column, frosted over it. */
.kvyk-appbar {
  position: sticky;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--kvyk-space-md);
  height: var(--kvyk-header-height);
  flex-shrink: 0;
  padding-inline: var(--kvyk-margin-desktop);
  background: rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--kvyk-outline-variant);
  z-index: var(--kvyk-z-header);
}
@media (max-width: 767px) {
  .kvyk-appbar { padding-inline: var(--kvyk-margin-mobile); }
}
/* The bar's breadcrumbs fill it between the menu button and its controls;
   below 768px they drop to a band of their own under the bar. */
.kvyk-appbar__trail { flex: 1; min-width: 0; }
@media (max-width: 767px) {
  .kvyk-appbar:has(> .kvyk-appbar__trail) {
    display: grid;
    grid-template-columns: auto auto;
    grid-template-rows: var(--kvyk-header-height) auto;
    justify-content: space-between;
    row-gap: 0;
    height: auto;
  }
  .kvyk-appbar__trail {
    grid-row: 2;
    grid-column: 1 / -1;
    margin-inline: calc(-1 * var(--kvyk-margin-mobile));
    padding: var(--kvyk-space-sm) var(--kvyk-margin-mobile);
    border-top: 1px solid var(--kvyk-outline-variant);
  }
}

/* A page in the main column: the container's width, with room above and below. */
.kvyk-page {
  padding-block: var(--kvyk-space-xl) var(--kvyk-space-2xl);
}

/* The rhythm of a page: its header on the tinted canvas, then each of its
   sections a white, square, outlined surface, with space between them. A
   section inside a section is part of its surface, not one of its own. */
:root {
  --kvyk-surface-pad: var(--kvyk-space-xl);
  --kvyk-surface-gap: var(--kvyk-space-xl);
}
@media (max-width: 767px) {
  :root {
    --kvyk-surface-pad: calc(var(--kvyk-space-md) + var(--kvyk-space-xs));
    --kvyk-surface-gap: var(--kvyk-space-lg);
  }
}
.kvyk-page-body {
  display: flex;
  flex-direction: column;
  gap: var(--kvyk-surface-gap);
}
/* Sections side by side keep the same space between them as stacked ones. */
.kvyk-page-body > .kvyk-grid { --kvyk-grid-gap: var(--kvyk-surface-gap); }
.kvyk-page-header {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--kvyk-space-md) var(--kvyk-space-lg);
}
.kvyk-page-header__text {
  --_flow-gap: var(--kvyk-space-sm);
  display: flex;
  flex-direction: column;
  gap: var(--_flow-gap);
  min-width: 0;
}
.kvyk-page-header > .kvyk-page-header__text { flex: 1 1 20rem; }
.kvyk-page-header__text > p { max-width: var(--kvyk-measure); color: var(--kvyk-on-surface-variant); }
.kvyk-page-header__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--kvyk-space-sm);
}
.kvyk-section {
  --_flow-gap: var(--kvyk-stack-gap, var(--kvyk-space-md));
  display: flex;
  flex-direction: column;
  gap: var(--_flow-gap);
  min-width: 0;
}
.kvyk-page-body .kvyk-section:not(.kvyk-section .kvyk-section) {
  padding: var(--kvyk-surface-pad);
  background: var(--kvyk-surface-container-lowest);
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-card);
}
/* A list in a section runs to the surface's edges, its row lines with it,
   and its first and last columns line up with the section's text, so the
   section reads as one block instead of a box in a box. One kept to the
   fields' width keeps its frame. */
.kvyk-page-body .kvyk-section:not(.kvyk-section .kvyk-section) :is(.kvyk-table-wrap, .kvyk-table-panel, .kvyk-list):not(.kvyk-table-panel > *, .kvyk-section__body *) {
  margin-inline: calc(-1 * var(--kvyk-surface-pad));
  border-inline: 0;
  border-radius: 0;
}
.kvyk-page-body .kvyk-section:not(.kvyk-section .kvyk-section) > :is(.kvyk-table-wrap, .kvyk-table-panel, .kvyk-list):first-child {
  margin-top: calc(-1 * var(--kvyk-surface-pad));
  border-top: 0;
}
.kvyk-page-body .kvyk-section:not(.kvyk-section .kvyk-section) > :is(.kvyk-table-wrap, .kvyk-table-panel, .kvyk-list):last-child {
  margin-bottom: calc(-1 * var(--kvyk-surface-pad));
  border-bottom: 0;
}
.kvyk-page-body .kvyk-section:not(.kvyk-section .kvyk-section) .kvyk-table:not(.kvyk-section__body *) :is(th, td):first-child { padding-left: var(--kvyk-surface-pad); }
.kvyk-page-body .kvyk-section:not(.kvyk-section .kvyk-section) .kvyk-table:not(.kvyk-section__body *) :is(th, td):last-child { padding-right: var(--kvyk-surface-pad); }
.kvyk-page-body .kvyk-section:not(.kvyk-section .kvyk-section) :is(.kvyk-table-footer, .kvyk-list-item):not(.kvyk-section__body *) { padding-inline: var(--kvyk-surface-pad); }
/* A field straight in a section keeps a readable width. */
.kvyk-section > .kvyk-field { max-width: var(--kvyk-measure); }
/* A section's title, with a line under it when it needs one. */
.kvyk-section__header {
  --_flow-gap: var(--kvyk-space-xs);
  display: flex;
  flex-direction: column;
  gap: var(--_flow-gap);
  min-width: 0;
}
/* A section's header with its actions on the right. */
.kvyk-section__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--kvyk-space-sm) var(--kvyk-space-md);
}
/* A section's fields: a readable width, not the page's. */
.kvyk-section__body {
  --_flow-gap: var(--kvyk-space-md);
  display: flex;
  flex-direction: column;
  gap: var(--_flow-gap);
  max-width: var(--kvyk-measure);
  min-width: 0;
}
/* A section's actions, after its fields: the main one first. */
.kvyk-section__footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--kvyk-space-sm);
}
.kvyk-section__title {
  margin: 0;
  font-family: var(--kvyk-font-sans);
  font-size: 16px;
  line-height: var(--kvyk-leading-heading);
  font-weight: var(--kvyk-weight-semibold);
  color: var(--kvyk-on-surface);
}
.kvyk-section__lead {
  max-width: var(--kvyk-measure);
  font-size: 14px;
  line-height: var(--kvyk-leading-body);
  color: var(--kvyk-on-surface-variant);
}
/* Short terms with what each means, the meanings lined up in one column;
   on a phone each meaning goes under its term. */
.kvyk-terms {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: var(--kvyk-space-sm) var(--kvyk-space-lg);
  max-width: var(--kvyk-measure);
  margin: 0;
  font-size: 14px;
  line-height: 20px;
}
.kvyk-terms dt { font-weight: var(--kvyk-weight-semibold); color: var(--kvyk-on-surface); }
.kvyk-terms dd { margin: 0; color: var(--kvyk-on-surface-variant); }
@media (max-width: 479px) {
  .kvyk-terms { grid-template-columns: minmax(0, 1fr); row-gap: 0; }
  .kvyk-terms dd + dt { margin-top: var(--kvyk-space-sm); }
}

/* A row of controls over a list: its search on the left, what acts on the
   whole list on the right. */
.kvyk-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--kvyk-space-sm) var(--kvyk-space-md);
}

/* A quiet control over a page, on its right: who the page is seen as. */
.kvyk-view-as {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--kvyk-space-sm);
}
.kvyk-view-as__picker { flex: 0 1 18rem; min-width: 12rem; }
.kvyk-view-as .kvyk-combobox { min-width: 0; }
.kvyk-view-as .kvyk-input { height: var(--kvyk-control-height-sm); font-size: 14px; }

/* Labelled values, as many columns as fit: the label small and muted above. */
.kvyk-details {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(16rem, 100%), 1fr));
  gap: var(--kvyk-space-lg);
  margin: 0;
}
.kvyk-details > div { display: flex; flex-direction: column; gap: var(--kvyk-space-xs); min-width: 0; }
.kvyk-details dt {
  font-family: var(--kvyk-font-mono);
  font-size: 12px;
  line-height: 16px;
  font-weight: var(--kvyk-weight-medium);
  color: var(--kvyk-on-surface-variant);
}
.kvyk-details dd { margin: 0; overflow-wrap: anywhere; }

/* Nothing here yet: a calm block that says so and offers the way on. */
.kvyk-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--kvyk-space-md);
  padding: var(--kvyk-space-2xl) var(--kvyk-space-lg);
  text-align: center;
  background: var(--kvyk-surface-container-lowest);
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-card);
}
.kvyk-empty > p { max-width: 36rem; color: var(--kvyk-on-surface-variant); }

/* Convenience surface backgrounds */
.kvyk-surface-card { background: var(--kvyk-surface-container-lowest); }
.kvyk-surface-low { background: var(--kvyk-surface-container-low); }
.kvyk-surface-1 { background: var(--kvyk-surface-container); }
.kvyk-surface-2 { background: var(--kvyk-surface-container-high); }
.kvyk-surface-3 { background: var(--kvyk-surface-container-highest); }

/* ==========================================================================
   6. COMPONENTS
   ========================================================================== */

/* ---- Icon ---------------------------------------------------------------- */
/* Inline SVG line icons: 24px grid, 2px stroke, currentColor.
   Use <svg class="kvyk-icon"><use href="#i-search"/></svg>. */
.kvyk-icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.kvyk-icon--sm { width: 16px; height: 16px; }
.kvyk-icon--lg { width: 24px; height: 24px; }
.kvyk-icon--xl { width: 32px; height: 32px; }
.kvyk-icon--solid { fill: currentColor; stroke: none; }

/* Square tile that frames an icon (feature cards, etc.) */
.kvyk-icon-tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: var(--kvyk-radius-md);
  background: var(--kvyk-surface-container);
  color: var(--kvyk-secondary);
  flex-shrink: 0;
}
.kvyk-icon-tile--sm { width: 40px; height: 40px; }
.kvyk-icon-tile--round { border-radius: var(--kvyk-radius-circle); }
.kvyk-icon-tile--accent { background: var(--kvyk-secondary-container); color: var(--kvyk-on-secondary-container); }
.kvyk-icon-tile--success { background: var(--kvyk-tertiary-fixed-dim); color: var(--kvyk-on-tertiary-fixed-variant); }
.kvyk-icon-tile--danger { background: var(--kvyk-error-container); color: var(--kvyk-on-error-container); }

/* ---- Button -------------------------------------------------------------- */
.kvyk-btn {
  /* themeable locals — variants only re-map these */
  --_bg: var(--kvyk-surface-container);
  --_fg: var(--kvyk-on-surface);
  --_bd: transparent;
  --_bg-hover: var(--kvyk-surface-container-high);
  --_shadow: none;
  --_shadow-hover: none;

  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--kvyk-space-sm);
  height: 40px;
  padding-inline: var(--kvyk-space-md);
  font-family: var(--kvyk-font-mono);
  font-size: 14px;
  line-height: 20px;
  font-weight: var(--kvyk-weight-medium);
  letter-spacing: 0.02em;
  color: var(--_fg);
  background: var(--_bg);
  border: 1px solid var(--_bd);
  border-radius: var(--kvyk-radius-sm);
  box-shadow: var(--_shadow);
  white-space: nowrap;
  user-select: none;
  text-decoration: none;
  transition: background-color var(--kvyk-duration) var(--kvyk-ease),
              color var(--kvyk-duration) var(--kvyk-ease),
              border-color var(--kvyk-duration) var(--kvyk-ease),
              box-shadow var(--kvyk-duration) var(--kvyk-ease),
              transform var(--kvyk-duration-fast) var(--kvyk-ease);
}
.kvyk-btn:hover { background: var(--_bg-hover); box-shadow: var(--_shadow-hover); text-decoration: none; }
.kvyk-btn:active { transform: translateY(1px); }
.kvyk-btn:disabled,
.kvyk-btn[aria-disabled="true"] { opacity: 0.45; pointer-events: none; }
.kvyk-btn .kvyk-icon { width: 18px; height: 18px; }

.kvyk-btn--primary {
  --_bg: var(--kvyk-primary);
  --_fg: var(--kvyk-on-primary);
  --_bg-hover: var(--kvyk-inverse-surface);
}
.kvyk-btn--accent {
  --_bg: var(--kvyk-secondary);
  --_fg: var(--kvyk-on-secondary);
  --_bg-hover: var(--kvyk-on-secondary-fixed-variant);
}
.kvyk-btn--tonal {
  --_bg: var(--kvyk-secondary-fixed);
  --_fg: var(--kvyk-on-secondary-fixed);
  --_bg-hover: var(--kvyk-secondary-fixed-dim);
}
.kvyk-btn--outline {
  --_bg: transparent;
  --_fg: var(--kvyk-on-surface);
  --_bd: var(--kvyk-outline);
  --_bg-hover: var(--kvyk-surface-container-low);
}
.kvyk-btn--ghost {
  --_bg: transparent;
  --_fg: var(--kvyk-on-surface-variant);
  --_bg-hover: var(--kvyk-surface-container-low);
}
.kvyk-btn--danger {
  --_bg: var(--kvyk-error);
  --_fg: var(--kvyk-on-error);
  --_bg-hover: var(--kvyk-on-error-container);
}
/* A filled button that cannot be used yet goes neutral, rather than a faded
   colour that still reads as the main action. */
.kvyk-btn--primary:disabled,
.kvyk-btn--accent:disabled,
.kvyk-btn--danger:disabled,
.kvyk-btn--tonal:disabled {
  --_bg: var(--kvyk-surface-container);
  --_fg: var(--kvyk-on-surface-variant);
  opacity: 1;
}
/* Raised: the hero CTA with a colored glow that lifts on hover. */
.kvyk-btn--raised {
  --_shadow: var(--kvyk-elevation-accent);
  --_shadow-hover: var(--kvyk-elevation-accent-hover);
}

.kvyk-btn--sm { height: 32px; padding-inline: var(--kvyk-space-sm); font-size: 12px; }
.kvyk-btn--lg { height: 48px; padding-inline: var(--kvyk-space-lg); }
.kvyk-btn--block { width: 100%; }

/* Icon-only button (square or circular) */
.kvyk-btn--icon {
  width: 40px;
  height: 40px;
  padding: 0;
  border-radius: var(--kvyk-radius-circle);
}
.kvyk-btn--icon.kvyk-btn--sm { width: 32px; height: 32px; }
.kvyk-btn--icon .kvyk-icon { width: 20px; height: 20px; }

/* ---- Badge / Chip / Tag -------------------------------------------------- */
.kvyk-badge {
  --_bg: var(--kvyk-surface-container-low);
  --_fg: var(--kvyk-on-surface-variant);
  display: inline-flex;
  align-items: center;
  gap: var(--kvyk-space-xs);
  padding: 2px 8px;
  font-family: var(--kvyk-font-mono);
  font-size: 12px;
  line-height: 16px;
  font-weight: var(--kvyk-weight-medium);
  color: var(--_fg);
  background: var(--_bg);
  border-radius: var(--kvyk-radius-pill);
  white-space: nowrap;
}
.kvyk-badge--accent { --_bg: var(--kvyk-secondary-fixed); --_fg: var(--kvyk-on-secondary-fixed); }
/* A badge that can be taken away, as an active filter is: its remove button. */
.kvyk-badge__remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  margin-right: -4px;
  padding: 0;
  color: inherit;
  background: transparent;
  border: none;
  border-radius: var(--kvyk-radius-pill);
  cursor: pointer;
}
.kvyk-badge__remove:hover { background: var(--kvyk-surface-container-high); color: var(--kvyk-on-surface); }
.kvyk-badge__remove .kvyk-icon { width: 12px; height: 12px; }
/* Status badges carry their colour in a hairline and the text, never a
   bright fill, so a column of them stays calm. */
.kvyk-badge--success {
  --_bg: transparent;
  --_fg: var(--kvyk-on-tertiary-fixed-variant);
  box-shadow: inset 0 0 0 1px var(--kvyk-tertiary-fixed-dim);
}
.kvyk-badge--danger {
  --_bg: transparent;
  --_fg: var(--kvyk-on-error-container);
  box-shadow: inset 0 0 0 1px var(--kvyk-error);
}
.kvyk-badge--outline {
  --_bg: transparent;
  box-shadow: inset 0 0 0 1px var(--kvyk-outline-variant);
}
.kvyk-badge--square { border-radius: var(--kvyk-radius-xs); }
.kvyk-badge .kvyk-icon { width: 14px; height: 14px; }

/* Leading status dot */
.kvyk-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: var(--kvyk-radius-circle);
  background: var(--kvyk-outline);
  flex-shrink: 0;
}
.kvyk-dot--accent { background: var(--kvyk-secondary); }
.kvyk-dot--success { background: var(--kvyk-tertiary-fixed-dim); }
.kvyk-dot--danger { background: var(--kvyk-error); }
.kvyk-dot--pulse { animation: kvyk-pulse 2s var(--kvyk-ease) infinite; }

/* Which stage's data a page shows: a status beside a page's buttons, as tall
   as they are, so it lines up with them, yet no frame, fill or hover, so it is
   never taken for one. Live is real data and wears the success green; Preview
   a hollow dot. */
.kvyk-stage {
  --_dot: var(--kvyk-outline);
  --_fg: var(--kvyk-on-surface-variant);
  display: inline-flex;
  align-items: center;
  gap: var(--kvyk-space-sm);
  height: var(--kvyk-control-height);
  padding-inline: var(--kvyk-space-xs);
  font-family: var(--kvyk-font-mono);
  font-size: 13px;
  line-height: 20px;
  font-weight: var(--kvyk-weight-medium);
  letter-spacing: 0.02em;
  color: var(--_fg);
  white-space: nowrap;
  cursor: default;
}
.kvyk-stage::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: var(--kvyk-radius-circle);
  box-shadow: inset 0 0 0 2px var(--_dot);
  flex-shrink: 0;
}
.kvyk-stage--live {
  --_dot: var(--kvyk-on-tertiary-container);
  --_fg: var(--kvyk-on-tertiary-fixed-variant);
}
.kvyk-stage--live::before { background: var(--_dot); }

/* A count of things waiting, such as conversations with an answer not yet
   read: a small filled pill in the accent, at the end of a nav item or on an
   icon button's corner. It is only seen; the control's name says the count. */
.kvyk-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  font-family: var(--kvyk-font-mono);
  font-size: 11px;
  line-height: 1;
  font-weight: var(--kvyk-weight-semibold);
  letter-spacing: 0;
  color: var(--kvyk-on-secondary);
  background: var(--kvyk-secondary);
  border-radius: var(--kvyk-radius-pill);
  flex-shrink: 0;
}
.kvyk-nav-item > .kvyk-count { margin-left: auto; }
.kvyk-btn--icon:has(> .kvyk-count) { position: relative; }
.kvyk-btn--icon > .kvyk-count {
  position: absolute;
  top: 2px;
  right: 0;
}

@keyframes kvyk-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}

/* Something is being worked on, such as a file being checked: a small ring
   that turns, sized for a badge or a chip. It says nothing itself, so give it
   role="img" and an aria-label naming what is happening. Without motion it
   stands still as a dotted ring. */
.kvyk-spinner {
  --_size: 14px;
  display: inline-block;
  width: var(--_size);
  height: var(--_size);
  flex-shrink: 0;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: var(--kvyk-radius-circle);
  animation: kvyk-spin 0.8s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .kvyk-spinner {
    animation: none !important;
    border-style: dotted;
    border-top-color: currentColor;
  }
}

@keyframes kvyk-spin {
  to { transform: rotate(360deg); }
}

/* ---- Card ---------------------------------------------------------------- */
.kvyk-card {
  background: var(--kvyk-surface-container-lowest);
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-card);
  padding: var(--kvyk-space-lg);
}
.kvyk-card--flush { padding: 0; }
/* A table or list straight in a flush card runs to its edges: the card's
   border and its header's rule frame it, not a second border of its own. */
.kvyk-card--flush > :is(.kvyk-table-wrap, .kvyk-table-panel, .kvyk-list) {
  border: 0;
  border-radius: 0;
}
.kvyk-card--flush > :is(.kvyk-table-wrap, .kvyk-table-panel, .kvyk-list):last-child {
  border-radius: 0 0 calc(var(--kvyk-radius-card) - 1px) calc(var(--kvyk-radius-card) - 1px);
}
.kvyk-card--lg { padding: var(--kvyk-space-xl); }
.kvyk-card--raised { box-shadow: var(--kvyk-elevation-2); }
.kvyk-card--floating { border-color: transparent; box-shadow: var(--kvyk-elevation-3); }
.kvyk-card--interactive {
  cursor: pointer;
  transition: box-shadow var(--kvyk-duration) var(--kvyk-ease),
              transform var(--kvyk-duration) var(--kvyk-ease),
              border-color var(--kvyk-duration) var(--kvyk-ease);
}
.kvyk-card--interactive:hover {
  box-shadow: var(--kvyk-elevation-2);
  transform: translateY(-2px);
}

/* Card subsections (header / body / footer), split by a single rule on the
   card's own white. A banded card tints its header and footer, for a page of
   cards side by side (an organisation's home). */
.kvyk-card__header {
  padding: var(--kvyk-space-md) var(--kvyk-space-lg);
  border-bottom: 1px solid var(--kvyk-outline-variant);
}
.kvyk-card__body { padding: var(--kvyk-space-lg); }
.kvyk-card--banded > .kvyk-card__header,
.kvyk-card--banded > .kvyk-card__footer { background: var(--kvyk-surface-container-low); }
.kvyk-card__footer {
  padding: var(--kvyk-space-md) var(--kvyk-space-lg);
  border-top: 1px solid var(--kvyk-outline-variant);
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: var(--kvyk-space-sm);
}

/* ---- Stat card ----------------------------------------------------------- */
.kvyk-stat__label {
  font-family: var(--kvyk-font-mono);
  font-size: 12px;
  font-weight: var(--kvyk-weight-medium);
  letter-spacing: 0.02em;
  color: var(--kvyk-on-surface-variant);
}
.kvyk-stat__value {
  font-family: var(--kvyk-font-sans);
  font-weight: var(--kvyk-weight-semibold);
  font-size: 32px;
  line-height: 40px;
  letter-spacing: -0.01em;
  color: var(--kvyk-on-surface);
}
.kvyk-stat__delta {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 1px 6px;
  border-radius: var(--kvyk-radius-xs);
  font-family: var(--kvyk-font-mono);
  font-size: 12px;
  font-weight: var(--kvyk-weight-medium);
  background: var(--kvyk-surface-container-high);
  color: var(--kvyk-on-surface-variant);
}
.kvyk-stat__delta--up { background: rgba(78, 222, 163, 0.2); color: var(--kvyk-on-tertiary-container); }
.kvyk-stat__delta--down { background: var(--kvyk-error-container); color: var(--kvyk-on-error-container); }
.kvyk-stat__delta .kvyk-icon { width: 14px; height: 14px; }

/* Tiny inline bar chart (decorative sparkline). */
.kvyk-sparkbars {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: 48px;
}
.kvyk-sparkbars > span {
  flex: 1;
  background: var(--kvyk-secondary-fixed);
  border-radius: var(--kvyk-radius-xs) var(--kvyk-radius-xs) 0 0;
}
.kvyk-sparkbars > span:last-child { background: var(--kvyk-secondary); }

/* ---- Chart ----------------------------------------------------------------
   A chart drawn as inline SVG: thin marks from a shared baseline, a recessive
   axis, values in text colours and never in a series' colour. Series take
   the categorical colours in order (--kvyk-chart-1 first, the accent), never
   cycled: a seventh group folds into "Other". Three of them sit below 3:1 on
   white, so a chart always carries a legend and the numbers on hover, focus
   and in a table. */
.kvyk-chart {
  --kvyk-chart-1: var(--kvyk-secondary);
  --kvyk-chart-2: #eb6834;
  --kvyk-chart-3: #1baf7a;
  --kvyk-chart-4: #eda100;
  --kvyk-chart-5: #e87ba4;
  --kvyk-chart-6: #6250d6;
  display: flex;
  flex-direction: column;
  gap: var(--kvyk-space-xs);
  margin: 0;
  min-height: 0;
  height: 100%;
}
.kvyk-chart__plot {
  position: relative;
  flex: 1;
  min-height: 96px;
}
.kvyk-chart__plot > svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}
.kvyk-chart__axis {
  stroke: var(--kvyk-outline-variant);
  stroke-width: 1;
}
.kvyk-chart__grid {
  stroke: var(--kvyk-outline-variant);
  stroke-width: 1;
  stroke-dasharray: 2 4;
}
.kvyk-chart__mark { transition: opacity var(--kvyk-duration-fast) var(--kvyk-ease); }
.kvyk-chart__hit { fill: transparent; }
.kvyk-chart__hit:focus { outline: none; }
.kvyk-chart__hit:focus-visible { fill: var(--kvyk-ring-color); }
.kvyk-chart.is-pointing .kvyk-chart__mark:not(.is-pointed) { opacity: 0.45; }
.kvyk-chart__line {
  fill: none;
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.kvyk-chart__ticks {
  display: flex;
  justify-content: space-between;
  gap: var(--kvyk-space-sm);
  font-family: var(--kvyk-font-mono);
  font-size: 11px;
  color: var(--kvyk-on-surface-variant);
}
.kvyk-chart__readout {
  font-size: 13px;
  color: var(--kvyk-on-surface-variant);
  min-height: 1.5em;
}
.kvyk-chart__readout strong { color: var(--kvyk-on-surface); font-weight: var(--kvyk-weight-semibold); }
.kvyk-chart__legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--kvyk-space-xs) var(--kvyk-space-sm-md);
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 12px;
  color: var(--kvyk-on-surface-variant);
}
.kvyk-chart__legend li { display: inline-flex; align-items: center; gap: var(--kvyk-space-xs); }
.kvyk-chart__swatch {
  width: 10px;
  height: 10px;
  border-radius: var(--kvyk-radius-xs);
  flex: none;
}
/* Horizontal bars: a row per group, its name, its bar and its value. */
.kvyk-chart__rows {
  display: grid;
  grid-template-columns: minmax(4rem, max-content) 1fr max-content;
  align-items: center;
  gap: var(--kvyk-space-xs) var(--kvyk-space-sm);
  font-size: 13px;
  overflow-y: auto;
}
.kvyk-chart__rows > .kvyk-chart__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 12rem;
  color: var(--kvyk-on-surface-variant);
}
.kvyk-chart__track { display: flex; gap: 2px; height: 14px; }
.kvyk-chart__track > span { border-radius: 0 var(--kvyk-radius-sm) var(--kvyk-radius-sm) 0; min-width: 0; }
.kvyk-chart__value {
  font-family: var(--kvyk-font-mono);
  font-size: 12px;
  color: var(--kvyk-on-surface);
  text-align: end;
}
/* One number, the headline, with how it moved against the period before.
   Centred only while it fits: a short card scrolls it instead of cutting
   off its top. */
.kvyk-chart--metric { justify-content: safe center; gap: 0; }

/* ---- Board ----------------------------------------------------------------
   Cards on a grid of twelve columns and rows of a fixed height, the same gap
   both ways. Each card sets its place in custom properties (--x and --y from
   0, --w and --h in cells), so below 768px the cards simply stack. Editing,
   a card moves by its header and grows by its corner; a dashed frame shows
   where it lands. */
.kvyk-board {
  --kvyk-board-row: 72px;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-auto-rows: var(--kvyk-board-row);
  gap: var(--kvyk-space-md);
  position: relative;
}
.kvyk-board__card,
.kvyk-board__ghost {
  grid-column: calc(var(--x) + 1) / span var(--w);
  grid-row: calc(var(--y) + 1) / span var(--h);
  min-width: 0;
  min-height: 0;
}
.kvyk-board__card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--kvyk-surface-container-lowest);
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-card);
}
.kvyk-board__card:focus { outline: none; }
.kvyk-board__card:focus-visible { box-shadow: var(--kvyk-ring); border-color: var(--kvyk-secondary); }
.kvyk-board__head {
  display: flex;
  align-items: center;
  gap: var(--kvyk-space-xs);
  padding: var(--kvyk-space-sm) var(--kvyk-space-sm) var(--kvyk-space-sm) var(--kvyk-space-md);
  min-height: 44px;
}
.kvyk-board__title {
  flex: 1;
  min-width: 0;
  margin: 0;
  font-size: 14px;
  font-weight: var(--kvyk-weight-semibold);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kvyk-board__body {
  flex: 1;
  min-height: 0;
  overflow: auto;
  padding: 0 var(--kvyk-space-md) var(--kvyk-space-sm);
}
.kvyk-board__foot {
  padding: 0 var(--kvyk-space-md) var(--kvyk-space-sm);
  font-size: 12px;
  color: var(--kvyk-on-surface-variant);
}
.kvyk-board--editing .kvyk-board__head { cursor: grab; touch-action: none; }
.kvyk-board--editing .kvyk-board__card { border-style: dashed; }
.kvyk-board__card.is-moving {
  z-index: var(--kvyk-z-base);
  box-shadow: var(--kvyk-elevation-3);
  border-color: var(--kvyk-secondary);
  border-style: solid;
  opacity: 0.92;
  cursor: grabbing;
}
.kvyk-board__ghost {
  border: 2px dashed var(--kvyk-secondary);
  background: color-mix(in srgb, var(--kvyk-secondary-fixed) 40%, transparent);
  pointer-events: none;
}
.kvyk-board__resize {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 20px;
  height: 20px;
  padding: 0;
  border: 0;
  background:
    linear-gradient(135deg, transparent 50%, var(--kvyk-outline) 50%, var(--kvyk-outline) 60%, transparent 60%, transparent 70%, var(--kvyk-outline) 70%, var(--kvyk-outline) 80%, transparent 80%);
  cursor: nwse-resize;
  touch-action: none;
}
.kvyk-board__notice {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: var(--kvyk-space-sm);
  height: 100%;
  font-size: 13px;
  color: var(--kvyk-on-surface-variant);
}
/* The card being edited, beside the board: a sheet from the right edge. */
.kvyk-board__editor {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: var(--kvyk-z-overlay);
  display: flex;
  flex-direction: column;
  width: min(560px, 100vw);
  background: var(--kvyk-surface-container-lowest);
  border-left: 1px solid var(--kvyk-outline-variant);
  box-shadow: var(--kvyk-elevation-3);
}
.kvyk-board__editor > header,
.kvyk-board__editor > footer {
  display: flex;
  align-items: center;
  gap: var(--kvyk-space-sm);
  padding: var(--kvyk-space-md) var(--kvyk-space-lg);
  border-bottom: 1px solid var(--kvyk-outline-variant);
}
.kvyk-board__editor > footer {
  justify-content: flex-end;
  border-top: 1px solid var(--kvyk-outline-variant);
  border-bottom: 0;
}
.kvyk-board__editor > div {
  flex: 1;
  overflow-y: auto;
  padding: var(--kvyk-space-lg);
}
.kvyk-board__preview {
  display: flex;
  flex-direction: column;
  height: 240px;
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-card);
  padding: var(--kvyk-space-sm) var(--kvyk-space-md);
}
@media (max-width: 767px) {
  .kvyk-board { grid-template-columns: minmax(0, 1fr); grid-auto-rows: auto; }
  .kvyk-board__card { grid-column: 1; grid-row: auto; height: calc(var(--h) * 56px); min-height: 160px; }
  .kvyk-board__ghost,
  .kvyk-board__resize { display: none; }
}

/* ---- Field / Input / Textarea / Select ----------------------------------- */
.kvyk-field {
  --_flow-gap: var(--kvyk-space-sm);
  display: flex;
  flex-direction: column;
  gap: var(--_flow-gap);
}
/* A field of several controls is a fieldset under a legend: it keeps the
   field's look, not the browser's framed box. */
fieldset.kvyk-field {
  margin: 0;
  padding: 0;
  border: 0;
  min-inline-size: 0;
}
legend.kvyk-label {
  padding: 0;
  margin-bottom: var(--kvyk-space-sm);
}
/* A group of controls under a legend, without the browser's frame. */
.kvyk-fieldset {
  min-inline-size: 0;
  margin: 0;
  padding: 0;
  border: 0;
}
.kvyk-label {
  font-family: var(--kvyk-font-mono);
  font-size: 14px;
  line-height: 20px;
  font-weight: var(--kvyk-weight-medium);
  letter-spacing: 0.02em;
  color: var(--kvyk-on-surface);
}
.kvyk-help { font-size: 14px; line-height: var(--kvyk-leading-body); color: var(--kvyk-on-surface-variant); }
.kvyk-error-text {
  font-family: var(--kvyk-font-mono);
  font-size: 12px;
  line-height: 16px;
  color: var(--kvyk-error);
}

.kvyk-input,
.kvyk-textarea,
.kvyk-select {
  width: 100%;
  font-family: var(--kvyk-font-sans);
  font-size: 16px;
  line-height: 24px;
  color: var(--kvyk-on-surface);
  background: var(--kvyk-surface-container-lowest);
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-sm);
  padding: var(--kvyk-space-sm) var(--kvyk-space-sm-md);
  transition: border-color var(--kvyk-duration) var(--kvyk-ease),
              box-shadow var(--kvyk-duration) var(--kvyk-ease),
              background-color var(--kvyk-duration) var(--kvyk-ease);
}
.kvyk-input::placeholder,
.kvyk-textarea::placeholder { color: var(--kvyk-on-surface-variant); opacity: 0.6; }
/* One height for every single-line control, so a field and its button line up. */
.kvyk-input,
.kvyk-select { height: var(--kvyk-control-height); padding-block: 0; }
.kvyk-input:hover:not(:focus):not(:disabled),
.kvyk-textarea:hover:not(:focus):not(:disabled),
.kvyk-select:hover:not(:focus):not(:disabled) { border-color: var(--kvyk-outline); }

.kvyk-input:focus,
.kvyk-textarea:focus,
.kvyk-select:focus {
  outline: none;
  border-color: var(--kvyk-secondary);
  box-shadow: 0 0 0 3px var(--kvyk-ring-color);
}
.kvyk-textarea { resize: vertical; min-height: 80px; }

.kvyk-input[aria-invalid="true"],
.kvyk-textarea[aria-invalid="true"],
.kvyk-select[aria-invalid="true"],
.kvyk-input.is-invalid {
  border-color: var(--kvyk-error);
}
.kvyk-input[aria-invalid="true"]:focus,
.kvyk-textarea[aria-invalid="true"]:focus,
.kvyk-select[aria-invalid="true"]:focus,
.kvyk-input.is-invalid:focus {
  box-shadow: 0 0 0 3px rgba(186, 26, 26, 0.25);
}
.kvyk-input:disabled,
.kvyk-textarea:disabled,
.kvyk-select:disabled { opacity: 0.5; cursor: not-allowed; }

/* Native select with a custom chevron */
.kvyk-select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 40px;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='24'%20height='24'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%2345464d'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M6%209l6%206%206-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 20px;
}
/* A compact select, as tall as a small button and as wide as its options. */
.kvyk-select.kvyk-select--sm {
  width: auto;
  height: var(--kvyk-control-height-sm);
  padding: 0 32px 0 var(--kvyk-space-sm);
  font-size: 14px;
  line-height: 30px;
  background-position: right 8px center;
  background-size: 16px;
}

/* A searchable choice, for lists too long for a native select: the input
   filters, and a listbox of the matches opens under it (the ARIA combobox
   pattern). The active option takes the selected surface. */
.kvyk-combobox { position: relative; min-width: 14rem; }
.kvyk-combobox > .kvyk-input { width: 100%; }
/* As tall as a small button and a .kvyk-select--sm: for a toolbar. */
.kvyk-combobox--sm > .kvyk-input { height: var(--kvyk-control-height-sm); font-size: 14px; }
.kvyk-combobox__list {
  position: absolute;
  top: calc(100% + var(--kvyk-space-xs));
  left: 0;
  right: 0;
  z-index: calc(var(--kvyk-z-header) + 5);
  max-height: 18rem;
  overflow-y: auto;
  margin: 0;
  padding: var(--kvyk-space-xs);
  list-style: none;
  background: var(--kvyk-surface-container-lowest);
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-sm);
  box-shadow: var(--kvyk-elevation-2);
}
/* A dialog scrolls its own content, so a list floating over it would hide
   the dialog's buttons: there the list takes its place in the flow and the
   dialog grows to hold it. */
.kvyk-dialog .kvyk-combobox__list {
  position: static;
  margin-top: var(--kvyk-space-xs);
  max-height: 12rem;
  box-shadow: none;
}
.kvyk-combobox__option {
  padding: var(--kvyk-space-xs) var(--kvyk-space-sm);
  font-size: 14px;
  line-height: 20px;
  color: var(--kvyk-on-surface);
  border-radius: var(--kvyk-radius-sm);
  cursor: pointer;
}
.kvyk-combobox__option[aria-selected="true"] {
  background: var(--kvyk-surface-selected);
}
.kvyk-combobox__status {
  padding: var(--kvyk-space-xs) var(--kvyk-space-sm);
  font-size: 13px;
  line-height: 18px;
  color: var(--kvyk-on-surface-variant);
}

/* Input with a leading icon, a trailing icon button, or both: wrap in
   .kvyk-input-group. The leading icon is a direct child; the button is
   .kvyk-input-group__action (an icon-only .kvyk-btn--icon.kvyk-btn--sm, such
   as showing what a password field holds). */
.kvyk-input-group { position: relative; display: flex; align-items: center; min-width: 0; }
.kvyk-input-group > .kvyk-icon {
  position: absolute;
  left: 12px;
  color: var(--kvyk-on-surface-variant);
  pointer-events: none;
}
.kvyk-input-group > .kvyk-icon ~ .kvyk-input { padding-left: 40px; }
.kvyk-input-group__action {
  position: absolute;
  right: 4px;
  color: var(--kvyk-on-surface-variant);
}
.kvyk-input-group:has(> .kvyk-input-group__action) .kvyk-input { padding-right: 44px; }

/* ---- Checkbox / Radio ---------------------------------------------------- */
.kvyk-checkbox,
.kvyk-radio {
  appearance: none;
  -webkit-appearance: none;
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  margin: 0;
  background: var(--kvyk-surface-container-lowest);
  border: 2px solid var(--kvyk-outline);
  cursor: pointer;
  display: inline-grid;
  place-content: center;
  transition: border-color var(--kvyk-duration) var(--kvyk-ease),
              background-color var(--kvyk-duration) var(--kvyk-ease);
}
.kvyk-checkbox { border-radius: var(--kvyk-radius-xs); }
.kvyk-radio { border-radius: var(--kvyk-radius-circle); }

.kvyk-checkbox::before {
  content: "";
  width: 11px;
  height: 11px;
  transform: scale(0);
  transition: transform var(--kvyk-duration-fast) var(--kvyk-ease);
  background: var(--kvyk-on-secondary);
  clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
}
.kvyk-checkbox:checked {
  background: var(--kvyk-secondary);
  border-color: var(--kvyk-secondary);
}
.kvyk-checkbox:checked::before { transform: scale(1); }

.kvyk-radio::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: var(--kvyk-radius-circle);
  transform: scale(0);
  transition: transform var(--kvyk-duration-fast) var(--kvyk-ease);
  background: var(--kvyk-secondary);
}
.kvyk-radio:checked { border-color: var(--kvyk-secondary); }
.kvyk-radio:checked::before { transform: scale(1); }

.kvyk-checkbox:focus-visible,
.kvyk-radio:focus-visible { box-shadow: var(--kvyk-ring); }

/* Checkbox/radio + label row */
.kvyk-choice {
  display: inline-flex;
  align-items: center;
  gap: var(--kvyk-space-sm);
  cursor: pointer;
}

/* ---- Switch -------------------------------------------------------------- */
.kvyk-switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  width: 40px;
  height: 22px;
  flex-shrink: 0;
}
.kvyk-switch input {
  position: absolute;
  opacity: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  cursor: pointer;
}
.kvyk-switch__track {
  position: absolute;
  inset: 0;
  background: var(--kvyk-outline);
  border-radius: var(--kvyk-radius-pill);
  transition: background-color var(--kvyk-duration) var(--kvyk-ease);
}
.kvyk-switch__track::before {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 18px;
  height: 18px;
  background: #fff;
  border-radius: var(--kvyk-radius-circle);
  box-shadow: var(--kvyk-elevation-1);
  transition: transform var(--kvyk-duration) var(--kvyk-ease);
}
.kvyk-switch input:checked + .kvyk-switch__track { background: var(--kvyk-secondary); }
.kvyk-switch input:checked + .kvyk-switch__track::before { transform: translateX(18px); }
.kvyk-switch input:focus-visible + .kvyk-switch__track { box-shadow: var(--kvyk-ring); }

/* ---- Selectable option card (radio styled as a panel) -------------------- */
.kvyk-option {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: var(--kvyk-space-sm-md);
  padding: var(--kvyk-space-md);
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-card);
  background: var(--kvyk-surface-container-lowest);
  cursor: pointer;
  transition: background-color var(--kvyk-duration) var(--kvyk-ease),
              border-color var(--kvyk-duration) var(--kvyk-ease);
}
.kvyk-option:hover { background: var(--kvyk-surface-hover); }
.kvyk-option:has(input:checked) { border-color: var(--kvyk-secondary); }

/* ---- Segmented control / Tabs ------------------------------------------- */
.kvyk-segmented {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  background: var(--kvyk-surface-container-low);
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-md);
}
.kvyk-segmented__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--kvyk-space-xs);
  padding: 6px 12px;
  font-family: var(--kvyk-font-mono);
  font-size: 12px;
  font-weight: var(--kvyk-weight-medium);
  letter-spacing: 0.02em;
  color: var(--kvyk-on-surface-variant);
  background: transparent;
  border: none;
  border-radius: var(--kvyk-radius-sm);
  cursor: pointer;
  transition: background-color var(--kvyk-duration) var(--kvyk-ease),
              color var(--kvyk-duration) var(--kvyk-ease);
}
.kvyk-segmented__item:hover { color: var(--kvyk-on-surface); }
/* In a toolbar on a phone, a segmented control keeps to the toolbar's width
   and its items share it, instead of running past the surface's edge. */
@media (max-width: 479px) {
  .kvyk-toolbar > .kvyk-segmented { max-width: 100%; }
  .kvyk-toolbar > .kvyk-segmented > .kvyk-segmented__item { flex: 1 1 auto; min-width: 0; padding-inline: 8px; }
}
/* A preview's device switch (Desktop, Tablet, Phone): on a phone the screen
   is the phone, and every device shows at its width, so the switch goes and
   leaves the toolbar room for the controls that still matter there. */
@media (max-width: 479px) {
  .kvyk-segmented--devices { display: none; }
}
.kvyk-segmented__item.is-active,
.kvyk-segmented__item[aria-selected="true"] {
  background: var(--kvyk-surface-container-lowest);
  color: var(--kvyk-on-surface);
  box-shadow: var(--kvyk-elevation-1);
}

.kvyk-tabs {
  display: flex;
  gap: var(--kvyk-space-lg);
  /* Baseline drawn as an inset shadow rather than a border so it never adds to the
     scrollable area — a border + the tabs' -1px overlap would push 1px past the
     content box and trip a phantom vertical scrollbar once this becomes a scroller. */
  box-shadow: inset 0 -1px 0 var(--kvyk-outline-variant);
  /* When tabs exceed the width they scroll instead of overflowing the parent.
     The scrollbar only appears once they don't fit, so wide layouts are unchanged. */
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: var(--kvyk-outline-variant) transparent;
}
.kvyk-tabs::-webkit-scrollbar { height: 3px; }
.kvyk-tabs::-webkit-scrollbar-thumb {
  background: var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-pill);
}
.kvyk-tabs::-webkit-scrollbar-track { background: transparent; }
.kvyk-tab {
  flex: 0 0 auto; /* keep each tab's natural width; the strip scrolls rather than squashing tabs */
  scroll-snap-align: start;
  white-space: nowrap;
  padding: var(--kvyk-space-sm) 0;
  font-family: var(--kvyk-font-mono);
  font-size: 14px;
  font-weight: var(--kvyk-weight-medium);
  letter-spacing: 0.02em;
  color: var(--kvyk-on-surface-variant);
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  transition: color var(--kvyk-duration) var(--kvyk-ease),
              border-color var(--kvyk-duration) var(--kvyk-ease);
}
.kvyk-tab:hover { color: var(--kvyk-on-surface); }
.kvyk-tab.is-active,
.kvyk-tab[aria-selected="true"] {
  color: var(--kvyk-secondary);
  border-bottom-color: var(--kvyk-secondary);
}

/* ---- Navigation (sidebar) ------------------------------------------------ */
.kvyk-nav { display: flex; flex-direction: column; gap: var(--kvyk-space-2xs); }
.kvyk-nav-item {
  display: flex;
  align-items: center;
  gap: var(--kvyk-space-sm);
  padding: var(--kvyk-space-sm) var(--kvyk-space-sm-md);
  border-radius: var(--kvyk-radius-sm);
  font-family: var(--kvyk-font-mono);
  font-size: 14px;
  font-weight: var(--kvyk-weight-medium);
  letter-spacing: 0.02em;
  color: var(--kvyk-on-surface-variant);
  text-decoration: none;
  transition: background-color var(--kvyk-duration) var(--kvyk-ease),
              color var(--kvyk-duration) var(--kvyk-ease);
}
/* A nav item that acts rather than links (opening the assistant). */
button.kvyk-nav-item {
  width: 100%;
  border: none;
  background: none;
  text-align: left;
  cursor: pointer;
}
.kvyk-nav-item:hover {
  background: var(--kvyk-surface-hover);
  color: var(--kvyk-on-surface);
  text-decoration: none;
}
/* The active item: the selected surface with full-strength text and icon.
   No accent: the nav never outshouts the page. */
.kvyk-nav-item.is-active,
.kvyk-nav-item[aria-current="page"],
.kvyk-nav-item.is-active:hover,
.kvyk-nav-item[aria-current="page"]:hover {
  background: var(--kvyk-surface-selected);
  color: var(--kvyk-on-surface);
}
/* Entries a level down, under the item that opens them. */
.kvyk-nav--nested { padding-left: var(--kvyk-space-lg); }
/* The item that leads the menu, apart from the pages under it: the
   assistant, in the accent, since it is how most work gets done. */
.kvyk-nav-item--accent,
.kvyk-nav-item--accent:hover { color: var(--kvyk-secondary); }
.kvyk-nav-item--accent { margin-bottom: var(--kvyk-space-sm); }
.kvyk-nav-item--accent:hover,
.kvyk-nav-item--accent.is-active,
.kvyk-nav-item--accent.is-active:hover {
  background: var(--kvyk-secondary-fixed);
  color: var(--kvyk-on-secondary-fixed-variant);
}

/* ---- Navigation (top bar links) ----------------------------------------- */
.kvyk-navlink {
  padding: var(--kvyk-space-xs) var(--kvyk-space-sm);
  border-radius: var(--kvyk-radius-sm);
  font-family: var(--kvyk-font-mono);
  font-size: 14px;
  font-weight: var(--kvyk-weight-medium);
  letter-spacing: 0.02em;
  color: var(--kvyk-on-surface-variant);
  text-decoration: none;
  transition: background-color var(--kvyk-duration) var(--kvyk-ease),
              color var(--kvyk-duration) var(--kvyk-ease);
}
.kvyk-navlink:hover { background: var(--kvyk-surface-container-low); color: var(--kvyk-on-surface); text-decoration: none; }
.kvyk-navlink.is-active { color: var(--kvyk-on-surface); }

/* ---- Breadcrumbs --------------------------------------------------------- */
/* Where a page sits, in mono chrome: each step a link, the page itself plain. */
.kvyk-breadcrumbs {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--kvyk-space-xs) var(--kvyk-space-sm);
  min-width: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  font-family: var(--kvyk-font-mono);
  font-size: 14px;
  line-height: 20px;
  font-weight: var(--kvyk-weight-medium);
  letter-spacing: 0.02em;
  color: var(--kvyk-on-surface-variant);
}
.kvyk-breadcrumbs li {
  display: inline-flex;
  align-items: center;
  gap: var(--kvyk-space-sm);
  min-width: 0;
}
.kvyk-breadcrumbs li + li::before {
  content: "/";
  color: var(--kvyk-outline-variant);
}
.kvyk-breadcrumbs a,
.kvyk-breadcrumbs [aria-current="page"] {
  max-width: 24ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kvyk-breadcrumbs a { color: inherit; text-decoration: none; }
.kvyk-breadcrumbs a:hover { color: var(--kvyk-secondary); }
.kvyk-breadcrumbs [aria-current="page"] { color: var(--kvyk-on-surface); }

/* ---- Avatar -------------------------------------------------------------- */
.kvyk-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--kvyk-radius-circle);
  background: var(--kvyk-primary-container);
  color: var(--kvyk-on-primary-container);
  font-family: var(--kvyk-font-mono);
  font-size: 12px;
  font-weight: var(--kvyk-weight-medium);
  overflow: hidden;
  flex-shrink: 0;
}
.kvyk-avatar img { width: 100%; height: 100%; object-fit: cover; }
.kvyk-avatar--sm { width: 24px; height: 24px; }
.kvyk-avatar--lg { width: 40px; height: 40px; }
.kvyk-avatar--bordered { border: 1px solid var(--kvyk-outline-variant); }

/* ---- Brand lockup -------------------------------------------------------- */
.kvyk-brand {
  display: inline-flex;
  align-items: center;
  gap: var(--kvyk-space-xs);
  font-family: var(--kvyk-font-sans);
  font-size: 24px;
  font-weight: var(--kvyk-weight-bold);
  letter-spacing: -0.01em;
  color: var(--kvyk-on-surface);
  text-decoration: none;
}
.kvyk-brand:hover { text-decoration: none; }
/* Sized to the brand name's cap height (~0.73em) plus the triangle's own padding
   inside its viewBox, so the mark lines up with the letters instead of overhanging.
   Nudged down slightly: the downward-pointing triangle reads high when centered, so
   this drops it to sit in line with the lowercase letters (the "v" in kvyk). */
.kvyk-brand__mark { width: 0.68em; height: 0.68em; transform: translateY(0.07em); }

/* ---- Stepper ------------------------------------------------------------- */
.kvyk-stepper {
  display: flex;
  align-items: flex-start;
}
.kvyk-step {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--kvyk-space-sm);
  text-align: center;
}
/* connector line, drawn from the previous step's marker */
.kvyk-step:not(:first-child)::before {
  content: "";
  position: absolute;
  top: 16px;
  right: 50%;
  left: -50%;
  height: 2px;
  background: var(--kvyk-outline-variant);
  z-index: 0;
}
.kvyk-step[data-state="complete"]:not(:first-child)::before,
.kvyk-step[data-state="active"]:not(:first-child)::before { background: var(--kvyk-secondary); }

.kvyk-step__marker {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--kvyk-radius-circle);
  border: 2px solid var(--kvyk-outline-variant);
  background: var(--kvyk-surface-container-lowest);
  color: var(--kvyk-outline);
  font-family: var(--kvyk-font-mono);
  font-size: 14px;
  font-weight: var(--kvyk-weight-medium);
}
.kvyk-step__label {
  font-family: var(--kvyk-font-sans);
  font-size: 13px;
  line-height: 18px;
  font-weight: var(--kvyk-weight-regular);
  color: var(--kvyk-on-surface-variant);
}
.kvyk-step[data-state="complete"] .kvyk-step__marker {
  background: var(--kvyk-secondary);
  border-color: var(--kvyk-secondary);
  color: var(--kvyk-on-secondary);
}
.kvyk-step[data-state="active"] .kvyk-step__marker {
  border-color: var(--kvyk-secondary);
  color: var(--kvyk-secondary);
  box-shadow: 0 0 0 4px rgba(0, 88, 190, 0.18);
}
.kvyk-step[data-state="active"] .kvyk-step__label { color: var(--kvyk-on-surface); font-weight: var(--kvyk-weight-semibold); }

/* ---- AI prompt bar ------------------------------------------------------- */
.kvyk-prompt {
  display: flex;
  align-items: center;
  gap: var(--kvyk-space-sm);
  padding: var(--kvyk-space-sm);
  background: var(--kvyk-surface-container-lowest);
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-lg);
  box-shadow: var(--kvyk-elevation-2);
  transition: border-color var(--kvyk-duration) var(--kvyk-ease),
              box-shadow var(--kvyk-duration) var(--kvyk-ease);
}
.kvyk-prompt:focus-within {
  border-color: var(--kvyk-secondary);
  box-shadow: 0 0 0 3px var(--kvyk-ring-color);
}
.kvyk-prompt__icon { color: var(--kvyk-secondary); padding-left: var(--kvyk-space-sm); }
.kvyk-prompt__input {
  flex: 1;
  min-width: 0; /* allow the input to shrink below its intrinsic size in narrow containers */
  height: 40px;
  border: none;
  background: transparent;
  font-family: var(--kvyk-font-sans);
  font-size: 18px;
  color: var(--kvyk-on-surface);
}
/* The bar shows focus via .kvyk-prompt:focus-within, so clear the input's own
   ring — the global :focus-visible paints a box-shadow, which outline:none misses. */
.kvyk-prompt__input:focus { outline: none; box-shadow: none; }
.kvyk-prompt__input::placeholder { color: var(--kvyk-on-surface-variant); opacity: 0.6; }

/* ---- Chat ---------------------------------------------------------------- */
.kvyk-chat { display: flex; flex-direction: column; gap: var(--kvyk-space-lg); }
.kvyk-bubble {
  max-width: 85%;
  padding: var(--kvyk-space-md);
  font-size: 14px;
  line-height: var(--kvyk-leading-body);
  border-radius: var(--kvyk-radius-lg);
}
.kvyk-bubble--user {
  align-self: flex-end;
  background: var(--kvyk-surface-container);
  color: var(--kvyk-on-surface);
  border: 1px solid var(--kvyk-outline-variant);
  border-top-right-radius: var(--kvyk-radius-xs);
}
.kvyk-bubble--ai {
  align-self: flex-start;
  background: var(--kvyk-surface-container-lowest);
  color: var(--kvyk-on-surface);
  border: 1px solid var(--kvyk-outline-variant);
  border-top-left-radius: var(--kvyk-radius-xs);
  box-shadow: var(--kvyk-elevation-1);
}
.kvyk-bubble__meta {
  font-family: var(--kvyk-font-mono);
  font-size: 11px;
  color: var(--kvyk-on-surface-variant);
  margin-top: var(--kvyk-space-xs);
}
/* What a message replies to, quoted at its start: quieter, after a rule. */
.kvyk-bubble__quote {
  margin: 0 0 var(--kvyk-space-xs);
  padding-left: var(--kvyk-space-sm);
  border-left: 2px solid var(--kvyk-outline-variant);
  color: var(--kvyk-on-surface-variant);
}

/* A prompt that grows with what is typed: Enter sends, Shift+Enter a new line.
   It grows up to eight lines (never past a third of the screen), then
   scrolls inside; the page sets its height to what it holds, and a browser
   that sizes fields to their content does so without it. */
.kvyk-prompt--multiline { align-items: flex-end; }
.kvyk-prompt--multiline .kvyk-prompt__icon { align-self: center; }
.kvyk-prompt--multiline .kvyk-prompt__input {
  height: auto;
  min-height: 40px;
  max-height: min(calc(8 * 22px + 18px), 33dvh);
  padding-block: 9px;
  overflow-y: auto;
  resize: none;
  field-sizing: content;
  font-size: 15px;
  line-height: 22px;
}
/* How many characters a message holds, shown quietly only near its limit;
   past it, in the error colour. */
.kvyk-prompt__count {
  margin: var(--kvyk-space-xs) 0 0;
  font-family: var(--kvyk-font-mono);
  font-size: 11px;
  line-height: 16px;
  text-align: right;
  color: var(--kvyk-on-surface-variant);
}
.kvyk-prompt__count--over { color: var(--kvyk-error); }

/* Messages written while the assistant works, waiting their turn at the foot
   of the conversation: the person's bubble, dashed and quieter, with what
   can be done with it under it. */
.kvyk-queued {
  display: flex;
  flex-direction: column;
  gap: var(--kvyk-space-md);
  margin: 0;
  padding: 0;
  list-style: none;
}
.kvyk-queued__item {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--kvyk-space-xs);
}
.kvyk-bubble--queued {
  max-width: 85%;
  white-space: pre-wrap;
  color: var(--kvyk-on-surface-variant);
  background: transparent;
  border-style: dashed;
}
.kvyk-queued__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--kvyk-space-xs);
}
.kvyk-queued__label {
  font-family: var(--kvyk-font-mono);
  font-size: 11px;
  line-height: 16px;
  color: var(--kvyk-on-surface-variant);
}

/* An assistant's answer, from its Markdown, in the size of the text around it:
   headings stay Inter at body sizes, tables are .kvyk-table, code is mono. */
.kvyk-prose > * { margin: 0; }
.kvyk-prose > * + * { margin-top: var(--kvyk-space-paragraph); }
.kvyk-prose strong { font-weight: var(--kvyk-weight-semibold); }
.kvyk-prose :is(h1, h2, h3, h4, h5, h6) {
  font-family: var(--kvyk-font-sans);
  font-weight: var(--kvyk-weight-semibold);
  color: var(--kvyk-on-surface);
  margin: 0;
}
.kvyk-prose :is(h1, h2) { font-size: 16px; line-height: var(--kvyk-leading-heading); }
.kvyk-prose :is(h3, h4, h5, h6) { font-size: inherit; line-height: var(--kvyk-leading-heading); }
.kvyk-prose > * + :is(h1, h2, h3, h4, h5, h6) { margin-top: var(--kvyk-space-lg); }
.kvyk-prose ul,
.kvyk-prose ol { padding-left: 1.25em; }
.kvyk-prose li > :is(ul, ol) { margin-top: var(--kvyk-space-2xs); }
.kvyk-prose li + li { margin-top: var(--kvyk-space-2xs); }
.kvyk-prose li > p { margin: 0; }
.kvyk-prose li > p + * { margin-top: var(--kvyk-space-2xs); }
.kvyk-prose hr {
  border: none;
  border-top: 1px solid var(--kvyk-outline-variant);
}
.kvyk-prose blockquote {
  margin: 0;
  padding-left: var(--kvyk-space-sm);
  border-left: 2px solid var(--kvyk-outline-variant);
  color: var(--kvyk-on-surface-variant);
}
.kvyk-prose pre {
  margin: 0;
  padding: var(--kvyk-space-sm);
  overflow-x: auto;
  border-radius: var(--kvyk-radius-sm);
  background: var(--kvyk-surface-container);
}
.kvyk-prose pre code { padding: 0; background: none; font-size: 12px; line-height: 18px; }
/* A table in an answer: the design system's, a little tighter. */
.kvyk-prose .kvyk-table thead th,
.kvyk-prose .kvyk-table tbody td { padding: var(--kvyk-space-xs) var(--kvyk-space-sm); }
.kvyk-prose .kvyk-table thead th { font-size: 11px; }
.kvyk-prose .kvyk-table tbody td { font-size: 13px; line-height: 18px; }
.kvyk-prose code {
  font-family: var(--kvyk-font-mono);
  font-size: 0.9em;
  padding: 0 4px;
  border-radius: var(--kvyk-radius-xs);
  background: var(--kvyk-surface-container);
}
.kvyk-prose a { color: var(--kvyk-secondary); text-decoration: underline; }

/* ---- Assistant ------------------------------------------------------------
   One conversation in three places (ADR-0042): the side panel in the
   sidebar's place on a desktop, resizable while open; the assistant page at
   full width; full screen on a phone, collapsible to a bar at the foot. */
.kvyk-sidebar--assistant {
  position: relative;
  width: var(--kvyk-assistant-width, 400px);
}
/* While the panel is open on a desktop it takes the nav's place. */
@media (min-width: 768px) {
  .kvyk-app-shell:has(> .kvyk-sidebar--assistant) > .kvyk-sidebar:not(.kvyk-sidebar--assistant) {
    display: none;
  }
}
.kvyk-assistant {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
  background: var(--kvyk-surface-container-lowest);
}
.kvyk-assistant__header {
  display: flex;
  align-items: center;
  gap: var(--kvyk-space-xs);
  flex-shrink: 0;
  height: var(--kvyk-header-height);
  padding-inline: var(--kvyk-space-md) var(--kvyk-space-sm);
  border-bottom: 1px solid var(--kvyk-outline-variant);
}
.kvyk-assistant__title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kvyk-assistant__log {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--kvyk-space-lg) var(--kvyk-space-md);
}
/* Reply, over what the person selects in the conversation: it sits just
   above where the selection starts, centred on it, and scrolls with it. */
.kvyk-assistant__selection-reply {
  position: absolute;
  z-index: 2;
  transform: translate(-50%, calc(-100% - var(--kvyk-space-2xs)));
  box-shadow: var(--kvyk-elevation-2);
}
/* A selection at the top of the view leaves no room above it. */
.kvyk-assistant__selection-reply--below { transform: translate(-50%, var(--kvyk-space-2xs)); }
/* The box to write in is the panel's last section, full width under a rule,
   not a box floating over the conversation; focus marks the rule. */
.kvyk-assistant__composer {
  flex-shrink: 0;
  padding: var(--kvyk-space-sm-md) var(--kvyk-space-md);
  border-top: 1px solid var(--kvyk-outline-variant);
  background: var(--kvyk-surface-container-lowest);
  transition: box-shadow var(--kvyk-duration) var(--kvyk-ease);
}
.kvyk-assistant__composer:focus-within { box-shadow: inset 0 2px 0 var(--kvyk-secondary); }
.kvyk-assistant__composer .kvyk-prompt,
.kvyk-assistant__composer .kvyk-prompt:focus-within {
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 0;
  box-shadow: none;
}
/* The conversation's name in its header: the most important words there. */
.kvyk-assistant__heading {
  margin: 0;
  font-family: var(--kvyk-font-sans);
  font-size: 15px;
  line-height: 22px;
  font-weight: var(--kvyk-weight-semibold);
  color: var(--kvyk-on-surface);
}
/* An answer: plain text on the conversation, as wide as it, with no frame
   or sender, so the person's own messages are the only bubbles. It reads as
   an article: a size up from the controls around it, paragraphs and list
   items apart, a heading well clear of what came before and close to what
   it heads, a rule with room on both sides. */
.kvyk-assistant__reply {
  display: flex;
  flex-direction: column;
  gap: var(--kvyk-space-md);
  font-size: 15px;
  line-height: 1.7;
  color: var(--kvyk-on-surface);
}
.kvyk-assistant .kvyk-bubble { font-size: 15px; }
.kvyk-assistant__reply .kvyk-prose :is(h1, h2) { font-size: 17px; }
.kvyk-assistant__reply .kvyk-prose :is(h3, h4, h5, h6) { font-size: 15px; }
.kvyk-assistant__reply .kvyk-prose > * + :is(h1, h2, h3, h4, h5, h6) { margin-top: var(--kvyk-space-xl); }
.kvyk-assistant__reply .kvyk-prose > :is(h1, h2, h3, h4, h5, h6) + * { margin-top: var(--kvyk-space-sm); }
.kvyk-assistant__reply .kvyk-prose li + li { margin-top: var(--kvyk-space-sm); }
.kvyk-assistant__reply .kvyk-prose li li + li { margin-top: var(--kvyk-space-xs); }
.kvyk-assistant__reply .kvyk-prose li > :is(ul, ol) { margin-top: var(--kvyk-space-xs); }
.kvyk-assistant__reply .kvyk-prose > hr,
.kvyk-assistant__reply .kvyk-prose > hr + * { margin-top: var(--kvyk-space-xl); }
/* The header's toggle while what it shows is open. */
.kvyk-assistant__header .kvyk-btn[aria-pressed="true"] {
  background: var(--kvyk-surface-selected);
  color: var(--kvyk-on-surface);
}
/* A button that reads as a link, for a row that opens its details in place. */
.kvyk-link-button {
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  color: var(--kvyk-secondary);
  text-align: left;
  text-decoration: underline;
  cursor: pointer;
}
.kvyk-link-button:focus-visible { outline: none; box-shadow: var(--kvyk-ring); }
/* Code or JSON to read, such as a request body's schema. */
.kvyk-code-block {
  margin: 0;
  padding: var(--kvyk-space-md);
  overflow-x: auto;
  font-family: var(--kvyk-font-mono);
  font-size: 12px;
  line-height: 18px;
  border-radius: var(--kvyk-radius-sm);
  background: var(--kvyk-surface-container);
}

/* A help page's text, at the page's reading size rather than a chat's. */
.kvyk-help-page { max-width: 46rem; }
.kvyk-help-page .kvyk-prose { font-size: 16px; }
.kvyk-help-page .kvyk-prose :is(h1, h2) { font-size: 20px; }
.kvyk-help-list { grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr)); }
.kvyk-assistant__starter:is(a) { text-decoration: none; }

/* Notes the assistant keeps, one under the other, each with its actions. */
.kvyk-notes { display: grid; gap: 0; margin: 0; padding: 0; list-style: none; }
.kvyk-notes__item {
  display: flex;
  flex-direction: column;
  gap: var(--kvyk-space-xs);
  padding: var(--kvyk-space-sm) 0;
  border-bottom: 1px solid var(--kvyk-outline-variant);
}
.kvyk-notes__item:first-child { padding-top: 0; }
.kvyk-notes__item:last-child { border-bottom: none; }

/* First prompts on a new conversation, chosen for the person and the page:
   each a card that sends its prompt. */
/* Each starter a square card of its own, apart from the next. */
.kvyk-assistant__starters {
  display: grid;
  gap: var(--kvyk-space-sm);
  margin: var(--kvyk-space-sm) 0 0;
  padding: 0;
  list-style: none;
}
.kvyk-assistant__starter {
  display: flex;
  flex-direction: column;
  gap: var(--kvyk-space-2xs);
  width: 100%;
  padding: var(--kvyk-space-sm-md) var(--kvyk-space-md);
  text-align: left;
  font: inherit;
  color: var(--kvyk-on-surface);
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-card);
  background: var(--kvyk-surface-container-lowest);
  cursor: pointer;
  transition: background-color var(--kvyk-duration) var(--kvyk-ease),
              border-color var(--kvyk-duration) var(--kvyk-ease);
}
.kvyk-assistant__starter:hover { background: var(--kvyk-surface-hover); border-color: var(--kvyk-outline); }
.kvyk-assistant__starter:focus-visible { outline: none; box-shadow: var(--kvyk-ring); }
.kvyk-assistant__starter-title {
  font-size: 14px;
  line-height: 20px;
  font-weight: var(--kvyk-weight-semibold);
}
.kvyk-assistant__starter-prompt {
  font-size: 12px;
  line-height: 16px;
  color: var(--kvyk-on-surface-variant);
}

/* Questions the assistant asks (ADR-0042): each in the input its kind needs,
   then Send and Skip. Its answers show after, as a short list. */
.kvyk-question {
  display: flex;
  flex-direction: column;
  gap: var(--kvyk-space-md);
  padding: var(--kvyk-space-md);
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-card);
  background: var(--kvyk-surface-container-lowest);
}
.kvyk-question__item {
  display: flex;
  flex-direction: column;
  gap: var(--kvyk-space-sm);
  min-width: 0;
  margin: 0;
  padding: 0;
  border: none;
}
.kvyk-question__label {
  padding: 0;
  font-family: var(--kvyk-font-sans);
  font-size: 14px;
  line-height: 20px;
  font-weight: var(--kvyk-weight-semibold);
  color: var(--kvyk-on-surface);
}
/* A fieldset's legend is not one of its flex items, so the item's gap does
   not reach it: it keeps its own distance from the choices under it. */
legend.kvyk-question__label { margin-bottom: var(--kvyk-space-sm); }
.kvyk-question__choices {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--kvyk-space-sm);
}
.kvyk-question__choices > .kvyk-input,
.kvyk-question__choices > .kvyk-combobox { align-self: stretch; }
.kvyk-question__choices > .kvyk-choice + .kvyk-input { margin-top: var(--kvyk-space-xs); }
.kvyk-question__colour {
  display: flex;
  align-items: center;
  gap: var(--kvyk-space-sm);
}
.kvyk-question__colour input[type="color"] {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  padding: 2px;
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-sm);
  background: var(--kvyk-surface-container-lowest);
  cursor: pointer;
}
.kvyk-question__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--kvyk-space-sm);
}
.kvyk-question__lines {
  margin: 0;
  padding-left: 1.25em;
  font-size: 14px;
  line-height: 20px;
}
.kvyk-question__answers {
  display: grid;
  gap: var(--kvyk-space-xs);
  margin: 0;
  padding-left: var(--kvyk-space-sm);
  border-left: 2px solid var(--kvyk-secondary);
}
.kvyk-question__answers dt { font-size: 12px; line-height: 16px; color: var(--kvyk-on-surface-variant); }
.kvyk-question__answers dd { margin: 0; font-size: 14px; line-height: 20px; }
/* A step the assistant took ("Read the model"), with how it went. */
.kvyk-assistant__step {
  display: flex;
  align-items: center;
  gap: var(--kvyk-space-sm);
  font-family: var(--kvyk-font-mono);
  font-size: 12px;
  color: var(--kvyk-on-surface-variant);
}
/* A turn's steps folded into one line: what it does now while it works, how
   many steps it took (and how many did not work) once done. The line is as
   quiet as a step's, with no frame or fill, and is the button that unfolds
   the list and folds it again. */
.kvyk-steps {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--kvyk-space-sm);
  min-width: 0;
}
.kvyk-steps__toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--kvyk-space-sm);
  max-width: 100%;
  padding: 0;
  font-family: var(--kvyk-font-mono);
  font-size: 12px;
  line-height: 16px;
  text-align: left;
  color: var(--kvyk-on-surface-variant);
  background: none;
  border: none;
  border-radius: var(--kvyk-radius-xs);
  cursor: pointer;
}
.kvyk-steps__toggle:hover { color: var(--kvyk-on-surface); }
.kvyk-steps__toggle:focus-visible { outline: none; box-shadow: var(--kvyk-ring); }
.kvyk-steps__toggle .kvyk-icon { width: 14px; height: 14px; flex-shrink: 0; transition: transform var(--kvyk-duration-fast) var(--kvyk-ease); }
.kvyk-steps__toggle[aria-expanded="true"] .kvyk-icon { transform: rotate(180deg); }
.kvyk-steps__working { flex-shrink: 0; font-weight: var(--kvyk-weight-medium); color: var(--kvyk-on-surface); }
.kvyk-steps__now {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kvyk-steps__failed { flex-shrink: 0; color: var(--kvyk-on-error-container); }
/* A turn the person stopped: said beside its count, not as a failure. */
.kvyk-steps__stopped { flex-shrink: 0; color: var(--kvyk-on-surface); }
/* A step that failed and was then done again: said beside its line. */
.kvyk-steps__fixed { color: var(--kvyk-on-tertiary-fixed-variant); }
.kvyk-steps__list {
  display: grid;
  gap: var(--kvyk-space-sm);
  width: 100%;
  margin: 0;
  padding: 0 0 0 var(--kvyk-space-md);
  list-style: none;
  border-left: 2px solid var(--kvyk-outline-variant);
}
.kvyk-steps__list > li { display: grid; gap: var(--kvyk-space-xs); min-width: 0; }
/* The technical side of a step (the file read, the command run), kept off its main line. */
.kvyk-steps__detail {
  margin: 0 0 0 calc(8px + var(--kvyk-space-sm));
  font-family: var(--kvyk-font-mono);
  font-size: 11px;
  line-height: 16px;
  color: var(--kvyk-on-surface-variant);
  overflow-wrap: break-word;
}
/* The page's own version: one bar over the conversation, which fills the
   main column edge to edge at a reading width; the person's conversations
   open in a column beside it only when asked for. The page itself does not
   scroll: the list and the conversation do, and the box to write in stays at
   the foot of the window. On a phone the conversations show in its place. */
.kvyk-main:has(.kvyk-assistant-view) { overflow: hidden; }
.kvyk-page:has(> .kvyk-assistant-view) {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
  max-width: none;
  padding: 0;
}
.kvyk-assistant-view {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
}
.kvyk-assistant-page {
  display: grid;
  flex: 1;
  grid-template-columns: minmax(0, 1fr);
  min-height: 0;
  background: var(--kvyk-surface-container-lowest);
}
.kvyk-assistant-page.is-history { grid-template-columns: 280px minmax(0, 1fr); }
.kvyk-assistant-page__bar { padding-inline: var(--kvyk-space-sm) var(--kvyk-margin-desktop); }
.kvyk-assistant-page__bar .kvyk-assistant__heading { margin-left: var(--kvyk-space-xs); }
.kvyk-assistant-view .kvyk-assistant__log { padding-inline: var(--kvyk-margin-desktop); }
.kvyk-assistant-view .kvyk-chat,
.kvyk-assistant-view .kvyk-assistant__composer > .kvyk-prompt {
  max-width: 46rem;
  margin-inline: auto;
}
.kvyk-assistant-page__history {
  display: flex;
  flex-direction: column;
  min-height: 0;
  border-right: 1px solid var(--kvyk-outline-variant);
  background: var(--kvyk-surface-container-lowest);
}
.kvyk-assistant-page__back { display: none; }

/* A person's conversations: a search, then the newest first under Today,
   Yesterday and Earlier. A row's title leads; its time, and in a search the
   words that matched, follow smaller and muted. Its delete shows on hover or
   focus, and always on a touch screen. */
.kvyk-history {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}
/* The search is the band itself, flush with the column: no box in a box. */
.kvyk-history__search {
  display: flex;
  align-items: center;
  gap: var(--kvyk-space-sm);
  flex-shrink: 0;
  height: var(--kvyk-header-height);
  padding-inline: var(--kvyk-space-md) var(--kvyk-space-sm);
  border-bottom: 1px solid var(--kvyk-outline-variant);
  color: var(--kvyk-on-surface-variant);
  transition: background-color var(--kvyk-duration) var(--kvyk-ease),
              box-shadow var(--kvyk-duration) var(--kvyk-ease);
}
.kvyk-history__search:focus-within {
  background: var(--kvyk-surface-container-lowest);
  box-shadow: inset 0 -2px 0 var(--kvyk-secondary);
}
.kvyk-history__input {
  flex: 1;
  min-width: 0;
  height: 100%;
  padding: 0;
  border: none;
  background: none;
  font-family: var(--kvyk-font-sans);
  font-size: 14px;
  line-height: 20px;
  color: var(--kvyk-on-surface);
}
.kvyk-history__input::placeholder { color: var(--kvyk-on-surface-variant); }
.kvyk-history__input:focus,
.kvyk-history__input:focus-visible { outline: none; box-shadow: none; }
.kvyk-history__body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding-block: var(--kvyk-space-sm) var(--kvyk-space-md);
}
.kvyk-history__group + .kvyk-history__group { margin-top: var(--kvyk-space-md); }
.kvyk-history__heading {
  margin: 0;
  padding: var(--kvyk-space-xs) var(--kvyk-space-md);
  font-size: 11px;
}
.kvyk-history__item .kvyk-history__delete { margin-right: var(--kvyk-space-2xs); }
.kvyk-history__list { margin: 0; padding: 0; list-style: none; }
.kvyk-history__item {
  display: flex;
  align-items: center;
  margin-inline: var(--kvyk-space-sm);
  border-radius: var(--kvyk-radius-sm);
  transition: background-color var(--kvyk-duration) var(--kvyk-ease);
}
.kvyk-history__item:hover { background: var(--kvyk-surface-hover); }
.kvyk-history__item.is-active { background: var(--kvyk-surface-selected); }
.kvyk-history__open {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: var(--kvyk-space-2xs);
  min-width: 0;
  padding: var(--kvyk-space-sm);
  border: none;
  background: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.kvyk-history__open:focus-visible { outline: none; box-shadow: inset var(--kvyk-ring); border-radius: var(--kvyk-radius-sm); }
.kvyk-history__line {
  display: flex;
  align-items: baseline;
  gap: var(--kvyk-space-sm);
  min-width: 0;
}
.kvyk-history__title {
  flex: 1;
  min-width: 0;
  margin: 0;
  overflow: hidden;
  font-family: var(--kvyk-font-sans);
  font-size: 14px;
  line-height: 20px;
  font-weight: var(--kvyk-weight-regular);
  color: var(--kvyk-on-surface);
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* An answer the person has not read yet. */
.kvyk-history__item.is-unread .kvyk-history__title { font-weight: var(--kvyk-weight-semibold); }
.kvyk-history__excerpt {
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  font-size: 13px;
  line-height: 18px;
  color: var(--kvyk-on-surface);
}
.kvyk-history__meta {
  margin: 0;
  font-family: var(--kvyk-font-sans);
  font-size: 12px;
  line-height: 16px;
  color: var(--kvyk-on-surface-variant);
}
/* A row's time and Delete are there only while it is pointed at, focused or
   (on a touch screen) open; then its name gives way to them, cut short. */
.kvyk-history__line .kvyk-history__meta { flex-shrink: 0; }
.kvyk-history__delete { flex-shrink: 0; }
/* Where the next page loads as the list is scrolled to its end. */
.kvyk-history__more { min-height: 1px; }
.kvyk-history__note {
  margin: 0;
  padding: var(--kvyk-space-sm) var(--kvyk-space-md);
  font-size: 14px;
  line-height: 20px;
  color: var(--kvyk-on-surface-variant);
}

/* A handle on a panel's edge that drags (or, focused, arrows) its width. */
.kvyk-resizer {
  position: absolute;
  top: 0;
  right: -4px;
  bottom: 0;
  width: 8px;
  cursor: col-resize;
  z-index: 1;
  background: transparent;
  touch-action: none;
}
.kvyk-resizer::after {
  content: "";
  position: absolute;
  inset: 0 3px;
  background: transparent;
  transition: background var(--kvyk-duration) var(--kvyk-ease);
}
.kvyk-resizer:hover::after,
.kvyk-resizer:focus-visible::after,
.kvyk-resizer.is-dragging::after { background: var(--kvyk-secondary); }
.kvyk-resizer:focus-visible { outline: none; box-shadow: none; }

/* What shows only in one size: the phone's collapse, the desktop's expand. */
.kvyk-assistant__collapse,
.kvyk-assistant__bar { display: none; }
@media (max-width: 767px) {
  .kvyk-sidebar--assistant {
    display: flex;
    position: fixed;
    inset: 0;
    width: 100%;
    z-index: var(--kvyk-z-overlay);
  }
  .kvyk-sidebar--assistant .kvyk-resizer,
  .kvyk-assistant__expand { display: none; }
  .kvyk-assistant__collapse { display: inline-flex; }
  /* Collapsed: a bar at the foot of the page, tapped to expand. */
  .kvyk-sidebar--assistant.is-collapsed {
    inset: auto 0 0 0;
    height: auto;
    border-right: none;
    border-top: 1px solid var(--kvyk-outline-variant);
    box-shadow: var(--kvyk-elevation-3);
  }
  .kvyk-sidebar--assistant.is-collapsed .kvyk-assistant { display: none; }
  .kvyk-sidebar--assistant.is-collapsed .kvyk-assistant__bar {
    display: flex;
    align-items: center;
    gap: var(--kvyk-space-sm);
    width: 100%;
    min-height: 56px;
    padding: var(--kvyk-space-sm) var(--kvyk-space-md);
    border: none;
    background: var(--kvyk-surface-container-lowest);
    color: var(--kvyk-on-surface);
    text-align: left;
    font: inherit;
    cursor: pointer;
  }
  /* The page on a phone: the bar's actions as icons, and the conversations
     in the conversation's place while they are open. */
  .kvyk-assistant-page__bar { padding-inline: var(--kvyk-space-xs) var(--kvyk-space-sm); }
  .kvyk-assistant-page__new { padding-inline: var(--kvyk-space-sm); }
  .kvyk-assistant-page__new-label { display: none; }
  .kvyk-assistant-view .kvyk-assistant__log { padding-inline: var(--kvyk-space-md); }
  .kvyk-assistant-page.is-history { grid-template-columns: minmax(0, 1fr); }
  .kvyk-assistant-page__history { border-right: none; }
  .kvyk-assistant-page.is-history .kvyk-assistant { display: none; }
  .kvyk-assistant-page__back {
    display: inline-flex;
    align-self: flex-start;
    margin: var(--kvyk-space-sm) var(--kvyk-space-sm) 0;
  }
}

/* ---- Ask kvyk --------------------------------------------------------------
   The prompt on every page, on a bar of its own under the app bar, the main
   column's full width: a quiet field with its shortcut, which opens the
   assistant in the side panel. The two bars stick to the top together
   (`.kvyk-appbar-group` around them). On a phone the shortcut is left out. */
.kvyk-appbar-group {
  position: sticky;
  top: 0;
  flex-shrink: 0;
  z-index: var(--kvyk-z-header);
}
.kvyk-askbar {
  display: flex;
  padding: var(--kvyk-space-sm) var(--kvyk-margin-desktop);
  background: rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--kvyk-outline-variant);
}
.kvyk-ask {
  display: flex;
  align-items: center;
  gap: var(--kvyk-space-sm);
  flex: 1;
  min-width: 0;
  height: 36px;
  padding-inline: var(--kvyk-space-sm-md) var(--kvyk-space-xs);
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-sm);
  background: var(--kvyk-surface-container-lowest);
  color: var(--kvyk-secondary);
  transition: border-color var(--kvyk-duration) var(--kvyk-ease),
              box-shadow var(--kvyk-duration) var(--kvyk-ease);
}
.kvyk-ask:hover { border-color: var(--kvyk-outline); }
.kvyk-ask:focus-within {
  border-color: var(--kvyk-secondary);
  box-shadow: 0 0 0 3px var(--kvyk-ring-color);
}
.kvyk-ask__input {
  flex: 1;
  min-width: 0;
  height: 100%;
  padding: 0;
  border: none;
  background: none;
  font-family: var(--kvyk-font-sans);
  font-size: 14px;
  color: var(--kvyk-on-surface);
}
.kvyk-ask__input::placeholder { color: var(--kvyk-on-surface-variant); }
.kvyk-ask__input:focus,
.kvyk-ask__input:focus-visible { outline: none; box-shadow: none; }
.kvyk-ask:focus-within .kvyk-ask__keys { visibility: hidden; }
@media (max-width: 767px) {
  .kvyk-askbar { padding-inline: var(--kvyk-margin-mobile); }
  .kvyk-askbar:not(.is-open) { display: none; }
  .kvyk-ask .kvyk-ask__keys { display: none; }
}

/* The app bar's controls on a phone, smaller: Ask kvyk behind a sparkle
   button (`.kvyk-appbar__ask`) that shows its bar (`.kvyk-askbar.is-open`),
   the stage as a drop-down (`.kvyk-appbar__stage-menu`) in place of its
   segmented switch (`.kvyk-appbar__stage`), and a menu button's arrow left out
   where the button alone says enough (`.kvyk-appbar__chevron`: the language's
   flag). On a desktop only the segmented switch and the arrows show. */
.kvyk-appbar__chevron { display: inline-flex; }
.kvyk-appbar .kvyk-appbar__ask,
.kvyk-appbar .kvyk-appbar__stage-menu { display: none; }
@media (max-width: 767px) {
  .kvyk-appbar .kvyk-appbar__ask { display: inline-flex; color: var(--kvyk-secondary); }
  .kvyk-appbar .kvyk-appbar__stage-menu { display: block; }
  .kvyk-appbar .kvyk-appbar__stage,
  .kvyk-appbar .kvyk-appbar__chevron { display: none; }
}

/* ---- Home -----------------------------------------------------------------
   An organisation's front door: what the person wants to do, asked in a
   large box with the first prompts under it, then the organisation in a few
   counts that link on. */
.kvyk-home {
  display: flex;
  flex-direction: column;
  gap: var(--kvyk-space-2xl);
}
.kvyk-home__ask {
  display: flex;
  flex-direction: column;
  gap: var(--kvyk-space-md);
  width: 100%;
  max-width: 44rem;
  margin: var(--kvyk-space-xl) auto 0;
}
.kvyk-home__ask > .kvyk-overline { margin: 0; text-align: center; }
.kvyk-home__ask > h1 { margin: 0; text-align: center; }
.kvyk-home__prompt { padding: var(--kvyk-space-sm) var(--kvyk-space-sm) var(--kvyk-space-sm) var(--kvyk-space-xs); }
.kvyk-home__prompt .kvyk-prompt__input { height: 48px; }
.kvyk-home__ask .kvyk-assistant__starters {
  grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  margin: 0;
}
.kvyk-home__tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
  gap: var(--kvyk-space-md);
  margin: 0;
  padding: 0;
  list-style: none;
}
.kvyk-home__tiles > li { display: flex; }
.kvyk-home__tile {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: var(--kvyk-space-xs);
  padding: var(--kvyk-space-md) var(--kvyk-space-lg);
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-card);
  background: var(--kvyk-surface-container-lowest);
  color: var(--kvyk-on-surface);
  text-decoration: none;
  transition: border-color var(--kvyk-duration) var(--kvyk-ease),
              background-color var(--kvyk-duration) var(--kvyk-ease);
}
.kvyk-home__tile:hover {
  border-color: var(--kvyk-outline);
  background: var(--kvyk-surface-hover);
  text-decoration: none;
}
.kvyk-home__tile:focus-visible { outline: none; box-shadow: var(--kvyk-ring); }
.kvyk-home__tile-head {
  display: flex;
  align-items: center;
  gap: var(--kvyk-space-sm);
  color: var(--kvyk-on-surface-variant);
}
.kvyk-home__apps {
  margin: 0;
  padding: 0;
  list-style: none;
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-card);
  background: var(--kvyk-surface-container-lowest);
}
.kvyk-home__apps > li + li { border-top: 1px solid var(--kvyk-outline-variant); }
.kvyk-home__app {
  display: flex;
  align-items: center;
  gap: var(--kvyk-space-sm);
  padding: var(--kvyk-space-sm-md) var(--kvyk-space-md);
  color: var(--kvyk-on-surface);
  text-decoration: none;
}
.kvyk-home__app:hover { background: var(--kvyk-surface-hover); text-decoration: none; }
.kvyk-home__app > .kvyk-icon { color: var(--kvyk-on-surface-variant); }
@media (max-width: 767px) {
  .kvyk-home { gap: var(--kvyk-space-xl); }
  .kvyk-home__ask { margin-top: 0; }
}

/* ---- Alert / Insight ----------------------------------------------------- */
.kvyk-alert {
  --_accent: var(--kvyk-secondary);
  --_bg: var(--kvyk-surface-container-low);
  display: flex;
  gap: var(--kvyk-space-sm);
  padding: var(--kvyk-space-md);
  background: var(--_bg);
  border: 1px solid var(--kvyk-outline-variant);
  border-left: 3px solid var(--_accent);
  border-radius: var(--kvyk-radius-md);
}
.kvyk-alert__icon { color: var(--_accent); flex-shrink: 0; }
.kvyk-alert__title { font-weight: var(--kvyk-weight-semibold); color: var(--kvyk-on-surface); font-size: 14px; }
.kvyk-alert__body { font-size: 14px; line-height: var(--kvyk-leading-body); color: var(--kvyk-on-surface-variant); }
.kvyk-alert--info { --_accent: var(--kvyk-secondary); }
.kvyk-alert--success { --_accent: var(--kvyk-tertiary-fixed-dim); }
.kvyk-alert--warning { --_accent: #b8860b; }
.kvyk-alert--danger { --_accent: var(--kvyk-error); --_bg: var(--kvyk-error-container); }
/* AI suggestion variant: subtle blue glow, no hard left bar. */
.kvyk-alert--ai {
  border: 1px solid var(--kvyk-secondary-fixed-dim);
  border-left: 1px solid var(--kvyk-secondary-fixed-dim);
  background: var(--kvyk-surface-container-low);
}

/* ---- Info card ----------------------------------------------------------- */
/* What a page is about, said once, quietly: an info icon, a sentence or two
   and a link to the documentation. No rail, no title, so it reads as a note
   and never as a warning. */
.kvyk-info {
  display: flex;
  align-items: flex-start;
  gap: var(--kvyk-space-sm-md);
  padding: var(--kvyk-space-sm-md) var(--kvyk-space-md);
  background: var(--kvyk-surface-container-low);
  border: 1px solid var(--kvyk-surface-container-high);
  border-radius: var(--kvyk-radius-md);
}
.kvyk-info__icon {
  display: inline-flex;
  padding-top: 2px;
  color: var(--kvyk-secondary);
  flex-shrink: 0;
}
.kvyk-info__body {
  max-width: var(--kvyk-measure);
  font-size: 14px;
  line-height: var(--kvyk-leading-body);
  color: var(--kvyk-on-surface-variant);
}
.kvyk-info__link {
  display: inline-flex;
  align-items: center;
  gap: var(--kvyk-space-xs);
  margin-left: var(--kvyk-space-xs);
  font-weight: var(--kvyk-weight-medium);
  white-space: nowrap;
}
.kvyk-info__link .kvyk-icon { width: 14px; height: 14px; }

/* ---- Toast --------------------------------------------------------------- */
/* What just happened to something the person did: a short message that floats
   over the page and goes, bottom right on a desktop, across the foot of the
   screen on a phone. The region holds the newest last. */
.kvyk-toasts {
  position: fixed;
  right: var(--kvyk-space-lg);
  bottom: var(--kvyk-space-lg);
  z-index: var(--kvyk-z-toast);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--kvyk-space-sm);
  width: min(420px, calc(100vw - 2 * var(--kvyk-space-md)));
  margin: 0;
  padding: 0;
  list-style: none;
  pointer-events: none;
}
.kvyk-toast {
  --_accent: var(--kvyk-on-tertiary-container);
  display: flex;
  align-items: flex-start;
  gap: var(--kvyk-space-sm);
  width: 100%;
  padding: var(--kvyk-space-xs) var(--kvyk-space-xs) var(--kvyk-space-xs) var(--kvyk-space-md);
  color: var(--kvyk-on-surface);
  background: var(--kvyk-surface-container-lowest);
  border: 1px solid var(--kvyk-outline-variant);
  border-left: 3px solid var(--_accent);
  border-radius: var(--kvyk-radius-md);
  box-shadow: var(--kvyk-elevation-3);
  pointer-events: auto;
  animation: kvyk-toast-in var(--kvyk-duration-slow) var(--kvyk-ease);
}
.kvyk-toast.is-leaving { animation: kvyk-toast-out var(--kvyk-duration) var(--kvyk-ease) forwards; }
.kvyk-toast--success { --_accent: var(--kvyk-on-tertiary-container); }
.kvyk-toast--danger { --_accent: var(--kvyk-error); }
.kvyk-toast__icon {
  display: inline-flex;
  padding-block: 10px;
  color: var(--_accent);
  flex-shrink: 0;
}
.kvyk-toast__text {
  flex: 1;
  min-width: 0;
  padding-block: 8px;
  font-size: 14px;
  line-height: var(--kvyk-leading-body);
  overflow-wrap: break-word;
}
.kvyk-toast__close { flex-shrink: 0; }
@media (max-width: 767px) {
  .kvyk-toasts {
    left: var(--kvyk-space-md);
    right: var(--kvyk-space-md);
    bottom: var(--kvyk-space-md);
    width: auto;
    align-items: stretch;
  }
}
@keyframes kvyk-toast-in {
  from { opacity: 0; transform: translateY(8px); }
}
@keyframes kvyk-toast-out {
  to { opacity: 0; transform: translateY(8px); }
}

/* ---- Dialog -------------------------------------------------------------- */
/* A question that must be answered before going on, such as "Delete this?":
   the native <dialog>, opened with showModal(), so the page behind is out of
   reach and Escape cancels. Its content sits in __panel, so a click on the
   backdrop is a click on the dialog itself. The confirm button is a
   .kvyk-btn--danger when the step cannot be undone. It sits wherever its
   trigger does, a table's actions cell among them, so it sets its own text
   alignment and wrapping rather than inheriting that cell's. */
.kvyk-dialog {
  width: min(480px, calc(100vw - 2 * var(--kvyk-space-md)));
  text-align: start;
  white-space: normal;
  overflow-wrap: break-word;
  max-width: none;
  max-height: calc(100dvh - 2 * var(--kvyk-space-md));
  margin: auto;
  padding: 0;
  overflow: auto;
  color: var(--kvyk-on-surface);
  background: var(--kvyk-surface-container-lowest);
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-lg);
  box-shadow: var(--kvyk-elevation-3);
}
.kvyk-dialog[open] { animation: kvyk-dialog-in var(--kvyk-duration) var(--kvyk-ease); }
.kvyk-dialog::backdrop { background: var(--kvyk-scrim); }
.kvyk-dialog__panel {
  --_flow-gap: var(--kvyk-space-sm-md);
  display: flex;
  flex-direction: column;
  gap: var(--_flow-gap);
  padding: var(--kvyk-space-lg);
}
.kvyk-dialog__title {
  font-size: 18px;
  line-height: var(--kvyk-leading-heading);
  font-weight: var(--kvyk-weight-semibold);
  color: var(--kvyk-on-surface);
}
.kvyk-dialog__body {
  font-size: 14px;
  line-height: var(--kvyk-leading-body);
  color: var(--kvyk-on-surface-variant);
}
.kvyk-dialog__footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--kvyk-space-sm);
  margin-top: var(--kvyk-space-sm);
}
@media (max-width: 479px) {
  .kvyk-dialog__footer { flex-direction: column-reverse; }
  .kvyk-dialog__footer > .kvyk-btn { width: 100%; }
}
@keyframes kvyk-dialog-in {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
}

/* ---- List (activity / settings rows) ------------------------------------ */
.kvyk-list {
  margin: 0;
  padding: 0;
  list-style: none;
  background: var(--kvyk-surface-container-lowest);
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-card);
  overflow: hidden;
}
.kvyk-list-item {
  display: flex;
  gap: var(--kvyk-space-md);
  padding: var(--kvyk-space-sm-md) var(--kvyk-space-md);
  transition: background-color var(--kvyk-duration) var(--kvyk-ease);
}
/* A row with small buttons is as tall as a row of text, not taller. */
.kvyk-list-item:has(.kvyk-btn--sm) { padding-block: var(--kvyk-space-xs); align-items: center; }
.kvyk-list-item + .kvyk-list-item { border-top: 1px solid var(--kvyk-outline-variant); }
.kvyk-list-item--interactive { cursor: pointer; }
.kvyk-list-item--interactive:hover { background: var(--kvyk-surface-hover); }
/* A list whose order matters: each row leads with its number. */
.kvyk-list--numbered { counter-reset: kvyk-list; }
.kvyk-list--numbered > .kvyk-list-item { counter-increment: kvyk-list; }
.kvyk-list--numbered > .kvyk-list-item::before {
  content: counter(kvyk-list);
  min-width: 2ch;
  font-family: var(--kvyk-font-mono);
  font-size: 12px;
  color: var(--kvyk-on-surface-variant);
  text-align: right;
}
.kvyk-list-item__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--kvyk-radius-circle);
  flex-shrink: 0;
  background: var(--kvyk-surface-container);
  color: var(--kvyk-secondary);
}

/* ---- Table --------------------------------------------------------------- */
.kvyk-table-wrap {
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-card);
  /* Scroll a too-wide table horizontally instead of clipping it; the rounded
     corners are still clipped, and the scrollbar only shows when it overflows. */
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: var(--kvyk-outline) transparent;
}
/* A table wider than its wrap scrolls sideways, and says so: a shade on the
   edge that hides columns, gone once scrolled to it (the covers scroll with
   the table, the shades stay with the wrap), and a scrollbar that shows. */
.kvyk-table-wrap {
  background:
    linear-gradient(to right, var(--kvyk-surface-container-lowest) 30%, transparent) left / 24px 100% no-repeat local,
    linear-gradient(to left, var(--kvyk-surface-container-lowest) 30%, transparent) right / 24px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%, var(--kvyk-scroll-shadow), transparent) left / 12px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, var(--kvyk-scroll-shadow), transparent) right / 12px 100% no-repeat scroll,
    var(--kvyk-surface-container-lowest);
}
.kvyk-table-wrap::-webkit-scrollbar { height: 8px; }
.kvyk-table-wrap::-webkit-scrollbar-thumb {
  background: var(--kvyk-outline);
  border-radius: var(--kvyk-radius-pill);
}
.kvyk-table-wrap::-webkit-scrollbar-track { background: transparent; }
/* A table with a footer band under its last row (counts, paging): the panel
   carries the border, the wrap inside scrolls, and the band does not. */
.kvyk-table-panel {
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-card);
  background: var(--kvyk-surface-container-lowest);
  overflow: hidden;
}
.kvyk-table-panel > :is(.kvyk-table-wrap, .kvyk-list) { border: none; border-radius: 0; }
.kvyk-table-footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--kvyk-space-sm) var(--kvyk-space-md);
  padding: var(--kvyk-space-sm) var(--kvyk-space-md);
  border-top: 1px solid var(--kvyk-outline-variant);
  color: var(--kvyk-on-surface-variant);
}
.kvyk-table { width: 100%; border-collapse: collapse; }
.kvyk-table thead th {
  text-align: left;
  padding: var(--kvyk-space-sm-md) var(--kvyk-space-md);
  font-family: var(--kvyk-font-mono);
  font-size: 11px;
  line-height: 16px;
  font-weight: var(--kvyk-weight-medium);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--kvyk-on-surface-variant);
  border-bottom: 1px solid var(--kvyk-outline-variant);
  white-space: nowrap;
}
.kvyk-table tbody td {
  padding: var(--kvyk-space-sm-md) var(--kvyk-space-md);
  vertical-align: middle;
  font-size: 14px;
  line-height: 20px;
  color: var(--kvyk-on-surface);
  border-bottom: 1px solid var(--kvyk-outline-variant);
}
.kvyk-table tbody tr:last-child td { border-bottom: none; }
/* Running text in a cell sets at the cell's own line (20px at 14px), so a
   paragraph there keeps the row as tall as a row of text. */
.kvyk-table :is(th, td) { --kvyk-leading-body: calc(20 / 14); }
/* A row's quieter second line, under its main value. */
.kvyk-table__secondary {
  margin-top: var(--kvyk-space-xs);
  font-family: var(--kvyk-font-mono);
  font-size: 12px;
  line-height: 16px;
  color: var(--kvyk-on-surface-variant);
}
/* Numbers line up on their last digit. */
.kvyk-table .is-numeric {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
/* A sortable column's header is a button; `aria-sort` on the cell says which way. */
.kvyk-table thead th button {
  display: inline-flex;
  align-items: center;
  gap: var(--kvyk-space-xs);
  padding: 0;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
}
.kvyk-table thead th button:hover,
.kvyk-table thead th[aria-sort] button { color: var(--kvyk-on-surface); }
.kvyk-table thead th button .kvyk-icon { width: 14px; height: 14px; }
.kvyk-table tbody tr { transition: background-color var(--kvyk-duration) var(--kvyk-ease); }
/* Rows alternate, so the eye keeps its line across a wide table. A row's
   detail opened under it (.kvyk-table__detail) belongs to it: it takes that
   row's colour and does not count, so the rows after it keep alternating. */
.kvyk-table tbody tr:where(:nth-child(even of :not(.kvyk-table__detail))),
.kvyk-table tbody tr:where(:nth-child(even of :not(.kvyk-table__detail))) + tr.kvyk-table__detail {
  background: var(--kvyk-table-stripe);
}
.kvyk-table tbody tr:not(.kvyk-table__detail):hover { background: var(--kvyk-table-hover); }
.kvyk-table tbody tr:has(.kvyk-btn--sm) td { padding-block: var(--kvyk-space-xs); }
/* A grid of records: each short value on one line; a long text gives way
   instead, at most two lines and then an ellipsis (the record's page shows it
   whole), so the columns fit before the table has to scroll. */
.kvyk-table--grid tbody td { white-space: nowrap; }
.kvyk-table--grid tbody td.is-long {
  min-width: 10rem;
  max-width: 24rem;
  white-space: normal;
}
.kvyk-clamp {
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow-wrap: break-word;
}
/* One line and then an ellipsis, the whole text in the element's title. In a
   table cell it takes the room the other columns leave, never less than a
   readable width, so the table scrolls before the text disappears. */
.kvyk-truncate {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kvyk-table td:has(> .kvyk-truncate) { width: 100%; max-width: 0; min-width: 12rem; }
/* The cell of a row's actions: at the row's end, its buttons close together. */
.kvyk-table td.kvyk-table__actions { text-align: right; white-space: nowrap; }
.kvyk-table td.kvyk-table__actions > * + * { margin-left: var(--kvyk-space-xs); }
.kvyk-table td.kvyk-table__actions .kvyk-cluster { justify-content: flex-end; flex-wrap: nowrap; }
/* A last cell of only buttons is a row's actions too, without the class. */
.kvyk-table tbody td:last-child:has(> .kvyk-btn, > .kvyk-cluster > .kvyk-btn) { text-align: right; white-space: nowrap; }
.kvyk-table tbody td:last-child > .kvyk-cluster:has(> .kvyk-btn) { justify-content: flex-end; flex-wrap: nowrap; }

/* ---- Tooltip ------------------------------------------------------------- */
.kvyk-tooltip { position: relative; display: inline-flex; }
.kvyk-tooltip__bubble {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  padding: 6px 10px;
  background: var(--kvyk-inverse-surface);
  color: var(--kvyk-inverse-on-surface);
  font-family: var(--kvyk-font-mono);
  font-size: 12px;
  line-height: 16px;
  white-space: nowrap;
  border-radius: var(--kvyk-radius-sm);
  box-shadow: var(--kvyk-elevation-2);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--kvyk-duration) var(--kvyk-ease),
              transform var(--kvyk-duration) var(--kvyk-ease);
  z-index: var(--kvyk-z-tooltip);
  /* Its own type, whatever its trigger sits in: a table header's capitals
     and spacing are not the tip's. */
  text-align: start;
  text-transform: none;
  letter-spacing: normal;
  font-weight: var(--kvyk-weight-regular);
}
.kvyk-tooltip:hover .kvyk-tooltip__bubble,
.kvyk-tooltip:focus-within .kvyk-tooltip__bubble {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
/* A tip of a sentence or two wraps instead of running off a narrow panel. */
.kvyk-tooltip__bubble--wrap {
  width: max-content;
  max-width: 240px;
  white-space: normal;
}
/* A tip that opens from its trigger's start edge, for a trigger near the
   left of a narrow panel, where a centred bubble would be cut off. */
.kvyk-tooltip--start .kvyk-tooltip__bubble { left: 0; transform: translateY(4px); }
.kvyk-tooltip--start:hover .kvyk-tooltip__bubble,
.kvyk-tooltip--start:focus-within .kvyk-tooltip__bubble { transform: translateY(0); }
/* A tip that opens from its trigger's end edge, for a trigger near the right. */
.kvyk-tooltip--end .kvyk-tooltip__bubble { left: auto; right: 0; transform: translateY(4px); }
.kvyk-tooltip--end:hover .kvyk-tooltip__bubble,
.kvyk-tooltip--end:focus-within .kvyk-tooltip__bubble { transform: translateY(0); }

/* A tip that opens below its trigger, for a trigger along the top of a
   scrolling box, a table's header, where a tip above would be cut off. */
.kvyk-tooltip--below .kvyk-tooltip__bubble { top: calc(100% + 8px); bottom: auto; }

/* ---- Keyboard key -------------------------------------------------------- */
.kvyk-kbd {
  display: inline-block;
  padding: 2px 6px;
  font-family: var(--kvyk-font-mono);
  font-size: 12px;
  line-height: 16px;
  color: var(--kvyk-on-surface-variant);
  background: var(--kvyk-surface-container);
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-xs);
}


/* A panel opened by a button beside it, over the page: a list's filter, sort
   or columns. It opens below the button, from its start (or, with --end, from
   its far edge), and never runs wider than the screen. */
.kvyk-popover-anchor {
  position: relative;
  display: inline-flex;
}
.kvyk-popover {
  position: absolute;
  top: calc(100% + var(--kvyk-space-xs));
  left: 0;
  z-index: var(--kvyk-z-overlay);
  width: max-content;
  min-width: 16rem;
  max-width: min(40rem, calc(100vw - 2 * var(--kvyk-space-md)));
  max-height: min(32rem, 70vh);
  overflow: auto;
  padding: var(--kvyk-space-md);
  background: var(--kvyk-surface-container-lowest);
  border: 1px solid var(--kvyk-outline-variant);
  border-radius: var(--kvyk-radius-sm);
  box-shadow: var(--kvyk-elevation-2);
}
.kvyk-popover--end {
  left: auto;
  right: 0;
}
/* On a phone it rises from the bottom of the screen instead, full width. */
@media (max-width: 767px) {
  .kvyk-popover {
    position: fixed;
    top: auto;
    left: var(--kvyk-space-md);
    right: var(--kvyk-space-md);
    bottom: var(--kvyk-space-md);
    width: auto;
    min-width: 0;
    max-width: none;
  }
}

/* ==========================================================================
   7. UTILITIES
   --------------------------------------------------------------------------
   A deliberately small set. Reach for tokens + components first; these cover
   the recurring one-offs without becoming a utility framework.
   ========================================================================== */
.kvyk-text-muted { color: var(--kvyk-on-surface-variant); }
.kvyk-text-accent { color: var(--kvyk-secondary); }
.kvyk-text-success { color: var(--kvyk-on-tertiary-container); }
.kvyk-text-danger { color: var(--kvyk-error); }
.kvyk-text-balance { text-wrap: balance; }
.kvyk-text-center { text-align: center; }

.kvyk-flex-1 { flex: 1; }
.kvyk-grow { flex-grow: 1; }
.kvyk-items-center { align-items: center; }
.kvyk-items-start { align-items: flex-start; }
.kvyk-items-end { align-items: flex-end; }
.kvyk-nowrap { white-space: nowrap; }
.kvyk-measure { max-width: var(--kvyk-measure); }
.kvyk-list-reset { margin: 0; padding: 0; list-style: none; }
.kvyk-justify-between { justify-content: space-between; }

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

.kvyk-elevation-1 { box-shadow: var(--kvyk-elevation-1); }
.kvyk-elevation-2 { box-shadow: var(--kvyk-elevation-2); }
.kvyk-elevation-3 { box-shadow: var(--kvyk-elevation-3); }
