/* ===================================================================
   KLOVO ADDITIONS  ·  2026-09-07
   Answers the five asks in "Klovo Design System — what still needs
   designing". Load AFTER tokens.css and console-ledger.css:

     <link rel="stylesheet" href="/brand/tokens.css">
     <link rel="stylesheet" href="/brand/console-ledger.css">
     <link rel="stylesheet" href="/brand/additions.css">

   Mode is a second body attribute, independent of theme:
     data-klovo-mode="dark"   explicit dark
     data-klovo-mode="light"  explicit light
     (no attribute)           follows prefers-color-scheme

   CONTENTS
     1  Gradient map            console only
     2  Dark mode               both themes, as --k-d-* tokens then applied
     3  Data visualisation      console only in colour; monochrome under brand
     4  Date and time
     5  Sort and filter
     6  Lower priority          avatar group, command palette, validation
   =================================================================== */


/* === 1. GRADIENT MAP ===============================================
   Every gradient is 135°, two stops, one hue, tint → slightly deeper
   tint. That is the pattern the estate already uses 84 times; we name
   it rather than replace it. Each has a flat --k-grad-*-flat twin that
   prefers-contrast: more swaps in.

   Ruling on brand: no gradients. The six on klovo.com are hero scrims,
   which are not decoration; they get one token, --k-scrim-hero, and
   nothing else. */

[data-klovo-theme="console"] {
  /* Active nav item, selected row. Replaces #f3e0e2 → #f7e8e6. Ink on
     the darker stop #F3E0E2: 13.9:1. */
  --k-grad-selected:      linear-gradient(135deg, #F3E0E2 0%, #F7E8E6 100%);
  --k-grad-selected-flat: #F5E4E4;
  /* Filled selected state on a dark ground. Replaces #9a3f49 → #7c2f39.
     White on the lighter stop #9A3F49: 6.7:1. */
  --k-grad-accent:        linear-gradient(135deg, #9A3F49 0%, #7C2F39 100%);
  --k-grad-accent-flat:   #8C3F48;
  --k-on-grad-accent:     #FFFFFF;
  /* Soft panel wash for hero and mission blocks. */
  --k-grad-surface:       linear-gradient(135deg, #FFFFFF 0%, #F5F4F0 100%);
  --k-grad-surface-flat:  #F9F8F5;
  /* Completed task. Tint of `great`. Great ink #0E4229 on #D3EDDF: 9.1:1. */
  --k-grad-done:          linear-gradient(135deg, #D3EDDF 0%, #E6F5EC 100%);
  --k-grad-done-flat:     #DCF1E5;
}
/* Ledger's accent is ink, so its selected wash is neutral, not wine. */
[data-klovo-theme="console"][data-k-var="ledger"] {
  --k-grad-selected:      linear-gradient(135deg, #ECEAE4 0%, #F5F4F0 100%);
  --k-grad-selected-flat: #F0EEE9;
  --k-grad-accent:        linear-gradient(135deg, #2E2B27 0%, #1B1A17 100%);
  --k-grad-accent-flat:   #1B1A17;
}
[data-klovo-theme="brand"], :root {
  /* Hero image scrim only. Not a decoration token. */
  --k-scrim-hero: linear-gradient(180deg, rgba(31,27,20,0) 35%, rgba(31,27,20,.58) 100%);
}
@media (prefers-contrast: more) {
  [data-klovo-theme="console"] {
    --k-grad-selected: var(--k-grad-selected-flat);
    --k-grad-accent:   var(--k-grad-accent-flat);
    --k-grad-surface:  var(--k-grad-surface-flat);
    --k-grad-done:     var(--k-grad-done-flat);
  }
}

/* Where they land. */
.k-nav a.is-selected, .k-nav a[aria-current].is-washed,
.k-table tr.is-selected td, .k-card.is-selected { background: var(--k-grad-selected); }
.k-segmented__item[aria-selected="true"].k-segmented__item--filled { background: var(--k-grad-accent); color: var(--k-on-grad-accent); box-shadow: none; }
.k-hero, .k-card--wash { background: var(--k-grad-surface); }
.k-card--task.is-done { background: var(--k-grad-done); }


/* === 2. DARK MODE ==================================================
   Palettes are declared once as --k-d-* on each theme, so every colour
   is a token that exists in every state. The mode blocks at the end
   only re-point the live tokens at them.

   Ruling on the accent: Klovo Amber #D4923B on #1C1913 is 6.1:1 as a
   fill and reads brown. Lifted to #E8AE5A it is 8.6:1 as a fill and
   keeps the hue; ink #1C1913 stays the text on it (8.6:1). Hover goes
   LIGHTER on dark (#F0C685, the existing glow), not deeper.

   Ruling on inversion: brand dark is NOT inverted cream. Ground is a
   warm near-black from the ink family; type is Cream #F4ECDB so the
   pair still reads as Klovo. 70/20/10 becomes 70 dark / 20 cream / 10
   amber, in that order. */

[data-klovo-theme="brand"], :root {
  --k-d-bg:        #1C1913;
  --k-d-surface:   #24201A;
  --k-d-surface-2: #2E2921;
  --k-d-ink:       #F4ECDB;   /* Cream as type. 14.6:1 on bg */
  --k-d-ink-soft:  #E3DAC5;   /* 12.4:1 */
  --k-d-dim:       #ADA38E;   /*  6.8:1 */
  --k-d-faint:     #7A7262;   /*  3.5:1, decorative and disabled only */
  --k-d-line:      #433D32;
  --k-d-line-soft: #332E25;
  --k-d-accent:      #E8AE5A;
  --k-d-accent-deep: #F0C685;
  --k-d-accent-glow: #7A5622;
  --k-d-on-accent:   #1C1913;
  --k-d-scrim:  rgba(0, 0, 0, .55);
  --k-d-scrim-hero: linear-gradient(180deg, rgba(28,25,19,0) 35%, rgba(28,25,19,.72) 100%);
}

[data-klovo-theme="console"] {
  --k-d-bg:        #1A1917;
  --k-d-surface:   #211F1C;
  --k-d-surface-2: #2A2825;
  --k-d-ink:       #F1EEE6;   /* 15.3:1 on bg */
  --k-d-ink-soft:  #D6D1C6;   /* 11.6:1 */
  --k-d-dim:       #A29B8E;   /*  6.4:1 */
  --k-d-faint:     #6F6960;   /*  3.3:1, decorative only */
  --k-d-line:      #3A3733;
  --k-d-line-soft: #2E2B27;
  --k-d-accent:      #D98891;  /* wine, lifted. Ink text on it 8.9:1 */
  --k-d-accent-deep: #E6A5AC;
  --k-d-accent-glow: #5A2E34;
  --k-d-on-accent:   #1A1917;
  --k-d-scrim:  rgba(0, 0, 0, .6);

  /* Semantic tones inverted: ground goes deep, ink goes pastel. Every
     pair clears 7:1 so a tinted row at 13px still reads. */
  --k-d-great-bg: #17362A; --k-d-great-ink: #A3E3BF; --k-d-great-line: #245A42;
  --k-d-good-bg:  #182C43; --k-d-good-ink:  #ABCDF1; --k-d-good-line:  #274A6E;
  --k-d-warn-bg:  #3B2F0F; --k-d-warn-ink:  #F3D88C; --k-d-warn-line:  #66531D;
  --k-d-bad-bg:   #421E1E; --k-d-bad-ink:   #F5B3B3; --k-d-bad-line:   #6E3333;
  --k-d-info-bg:  #2B2346; --k-d-info-ink:  #D1C3F3; --k-d-info-line:  #4B3D78;
  --k-d-note-bg:  #3D2718; --k-d-note-ink:  #F2C6A6; --k-d-note-line:  #69432A;
  --k-d-neutral-bg: #2A2825; --k-d-neutral-ink: #D2CCC1; --k-d-neutral-line: #45413B;

  /* Categorical hues, lifted for dark. */
  --k-d-cyan: #7FB8C9; --k-d-cyan-l: #4F8595; --k-d-alert: #F09A92;
  --k-d-good: #9BC9A6; --k-d-purple: #C4A2C6; --k-d-blue: #97BBD9;

  /* Gradients, dark. Same 135° tint→deeper rule. */
  --k-d-grad-selected: linear-gradient(135deg, #3A2A2D 0%, #2E2427 100%);
  --k-d-grad-accent:   linear-gradient(135deg, #B8626C 0%, #9A4A54 100%);
  --k-d-grad-surface:  linear-gradient(135deg, #24221F 0%, #1A1917 100%);
  --k-d-grad-done:     linear-gradient(135deg, #17362A 0%, #1F2E27 100%);
}
[data-klovo-theme="console"][data-k-var="ledger"] {
  --k-d-accent: #F1EEE6; --k-d-accent-deep: #D6D1C6; --k-d-accent-glow: #3A3733; --k-d-on-accent: #1A1917;
  --k-d-grad-selected: linear-gradient(135deg, #2E2B27 0%, #242220 100%);
  --k-d-grad-accent:   linear-gradient(135deg, #F1EEE6 0%, #D6D1C6 100%);
}

/* Apply. Written once as a mixin-by-repetition: the attribute block and
   the media block are identical on purpose. */
[data-klovo-theme][data-klovo-mode="dark"] {
  color-scheme: dark;
  --k-bg: var(--k-d-bg); --k-surface: var(--k-d-surface); --k-surface-2: var(--k-d-surface-2);
  --k-ink: var(--k-d-ink); --k-ink-soft: var(--k-d-ink-soft); --k-dim: var(--k-d-dim); --k-faint: var(--k-d-faint);
  --k-line: var(--k-d-line); --k-line-soft: var(--k-d-line-soft);
  --k-accent: var(--k-d-accent); --k-accent-deep: var(--k-d-accent-deep); --k-accent-glow: var(--k-d-accent-glow); --k-on-accent: var(--k-d-on-accent);
  --k-scrim: var(--k-d-scrim); --k-scrim-hero: var(--k-d-scrim-hero);
  --k-amber: #E8AE5A; --k-amber-deep: #F0C685;
}
[data-klovo-theme="console"][data-klovo-mode="dark"] {
  --k-great-bg: var(--k-d-great-bg); --k-great-ink: var(--k-d-great-ink); --k-great-line: var(--k-d-great-line);
  --k-good-bg: var(--k-d-good-bg);   --k-good-ink: var(--k-d-good-ink);   --k-good-line: var(--k-d-good-line);
  --k-warn-bg: var(--k-d-warn-bg);   --k-warn-ink: var(--k-d-warn-ink);   --k-warn-line: var(--k-d-warn-line);
  --k-bad-bg: var(--k-d-bad-bg);     --k-bad-ink: var(--k-d-bad-ink);     --k-bad-line: var(--k-d-bad-line);
  --k-info-bg: var(--k-d-info-bg);   --k-info-ink: var(--k-d-info-ink);   --k-info-line: var(--k-d-info-line);
  --k-note-bg: var(--k-d-note-bg);   --k-note-ink: var(--k-d-note-ink);   --k-note-line: var(--k-d-note-line);
  --k-neutral-bg: var(--k-d-neutral-bg); --k-neutral-ink: var(--k-d-neutral-ink); --k-neutral-line: var(--k-d-neutral-line);
  --k-cyan: var(--k-d-cyan); --k-cyan-l: var(--k-d-cyan-l); --k-alert: var(--k-d-alert); --k-good: var(--k-d-good); --k-purple: var(--k-d-purple); --k-blue: var(--k-d-blue);
  --k-grad-selected: var(--k-d-grad-selected); --k-grad-accent: var(--k-d-grad-accent); --k-grad-surface: var(--k-d-grad-surface); --k-grad-done: var(--k-d-grad-done);
  --k-grad-selected-flat: #2E2427; --k-grad-accent-flat: #9A4A54; --k-grad-surface-flat: #1F1D1B; --k-grad-done-flat: #1B3227;
}
@media (prefers-color-scheme: dark) {
  [data-klovo-theme]:not([data-klovo-mode="light"]) {
    color-scheme: dark;
    --k-bg: var(--k-d-bg); --k-surface: var(--k-d-surface); --k-surface-2: var(--k-d-surface-2);
    --k-ink: var(--k-d-ink); --k-ink-soft: var(--k-d-ink-soft); --k-dim: var(--k-d-dim); --k-faint: var(--k-d-faint);
    --k-line: var(--k-d-line); --k-line-soft: var(--k-d-line-soft);
    --k-accent: var(--k-d-accent); --k-accent-deep: var(--k-d-accent-deep); --k-accent-glow: var(--k-d-accent-glow); --k-on-accent: var(--k-d-on-accent);
    --k-scrim: var(--k-d-scrim); --k-scrim-hero: var(--k-d-scrim-hero);
    --k-amber: #E8AE5A; --k-amber-deep: #F0C685;
  }
  [data-klovo-theme="console"]:not([data-klovo-mode="light"]) {
    --k-great-bg: var(--k-d-great-bg); --k-great-ink: var(--k-d-great-ink); --k-great-line: var(--k-d-great-line);
    --k-good-bg: var(--k-d-good-bg);   --k-good-ink: var(--k-d-good-ink);   --k-good-line: var(--k-d-good-line);
    --k-warn-bg: var(--k-d-warn-bg);   --k-warn-ink: var(--k-d-warn-ink);   --k-warn-line: var(--k-d-warn-line);
    --k-bad-bg: var(--k-d-bad-bg);     --k-bad-ink: var(--k-d-bad-ink);     --k-bad-line: var(--k-d-bad-line);
    --k-info-bg: var(--k-d-info-bg);   --k-info-ink: var(--k-d-info-ink);   --k-info-line: var(--k-d-info-line);
    --k-note-bg: var(--k-d-note-bg);   --k-note-ink: var(--k-d-note-ink);   --k-note-line: var(--k-d-note-line);
    --k-neutral-bg: var(--k-d-neutral-bg); --k-neutral-ink: var(--k-d-neutral-ink); --k-neutral-line: var(--k-d-neutral-line);
    --k-cyan: var(--k-d-cyan); --k-cyan-l: var(--k-d-cyan-l); --k-alert: var(--k-d-alert); --k-good: var(--k-d-good); --k-purple: var(--k-d-purple); --k-blue: var(--k-d-blue);
    --k-grad-selected: var(--k-d-grad-selected); --k-grad-accent: var(--k-d-grad-accent); --k-grad-surface: var(--k-d-grad-surface); --k-grad-done: var(--k-d-grad-done);
  }
}
/* On dark the ink-filled button and toast would vanish into the ground;
   they invert with the palette because they use --k-ink / --k-bg, which
   is correct. Two things do not follow automatically: */
[data-klovo-mode="dark"] .k-check[aria-checked="true"]::before { color: var(--k-on-accent); }
[data-klovo-mode="dark"] .k-skeleton { background: var(--k-surface-2); }


/* === 3. DATA VISUALISATION =========================================
   Chart text is always a theme token. Every shape has an explicit fill.
   Under brand the semantic tokens resolve to ink, so a chart is
   monochrome there without any extra rule. */

/* Axis and gridline weights. Two tokens, both themes, both modes. */
:root, [data-klovo-theme] {
  --k-axis: var(--k-line);          /* the baseline / zero line, 1px */
  --k-gridline: var(--k-line-soft); /* every other line, 1px */
  --k-chart-ink: var(--k-ink);      /* the primary series */
  --k-chart-ink-2: var(--k-dim);    /* a secondary series */
}
[data-k-var="ledger"] { --k-axis: var(--k-ink); }

/* Sparkline. 80×24 SVG, no axes, one emphasised endpoint. The polyline
   points come from data; stroke and fills come from here. */
.k-spark { display: inline-block; width: 80px; height: 24px; vertical-align: middle; overflow: visible; color: var(--k-chart-ink); }
.k-spark__line { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; }
.k-spark__area { fill: var(--k-surface-2); stroke: none; }
.k-spark__end { fill: currentColor; stroke: var(--k-surface); stroke-width: 1.5; }
.k-spark--great { color: var(--k-great-ink); } .k-spark--bad { color: var(--k-bad-ink); } .k-spark--warn { color: var(--k-warn-ink); }

/* Bar chart, vertical. Grid with one column per bar. The drawing area
   reserves --k-chart-label (one label height) at the top so a value
   label on a full-height bar still lands inside the bounds. */
.k-chart {
  --k-chart-h: 140px;
  --k-chart-label: 18px;
  --k-chart-rows: 4;                 /* gridlines; set to match the tick count */
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: var(--k-sp-2);
  align-items: end;
  height: calc(var(--k-chart-h) + var(--k-chart-label));
  padding-top: var(--k-chart-label);
  border-bottom: 1px solid var(--k-axis);
  background:
    repeating-linear-gradient(to top,
      var(--k-gridline) 0, var(--k-gridline) 1px,
      transparent 1px, transparent calc(var(--k-chart-h) / var(--k-chart-rows)))
    bottom / 100% var(--k-chart-h) no-repeat;
}
.k-chart__bar {
  position: relative;
  height: var(--k-val, 0%);          /* set --k-val: 72% inline from data */
  min-height: 1px;
  background: var(--k-chart-ink);
  border-radius: var(--k-radius-sharp) var(--k-radius-sharp) 0 0;
  transition: height var(--k-dur-slow) var(--k-ease);
}
.k-chart__bar--2 { background: var(--k-chart-ink-2); }
.k-chart__bar--great { background: var(--k-great-ink); } .k-chart__bar--good { background: var(--k-good-ink); }
.k-chart__bar--warn { background: var(--k-warn-ink); } .k-chart__bar--bad { background: var(--k-bad-ink); }
.k-chart__bar--info { background: var(--k-info-ink); } .k-chart__bar--note { background: var(--k-note-ink); }
.k-chart__val {
  position: absolute; left: 50%; bottom: 100%;
  transform: translate(-50%, -3px);
  font-family: var(--k-mono, inherit); font-size: var(--k-fs-eyebrow); line-height: 1;
  color: var(--k-ink); white-space: nowrap; font-variant-numeric: tabular-nums;
}
/* Category labels sit in a sibling grid with the same column count. */
.k-chart-x { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: var(--k-sp-2); padding-top: 6px; }
.k-chart-x span { font-size: var(--k-fs-eyebrow); letter-spacing: var(--k-ls-label); text-transform: uppercase; color: var(--k-dim); text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Y ticks: one per gridline, top to bottom, placed beside the chart. */
.k-chart-y { display: flex; flex-direction: column; justify-content: space-between; height: var(--k-chart-h, 140px); margin-top: var(--k-chart-label, 18px); padding-right: var(--k-sp-2); text-align: right; }
.k-chart-y span { font-family: var(--k-mono, inherit); font-size: var(--k-fs-eyebrow); line-height: 1; color: var(--k-dim); font-variant-numeric: tabular-nums; transform: translateY(50%); }
.k-chart-y span:first-child { transform: translateY(-50%); }
.k-chart-wrap { display: grid; grid-template-columns: auto minmax(0, 1fr); }

/* Bar chart, horizontal. One row per item: label, track, value. The
   value lives outside the track so it never collides with a short bar. */
.k-hbar { display: grid; grid-template-columns: minmax(80px, auto) minmax(0, 1fr) auto; gap: var(--k-sp-2) var(--k-sp-3); align-items: center; font-size: var(--k-fs-xs); }
.k-hbar__label { color: var(--k-ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.k-hbar__track { height: 10px; background: var(--k-surface-2); border-radius: var(--k-radius-sharp); overflow: hidden;
  background-image: repeating-linear-gradient(to right, var(--k-gridline) 0, var(--k-gridline) 1px, transparent 1px, transparent 25%); }
.k-hbar__fill { height: 100%; width: var(--k-val, 0%); background: var(--k-chart-ink); transition: width var(--k-dur-slow) var(--k-ease); }
.k-hbar__val { font-family: var(--k-mono, inherit); font-variant-numeric: tabular-nums; color: var(--k-ink); text-align: right; min-width: 4ch; }

/* Donut / progress ring. --k-val is 0–100. Track and fill are both
   explicit; the hole is a mask, not a second circle. */
.k-ring {
  --k-val: 0;
  --k-ring-size: 96px;
  --k-ring-w: 10px;
  --k-ring-fill: var(--k-chart-ink);
  width: var(--k-ring-size); height: var(--k-ring-size);
  position: relative; display: inline-grid; place-items: center; flex: 0 0 auto;
}
.k-ring::before {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: conic-gradient(var(--k-ring-fill) calc(var(--k-val) * 1%), var(--k-surface-2) 0);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - var(--k-ring-w)), #000 calc(100% - var(--k-ring-w) + 1px));
          mask: radial-gradient(farthest-side, transparent calc(100% - var(--k-ring-w)), #000 calc(100% - var(--k-ring-w) + 1px));
}
.k-ring__val { position: relative; font-family: var(--k-display); font-weight: var(--k-fw-bold); font-size: calc(var(--k-ring-size) * .24); line-height: 1; color: var(--k-ink); font-variant-numeric: tabular-nums; }
.k-ring__val small { display: block; font-family: var(--k-sans); font-weight: var(--k-fw-med); font-size: var(--k-fs-eyebrow); letter-spacing: var(--k-ls-label); text-transform: uppercase; color: var(--k-dim); margin-top: 4px; }
.k-ring--sm { --k-ring-size: 48px; --k-ring-w: 6px; } .k-ring--sm .k-ring__val { font-size: 12px; }
.k-ring--great { --k-ring-fill: var(--k-great-ink); } .k-ring--warn { --k-ring-fill: var(--k-warn-ink); } .k-ring--bad { --k-ring-fill: var(--k-bad-ink); } .k-ring--good { --k-ring-fill: var(--k-good-ink); }

/* Trend indicator. Direction is a MARK (arrow), tone is a colour. They
   are set separately because up is not always good: --up.--bad is a
   rising defect rate. */
.k-trend { display: inline-flex; align-items: center; gap: 3px; font-family: var(--k-mono, inherit); font-size: var(--k-fs-xs); font-weight: var(--k-fw-med); font-variant-numeric: tabular-nums; color: var(--k-ink-soft); white-space: nowrap; }
.k-trend::before { content: "\2192"; font-family: var(--k-sans); }   /* → flat */
.k-trend--up::before   { content: "\2191"; }                          /* ↑ */
.k-trend--down::before { content: "\2193"; }                          /* ↓ */
.k-trend--great { color: var(--k-great-ink); } .k-trend--good { color: var(--k-good-ink); }
.k-trend--warn  { color: var(--k-warn-ink); }  .k-trend--bad  { color: var(--k-bad-ink); }
.k-trend--flat  { color: var(--k-dim); }
/* Tinted pill form for a stat block. */
.k-trend--pill { padding: 1px 6px; border-radius: var(--k-radius); background: var(--k-surface-2); }
.k-trend--pill.k-trend--great { background: var(--k-great-bg); } .k-trend--pill.k-trend--good { background: var(--k-good-bg); }
.k-trend--pill.k-trend--warn { background: var(--k-warn-bg); }   .k-trend--pill.k-trend--bad { background: var(--k-bad-bg); }

/* Legend. Swatch is a square under ledger, a dot elsewhere. */
.k-legend { display: flex; flex-wrap: wrap; gap: var(--k-sp-2) var(--k-sp-4); font-size: var(--k-fs-xs); color: var(--k-ink-soft); }
.k-legend__item { display: inline-flex; align-items: center; gap: 6px; }
.k-legend__swatch { width: 10px; height: 10px; border-radius: 50%; background: var(--k-chart-ink); flex: 0 0 auto; }
[data-k-var="ledger"] .k-legend__swatch { border-radius: 1px; }
.k-legend__swatch--2 { background: var(--k-chart-ink-2); }
.k-legend__swatch--great { background: var(--k-great-ink); } .k-legend__swatch--good { background: var(--k-good-ink); }
.k-legend__swatch--warn { background: var(--k-warn-ink); } .k-legend__swatch--bad { background: var(--k-bad-ink); }
.k-legend__swatch--info { background: var(--k-info-ink); } .k-legend__swatch--note { background: var(--k-note-ink); }
.k-legend__val { font-family: var(--k-mono, inherit); color: var(--k-dim); font-variant-numeric: tabular-nums; }


/* === 4. DATE AND TIME ==============================================
   Urgency ladder, mapped onto the seven tones. No new colour.

     overdue     bad      mark "!"
     due today   warn     mark "●"
     due soon    note     mark "◔"   (within 3 days)
     scheduled   neutral  mark "○"
     done        great    mark "✓"

   Colour reinforces; the mark and the word carry the meaning. */

/* Relative timestamp. Quiet by default; the machine date goes in
   <time datetime> and the full date in title. */
.k-time { font-size: var(--k-fs-xs); color: var(--k-dim); font-variant-numeric: tabular-nums; white-space: nowrap; }
.k-time--mono { font-family: var(--k-mono, inherit); }
.k-time--loud { color: var(--k-ink-soft); }

.k-due {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--k-mono, inherit); font-size: var(--k-fs-xs); font-weight: var(--k-fw-med);
  padding: 1px 7px 1px 6px; border-radius: var(--k-radius);
  background: var(--k-neutral-bg, var(--k-surface-2)); color: var(--k-neutral-ink, var(--k-dim));
  border: 1px solid transparent; white-space: nowrap; font-variant-numeric: tabular-nums;
}
.k-due::before { content: "\25CB"; font-family: var(--k-sans); font-size: 10px; line-height: 1; }          /* ○ scheduled */
.k-due--soon    { background: var(--k-note-bg); color: var(--k-note-ink); }
.k-due--soon::before    { content: "\25D4"; }                                                               /* ◔ */
.k-due--today   { background: var(--k-warn-bg); color: var(--k-warn-ink); }
.k-due--today::before   { content: "\25CF"; }                                                               /* ● */
.k-due--overdue { background: var(--k-bad-bg);  color: var(--k-bad-ink); border-color: var(--k-bad-line); font-weight: var(--k-fw-semi); }
.k-due--overdue::before { content: "!"; font-weight: var(--k-fw-bold); font-size: 12px; }
.k-due--done    { background: var(--k-great-bg); color: var(--k-great-ink); text-decoration: line-through; text-decoration-color: currentColor; }
.k-due--done::before    { content: "\2713"; text-decoration: none; }
/* Text-only form, for inside a sentence or a dense cell. */
.k-due--bare { background: none; padding: 0; border: 0; }

/* Date range. Two <time>s and an arrow. Wraps as a unit. */
.k-range { display: inline-flex; align-items: center; gap: 6px; font-size: var(--k-fs-xs); color: var(--k-ink-soft); font-variant-numeric: tabular-nums; white-space: nowrap; }
.k-range__sep { color: var(--k-faint); }
.k-range__sep::before { content: "\2192"; }
.k-range__len { color: var(--k-dim); }
.k-range__len::before { content: "\00b7\00a0"; }

/* Date picker: native. Agreed. It is free, accessible, localised, and
   on a phone it is the only one that works. We style the box, not the
   popup. color-scheme lets the popup follow dark mode. */
.k-input[type="date"], .k-input[type="datetime-local"], .k-input[type="time"] {
  font-family: var(--k-mono, inherit); font-variant-numeric: tabular-nums; cursor: pointer;
  color-scheme: light; width: auto; min-width: 11ch;
}
[data-klovo-mode="dark"] .k-input[type="date"], [data-klovo-mode="dark"] .k-input[type="datetime-local"], [data-klovo-mode="dark"] .k-input[type="time"] { color-scheme: dark; }
.k-input[type="date"]::-webkit-calendar-picker-indicator { opacity: .55; cursor: pointer; }
.k-input[type="date"]:hover::-webkit-calendar-picker-indicator { opacity: 1; }
/* Two dates side by side with the arrow between. */
.k-daterange { display: inline-flex; align-items: center; gap: var(--k-sp-2); }
.k-daterange__sep { color: var(--k-faint); } .k-daterange__sep::before { content: "\2192"; }


/* === 5. SORT AND FILTER ============================================ */

/* Sortable header. Drive it with aria-sort; the indicator is a glyph in
   the same 11px, so the baseline does not move. Resting shows a faint
   ↕ only on hover, so a wide header is not a picket fence of arrows. */
.k-table th[aria-sort] { cursor: pointer; user-select: none; }
.k-table th[aria-sort] > .k-sort { display: inline-flex; align-items: center; gap: 4px; color: inherit; background: none; border: 0; padding: 0; font: inherit; letter-spacing: inherit; text-transform: inherit; cursor: pointer; }
.k-table th[aria-sort]::after { content: "\2195"; display: inline-block; margin-left: 4px; color: var(--k-faint); opacity: 0; font-size: inherit; line-height: 1; transition: opacity var(--k-dur) var(--k-ease); }
.k-table th[aria-sort]:hover::after { opacity: 1; }
.k-table th[aria-sort="ascending"]::after  { content: "\2191"; color: var(--k-ink); opacity: 1; }
.k-table th[aria-sort="descending"]::after { content: "\2193"; color: var(--k-ink); opacity: 1; }
.k-table th[aria-sort="ascending"], .k-table th[aria-sort="descending"] { color: var(--k-ink); }
[data-k-var="ledger"] .k-table th[aria-sort="ascending"], [data-k-var="ledger"] .k-table th[aria-sort="descending"] { border-bottom-width: 2px; padding-bottom: 5px; }
.k-table th.k-num[aria-sort]::after { margin-left: 0; margin-right: -14px; }  /* keeps numerals right-aligned to the cell */

/* Filter bar. Chips on the left, result count and clear on the right.
   Toggle .has-filters on the bar when any chip is on. */
.k-filterbar { display: flex; flex-wrap: wrap; gap: var(--k-sp-2); align-items: center; padding-block: var(--k-sp-2); }
.k-filterbar__count { font-family: var(--k-mono, inherit); font-size: var(--k-fs-xs); color: var(--k-dim); font-variant-numeric: tabular-nums; margin-left: auto; white-space: nowrap; }
.k-filterbar__count strong { color: var(--k-ink); font-weight: var(--k-fw-med); }
.k-filterbar__clear { display: none; }
.k-filterbar.has-filters .k-filterbar__clear { display: inline-flex; }
.k-filterbar.has-filters .k-filterbar__count::before { content: "\00b7\00a0"; color: var(--k-faint); }
/* An active chip shows its remove affordance. */
.k-chip.is-on .k-chip__x, .k-chip[aria-pressed="true"] .k-chip__x { display: inline-block; }
.k-chip__x { display: none; margin-left: 2px; opacity: .7; font-size: 12px; line-height: 1; }
.k-chip:hover .k-chip__x { opacity: 1; }
/* Filter group label: "Status:" before its chips. */
.k-filterbar__group { display: inline-flex; align-items: center; gap: var(--k-sp-1); }
.k-filterbar__group > .k-label { margin-right: var(--k-sp-1); }

/* Column controls. A popover list; each row is drag handle, check,
   name. Reorder with .is-dragging / .k-drop--* from the base. */
.k-colctl { min-width: 220px; padding: var(--k-sp-2); background: var(--k-surface); border: 1px solid var(--k-line); border-radius: var(--k-radius); display: flex; flex-direction: column; gap: 2px; }
.k-colctl__head { display: flex; align-items: center; justify-content: space-between; padding: var(--k-sp-1) var(--k-sp-2) var(--k-sp-2); border-bottom: 1px solid var(--k-line-soft); margin-bottom: var(--k-sp-1); }
.k-colctl__row { display: flex; align-items: center; gap: var(--k-sp-2); padding: 5px var(--k-sp-2); border-radius: var(--k-radius); font-size: var(--k-fs-xs); color: var(--k-ink-soft); }
.k-colctl__row:hover { background: var(--k-surface-2); }
.k-colctl__row.is-hidden { color: var(--k-faint); }
.k-handle { color: var(--k-faint); cursor: grab; font-size: 12px; letter-spacing: -2px; user-select: none; flex: 0 0 auto; width: 12px; }
.k-handle::before { content: "\22EE\22EE"; }
.k-colctl__row:hover .k-handle { color: var(--k-dim); }
.k-handle:active { cursor: grabbing; }

/* Result count and clear-all, standalone (under a heading or above a table). */
.k-results { display: flex; align-items: baseline; gap: var(--k-sp-3); font-size: var(--k-fs-xs); color: var(--k-dim); }
.k-results__n { font-family: var(--k-mono, inherit); color: var(--k-ink); font-weight: var(--k-fw-med); font-variant-numeric: tabular-nums; }
.k-results .k-btn--bare { padding: 0; min-height: 0; font-size: inherit; }


/* === 6. LOWER PRIORITY ============================================= */

/* Avatar group. Overlapping --sm --round marks; the last one is "+N".
   Hovering the group fans it out so every face is reachable. */
.k-avatars { display: inline-flex; align-items: center; }
.k-avatars .k-mark { width: 26px; height: 26px; font-size: var(--k-fs-eyebrow); border-radius: 50%; margin-left: -8px; box-shadow: 0 0 0 2px var(--k-surface); transition: margin var(--k-dur) var(--k-ease); }
.k-avatars .k-mark:first-child { margin-left: 0; }
.k-avatars:hover .k-mark { margin-left: 2px; }
.k-avatars__more { background: var(--k-surface-2); color: var(--k-dim); font-family: var(--k-mono, inherit); font-weight: var(--k-fw-med); }
/* Ownership tone on a mark: the semantic inks, not the fills, so the
   initial stays legible on a small circle. */
.k-mark--great { background: var(--k-great-ink); color: var(--k-great-bg); } .k-mark--good { background: var(--k-good-ink); color: var(--k-good-bg); }
.k-mark--info { background: var(--k-info-ink); color: var(--k-info-bg); }    .k-mark--note { background: var(--k-note-ink); color: var(--k-note-bg); }
.k-mark--warn { background: var(--k-warn-ink); color: var(--k-warn-bg); }    .k-mark--neutral { background: var(--k-neutral-ink); color: var(--k-neutral-bg); }

/* Command palette. A modal with the input as its head. Results are
   grouped; the active row is the selected wash; every row ends in a
   right-aligned hint or shortcut. */
.k-cmd { width: min(640px, calc(100vw - var(--k-sp-6))); padding: 0; overflow: hidden; background: var(--k-surface); border: 1px solid var(--k-line); border-radius: var(--k-radius-lg); }
.k-cmd__input { display: flex; align-items: center; gap: var(--k-sp-3); padding: var(--k-sp-3) var(--k-sp-4); border-bottom: 1px solid var(--k-line); }
.k-cmd__input .k-input { border: 0; background: none; padding: 0; min-height: 0; font-size: var(--k-fs-body); box-shadow: none; }
.k-cmd__input .k-input:focus-visible { outline: none; box-shadow: none; }
.k-cmd__list { max-height: 50vh; overflow-y: auto; padding: var(--k-sp-2); }
.k-cmd__group { padding: var(--k-sp-2) var(--k-sp-2) var(--k-sp-1); }
.k-cmd__row { display: flex; align-items: center; gap: var(--k-sp-3); padding: var(--k-sp-2) var(--k-sp-3); border-radius: var(--k-radius); font-size: var(--k-fs-sm); color: var(--k-ink-soft); cursor: pointer; }
.k-cmd__row:hover { background: var(--k-surface-2); }
.k-cmd__row[aria-selected="true"] { background: var(--k-grad-selected, var(--k-surface-2)); color: var(--k-ink); }
.k-cmd__hint { margin-left: auto; font-size: var(--k-fs-xs); color: var(--k-dim); white-space: nowrap; }
.k-cmd__foot { display: flex; gap: var(--k-sp-4); padding: var(--k-sp-2) var(--k-sp-4); border-top: 1px solid var(--k-line-soft); font-size: var(--k-fs-eyebrow); color: var(--k-dim); }
.k-kbd { display: inline-block; font-family: var(--k-mono, inherit); font-size: var(--k-fs-eyebrow); line-height: 1; padding: 3px 5px; border: 1px solid var(--k-line); border-bottom-width: 2px; border-radius: var(--k-radius); background: var(--k-surface); color: var(--k-ink-soft); min-width: 18px; text-align: center; }

/* Validation. State on .k-field, so label, control and message move
   together. Message carries a mark; the border carries the tone. */
.k-field__msg { display: flex; align-items: baseline; gap: 5px; font-size: var(--k-fs-xs); color: var(--k-dim); }
.k-field__msg::before { flex: 0 0 auto; font-weight: var(--k-fw-bold); }
.k-field.is-error .k-input, .k-field.is-error .k-textarea, .k-field.is-error .k-select { border-color: var(--k-bad-ink); box-shadow: inset 0 -1px 0 var(--k-bad-ink); }
.k-field.is-error .k-field__msg { color: var(--k-bad-ink); font-weight: var(--k-fw-med); }
.k-field.is-error .k-field__msg::before { content: "\00d7"; }
.k-field.is-warn .k-input, .k-field.is-warn .k-textarea, .k-field.is-warn .k-select { border-color: var(--k-warn-ink); }
.k-field.is-warn .k-field__msg { color: var(--k-warn-ink); }
.k-field.is-warn .k-field__msg::before { content: "!"; }
.k-field.is-ok .k-input, .k-field.is-ok .k-textarea, .k-field.is-ok .k-select { border-color: var(--k-great-ink); }
.k-field.is-ok .k-field__msg { color: var(--k-great-ink); }
.k-field.is-ok .k-field__msg::before { content: "\2713"; }
.k-field.is-error .k-label { color: var(--k-bad-ink); }
/* Field-level focus should win over the state colour so the user sees
   where they are, then the state comes back on blur. */
.k-field.is-error .k-input:focus-visible, .k-field.is-warn .k-input:focus-visible, .k-field.is-ok .k-input:focus-visible { border-color: var(--k-ink); box-shadow: inset 0 -1px 0 var(--k-ink); }
