/* ===================================================================
   KLOVO DESIGN SYSTEM  ·  v2  ·  2026-09-07
   https://www.klovo.com/brand/tokens.css

   One stylesheet, two themes, every shared component. Link it and pick
   a theme; nothing downstream declares a colour, a radius or a type
   step of its own.

   -------------------------------------------------------------------
   QUICK START

     <link rel="stylesheet" href="https://www.klovo.com/brand/tokens.css">
     <body data-klovo-theme="console">   internal tools and boards
     <body data-klovo-theme="brand">     anything a customer sees

   No attribute gives you `brand`.

   -------------------------------------------------------------------
   WHY A STYLESHEET AND NOT A PACKAGE

   Eight of the twelve Klovo-family surfaces are single-file static HTML
   with no build step: dashboard, outcomes, crm, payments, tools,
   sohampa, spkhaitan, spkhaitan-outcomes. A package reaches the three
   that build. A <link> reaches all twelve today, with one line and no
   toolchain. If real components are later wanted for klovo-website and
   klovo-orders, they sit on top of this rather than replacing it.

   -------------------------------------------------------------------
   WHY TWO THEMES

   `brand`    Klovo Brand System v2.2. Cream ground, amber accent, ink
              type, Inter Tight and Space Grotesk. The public face. The
              deck governs it and it is not ours to reinterpret.

   `console`  The system already running, byte-identically, on
              sohampa.com and outcomes.klovo.com. White ground, warm
              grey rules, wine accent, system fonts. Denser and quieter,
              which is right for a board you look at all day and wrong
              for a storefront.

   Structure, spacing, type scale and every component below are shared.
   Only the surface differs. Collapsing the two would make a task board
   look like a marketing page and a storefront look like a spreadsheet.

   -------------------------------------------------------------------
   NAMING, SO THIS STAYS PREDICTABLE AS IT GROWS

     .k-thing            a component
     .k-thing--variant   a variant of it
     .k-thing__part      a part inside it
     .is-state           a state, toggled at runtime (is-open, is-busy)

   Everything is prefixed `k-` so it can be dropped into a page with an
   existing stylesheet without collisions. States are unprefixed on
   purpose: they read naturally in JS as `el.classList.add('is-open')`.

   -------------------------------------------------------------------
   HOW TO EXTEND IT

   1. Add the component in the right section below, alphabetically.
   2. Use tokens for every value. Any token a shared component touches
      must exist in BOTH themes, or it breaks under one of them. A raw
      hex in a component is the bug this file exists to prevent.
      Categorical hues (cyan, alert, good, purple, blue) are the one
      asymmetry: real under console, resolved to ink under brand,
      because the deck forbids new colour on customer-facing surfaces.
   3. Check it under both themes before shipping. Switching the body
      attribute is the whole test.
   4. Never let colour be the only carrier of meaning. Pair it with a
      mark, a word, or a shape.

   -------------------------------------------------------------------
   CONTENTS

     1  Structural tokens
     2  Theme: brand
     3  Theme: console
     4  Base
     5  Layout
     6  Typography
     7  Buttons
     8  Forms
     9  Cards
     10 Badges and status
     11 Tables
     12 Overlays
     13 Navigation
     14 Stats
     15 States
     16 Utilities

   v3 adds: k-quad, k-check, k-card--task, k-mark, k-icon,
   k-drawer__close, k-segmented, is-dragging, k-drop
   =================================================================== */


/* === 1. STRUCTURAL TOKENS ==========================================
   Identical under both themes. Anything here is about rhythm and
   proportion, never about colour. */

:root {
  /* Spacing, 4px grid */
  --k-sp-1: 4px;   --k-sp-2: 8px;   --k-sp-3: 12px;  --k-sp-4: 16px;
  --k-sp-5: 24px;  --k-sp-6: 32px;  --k-sp-7: 48px;  --k-sp-8: 64px;
  --k-sp-9: 88px;

  /* Measure */
  --k-measure: 1240px;        /* brand deck max width */
  --k-measure-text: 68ch;     /* comfortable reading line */
  --k-measure-narrow: 940px;  /* focused pages: cart, checkout, forms */
  --k-section-pad: var(--k-sp-9);

  /* Type scale. Brand deck: 96 / 60 / 32 / 18 / 16 / 11. */
  --k-fs-display: clamp(48px, 8vw, 96px);
  --k-fs-h1:      clamp(36px, 5vw, 60px);
  --k-fs-h2:      32px;
  --k-fs-h3:      24px;
  --k-fs-h4:      18px;
  --k-fs-lede:    18px;
  --k-fs-body:    16px;
  --k-fs-sm:      14px;
  --k-fs-xs:      13px;
  --k-fs-eyebrow: 11px;   /* hard floor. Nothing smaller, ever. */

  --k-lh-tight: 1.05;
  --k-lh-head:  1.2;
  --k-lh-body:  1.6;
  --k-ls-eyebrow: .14em;
  --k-ls-label:   .09em;
  --k-ls-tight:  -.02em;

  --k-fw-body: 400;
  --k-fw-med:  500;
  --k-fw-semi: 600;
  --k-fw-bold: 700;

  /* Radii. Each theme picks its own --k-radius from these. */
  --k-radius-sharp: 2px;
  --k-radius-soft:  9px;
  --k-radius-lg:    18px;
  --k-radius-pill:  999px;

  /* Controls */
  --k-tap: 44px;              /* iOS minimum. Every control clears it. */
  --k-control-pad: 10px 16px;

  /* Motion */
  --k-dur: 160ms;
  --k-dur-slow: 260ms;
  --k-ease: cubic-bezier(.2, 0, .2, 1);

  /* Stacking. Named so nothing invents a z-index of 9999. */
  --k-z-base: 1;
  --k-z-sticky: 20;
  --k-z-overlay: 100;
  --k-z-drawer: 110;
  --k-z-toast: 200;
}

@media (max-width: 767px) {
  :root { --k-section-pad: 56px; }
}
@media (prefers-reduced-motion: reduce) {
  :root { --k-dur: 0ms; --k-dur-slow: 0ms; }
}


/* === 2. THEME: BRAND ===============================================
   klovo.com and anything customer-facing. Brand System v2.2.
   70% cream, 20% ink, 10% amber, never inverted. */

:root,
[data-klovo-theme="brand"] {
  --k-bg:        #F4ECDB;   /* Cream  */
  --k-surface:   #FBF6EA;   /* Paper  */
  --k-surface-2: #E6DCC6;
  --k-ink:       #1F1B14;
  --k-ink-soft:  #3A3328;
  --k-dim:       #6F6757;
  --k-faint:     #A79E88;
  --k-line:      #C9BD9F;
  --k-line-soft: #DDD3B7;

  --k-accent:      #D4923B;  /* Klovo Amber */
  --k-accent-deep: #B07320;  /* Amber Deep, hover only */
  --k-accent-glow: #F0C685;
  --k-on-accent:   #1F1B14;

  --k-display: 'Inter Tight', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --k-sans:    'Space Grotesk', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;

  --k-radius: var(--k-radius-sharp);
  --k-shadow: none;          /* the deck rules out shadows on cards */
  --k-scrim:  rgba(31, 27, 20, .38);

  /* Categorical hues resolve to INK under brand, on purpose. The deck
     rules out introducing any new colour, green for success and red for
     error included: use ink plus a check or a cross instead. Defining
     them rather than omitting them means a shared component can safely
     reference one and simply render monochrome here, instead of hitting
     an undefined variable. Console gives them real values. */
  --k-cyan:   var(--k-ink);
  --k-cyan-l: var(--k-dim);
  --k-alert:  var(--k-ink);
  --k-good:   var(--k-ink);
  --k-purple: var(--k-ink);
  --k-blue:   var(--k-ink);
}


/* === 3. THEME: CONSOLE =============================================
   Internal tools and boards. Lifted from sohampa.com and
   outcomes.klovo.com, which carry it identically today. */

[data-klovo-theme="console"] {
  --k-bg:        #ffffff;
  --k-surface:   #ffffff;
  --k-surface-2: #f4f2ee;
  --k-ink:       #2d2823;
  --k-ink-soft:  #4a4339;
  --k-dim:       #7c7466;
  --k-faint:     #ada592;
  --k-line:      #e9e4db;
  --k-line-soft: #f0ece5;

  --k-accent:      #8c3f48;  /* wine */
  --k-accent-deep: #6f2f38;
  --k-accent-glow: #c9a0a6;
  --k-on-accent:   #ffffff;

  /* Categorical hues. Status and ownership only, never decoration. */
  --k-cyan:   #3f7f93;
  --k-cyan-l: #7aa6b3;
  --k-alert:  #cc5147;
  --k-good:   #5a9266;
  --k-purple: #8a5f8c;
  --k-blue:   #4f7aa0;

  --k-display: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --k-sans:    -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;

  --k-radius: var(--k-radius-soft);
  --k-shadow: none;
  --k-scrim:  rgba(40, 30, 25, .35);
}

/* Amber keeps its true value under BOTH themes, so a console surface
   showing the Klovo mark gets the real orange and not the wine.
   NOTE: the console system originally called its #8c3f48 wine red
   `--amber`, which collided with this. It is `--k-accent` here, and
   `--k-amber` below always means Klovo Amber. */
:root,
[data-klovo-theme] {
  --k-amber:      #D4923B;
  --k-amber-deep: #B07320;
}


/* === 4. BASE ======================================================= */

.k-root {
  background: var(--k-bg);
  color: var(--k-ink-soft);
  font-family: var(--k-sans);
  font-size: var(--k-fs-body);
  line-height: var(--k-lh-body);
  -webkit-text-size-adjust: 100%;
}
.k-root *,
.k-root *::before,
.k-root *::after { box-sizing: border-box; }

.k-root :focus-visible {
  outline: 2px solid var(--k-accent);
  outline-offset: 2px;
  border-radius: var(--k-radius-sharp);
}


/* === 5. LAYOUT ===================================================== */

.k-wrap {
  width: 100%;
  max-width: var(--k-measure);
  margin-inline: auto;
  padding-inline: var(--k-sp-5);
}
.k-wrap--narrow { max-width: var(--k-measure-narrow); }
.k-wrap--text   { max-width: var(--k-measure-text); }

.k-section { padding-block: var(--k-section-pad); }

/* App shell: fixed sidebar beside a scrolling main. */
.k-shell { display: flex; min-height: 100vh; min-height: 100dvh; }
.k-shell__side {
  flex: 0 0 240px;
  border-right: 1px solid var(--k-line);
  background: var(--k-surface);
}
.k-shell__main {
  flex: 1 1 auto;
  min-width: 0;                 /* lets wide children scroll, not push */
  padding: var(--k-sp-4);
  /* Respects the home indicator on iOS, which the boards get wrong
     without it: the last row sits under the gesture bar. */
  padding-bottom: calc(var(--k-sp-4) + env(safe-area-inset-bottom));
}
@media (max-width: 767px) {
  .k-shell { flex-direction: column; }
  .k-shell__side { flex: 0 0 auto; border-right: none; border-bottom: 1px solid var(--k-line); }
}

/* Kanban column. Fixed width, scrolls its own contents, so a board of
   them scrolls horizontally without the page doing so. */
.k-lane {
  flex: 0 0 270px; min-width: 0;
  background: var(--k-surface-2);
  border: 1px solid var(--k-line);
  border-radius: var(--k-radius);
  padding: var(--k-sp-3);
  display: flex; flex-direction: column; gap: var(--k-sp-2);
}
.k-lane__head { display: flex; align-items: center; gap: var(--k-sp-2); }
.k-board { display: flex; gap: var(--k-sp-3); overflow-x: auto; align-items: flex-start; }

/* Quadrant panel. Four of these make an Eisenhower board. The top edge
   carries the quadrant's own colour via --k-quad-accent, set inline or by
   a semantic modifier; it falls back to a plain hairline. */
.k-quad {
  background: var(--k-surface);
  border: 1px solid var(--k-line);
  border-top: 3px solid var(--k-quad-accent, var(--k-line));
  border-radius: var(--k-radius);
  padding: var(--k-sp-3);
  min-width: 0;
}
.k-quad__empty { color: var(--k-faint); font-size: var(--k-fs-xs); padding: var(--k-sp-2); text-align: center; }

/* Vertical rhythm without margin collapse. */
.k-stack { display: flex; flex-direction: column; gap: var(--k-sp-4); }
.k-stack--tight { gap: var(--k-sp-2); }
.k-stack--loose { gap: var(--k-sp-6); }

/* Horizontal group that wraps. Filter bars, tag rows, button rows. */
.k-cluster { display: flex; flex-wrap: wrap; gap: var(--k-sp-2); align-items: center; }
.k-cluster--end { justify-content: flex-end; }

.k-grid {
  display: grid;
  gap: var(--k-sp-4);
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}


/* === 6. TYPOGRAPHY ================================================= */

.k-display, .k-h1, .k-h2, .k-h3, .k-h4 {
  font-family: var(--k-display);
  color: var(--k-ink);
  font-weight: var(--k-fw-semi);
  letter-spacing: var(--k-ls-tight);
  line-height: var(--k-lh-head);
  text-wrap: balance;
  margin: 0;
}
.k-display { font-size: var(--k-fs-display); line-height: var(--k-lh-tight); }
.k-h1 { font-size: var(--k-fs-h1); line-height: var(--k-lh-tight); }
.k-h2 { font-size: var(--k-fs-h2); }
.k-h3 { font-size: var(--k-fs-h3); }
.k-h4 { font-size: var(--k-fs-h4); }

/* One amber word in a headline is the deck's signature move. One. */
.k-h1 em, .k-h2 em, .k-display em {
  font-style: normal;
  color: var(--k-accent);
  font-weight: var(--k-fw-bold);
}

.k-eyebrow {
  font-family: var(--k-sans);
  font-size: var(--k-fs-eyebrow);
  letter-spacing: var(--k-ls-eyebrow);
  text-transform: uppercase;
  font-weight: var(--k-fw-semi);
  color: var(--k-dim);
  margin: 0;
}

.k-lede { font-size: var(--k-fs-lede); line-height: 1.55; color: var(--k-ink-soft); max-width: var(--k-measure-text); margin: 0; }
.k-body { font-size: var(--k-fs-body); max-width: var(--k-measure-text); margin: 0; }
.k-small { font-size: var(--k-fs-sm); }
.k-dim { color: var(--k-dim); }
.k-faint { color: var(--k-faint); }

/* Trailing meta on a section header: count, timestamp, secondary note. */
.k-sec-sub {
  font-size: var(--k-fs-xs);
  color: var(--k-dim);
  font-weight: var(--k-fw-med);
  margin-left: auto;
}

.k-rule { border: 0; border-top: 1px solid var(--k-line); margin-block: var(--k-sp-5); }
.k-rule--soft { border-top-color: var(--k-line-soft); }


/* === 7. BUTTONS ====================================================
   .k-btn is the filled accent action. There should be one obvious
   primary action per view; everything else is --ghost or --quiet. */

.k-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--k-sp-2);
  font: inherit;
  font-family: var(--k-sans);
  font-size: var(--k-fs-xs);
  font-weight: var(--k-fw-bold);
  line-height: 1;
  padding: var(--k-control-pad);
  min-height: var(--k-tap);
  border: 1px solid transparent;
  border-radius: var(--k-radius);
  background: var(--k-accent);
  color: var(--k-on-accent);
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--k-dur) var(--k-ease), border-color var(--k-dur) var(--k-ease);
}
.k-btn:hover { background: var(--k-accent-deep); }
.k-btn:active { transform: translateY(1px); }
.k-btn[disabled], .k-btn[aria-disabled="true"] {
  opacity: .55; cursor: default; pointer-events: none;
}

/* Outlined. The common secondary. */
.k-btn--ghost {
  background: transparent;
  color: var(--k-accent);
  border-color: var(--k-accent);
}
.k-btn--ghost:hover { background: var(--k-surface-2); color: var(--k-accent-deep); border-color: var(--k-accent-deep); }

/* Neutral outline, for actions that should not compete for the eye. */
.k-btn--quiet {
  background: transparent;
  color: var(--k-ink);
  border-color: var(--k-line);
}
.k-btn--quiet:hover { background: var(--k-surface-2); }

/* Ink-filled. Use where many rows each need an action and amber would
   blow the 10% budget: a catalogue table, a list of cards. */
.k-btn--ink {
  background: var(--k-ink);
  color: var(--k-bg);
  border-color: var(--k-ink);
}
.k-btn--ink:hover { background: var(--k-ink-soft); border-color: var(--k-ink-soft); }

/* Text-only. Destructive and tertiary actions. */
.k-btn--bare {
  background: none; border-color: transparent;
  color: var(--k-dim); font-weight: var(--k-fw-med);
  min-height: 0; padding: var(--k-sp-1) var(--k-sp-2);
}
.k-btn--bare:hover { background: none; color: var(--k-ink); text-decoration: underline; }

.k-btn--sm { font-size: var(--k-fs-eyebrow); padding: 6px 12px; min-height: 0; }
.k-btn--lg { font-size: var(--k-fs-body); padding: 15px 24px; }
.k-btn--block { display: flex; width: 100%; }

/* Dashed full-width "add another" affordance. On five surfaces today
   as .mini-add. Reads as a slot to fill, not a button to press. */
.k-add {
  display: block;
  width: 100%;
  padding: 7px;
  font: inherit;
  font-size: var(--k-fs-xs);
  background: transparent;
  border: 1px dashed var(--k-faint);
  border-radius: var(--k-radius);
  color: var(--k-dim);
  cursor: pointer;
  transition: border-color var(--k-dur) var(--k-ease), color var(--k-dur) var(--k-ease);
}
.k-add:hover { border-color: var(--k-accent); color: var(--k-accent); }


/* === 8. FORMS ====================================================== */

.k-field { display: flex; flex-direction: column; gap: var(--k-sp-1); margin-bottom: var(--k-sp-3); }

.k-label {
  font-size: var(--k-fs-eyebrow);
  letter-spacing: var(--k-ls-eyebrow);
  text-transform: uppercase;
  font-weight: var(--k-fw-semi);
  color: var(--k-dim);
}

/* Square check. Boards use this instead of a native checkbox so the tick
   sits on the card's own grid. Drive it with aria-checked, not a class. */
.k-check {
  width: 18px; height: 18px; flex: 0 0 auto;
  border: 2px solid var(--k-faint);
  border-radius: var(--k-radius);
  background: none; cursor: pointer; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  transition: border-color var(--k-dur) var(--k-ease), background var(--k-dur) var(--k-ease);
}
.k-check:hover { border-color: var(--k-accent); }
.k-check[aria-checked="true"] { background: var(--k-accent); border-color: var(--k-accent); }
.k-check[aria-checked="true"]::before { content: "\2713"; color: var(--k-on-accent); font-size: 12px; line-height: 1; }

.k-input, .k-textarea, .k-select {
  font: inherit;
  font-family: var(--k-sans);
  font-size: var(--k-fs-body);   /* 16px: anything less zooms iOS Safari */
  color: var(--k-ink);
  background: var(--k-surface);
  border: 1px solid var(--k-line);
  border-radius: var(--k-radius);
  padding: 9px 12px;
  min-height: var(--k-tap);
  width: 100%;
}
.k-input::placeholder, .k-textarea::placeholder { color: var(--k-faint); }
.k-input:focus-visible, .k-textarea:focus-visible, .k-select:focus-visible {
  outline: 2px solid var(--k-accent); outline-offset: 1px; border-color: var(--k-accent);
}
.k-textarea { min-height: 96px; resize: vertical; line-height: var(--k-lh-body); }
.k-select { appearance: none; padding-right: var(--k-sp-6); cursor: pointer; }

/* Inline "type a thing and add it" row. Four surfaces carry this. */
.k-addbar { display: flex; gap: var(--k-sp-2); align-items: stretch; }
.k-addbar .k-input { flex: 1 1 auto; min-width: 0; }

/* Preformatted output: an agent reply, a log, a pasted spec. Wraps
   rather than scrolling, because these are read not scrubbed. */
.k-pre {
  white-space: pre-wrap; overflow-wrap: anywhere;
  background: var(--k-surface-2);
  border: 1px solid var(--k-line);
  border-radius: var(--k-radius);
  padding: var(--k-sp-3);
  font-size: var(--k-fs-xs);
  line-height: var(--k-lh-body);
  color: var(--k-ink-soft);
}

.k-help { font-size: var(--k-fs-xs); color: var(--k-dim); }
.k-error { font-size: var(--k-fs-sm); color: var(--k-ink); font-weight: var(--k-fw-semi); }
.k-error::before { content: "\00d7\00a0"; }


/* === 9. CARDS ====================================================== */

.k-card {
  background: var(--k-surface);
  border: 1px solid var(--k-line);
  border-radius: var(--k-radius);
  padding: var(--k-sp-4);
  box-shadow: var(--k-shadow);
}
.k-card--flush { padding: 0; overflow: hidden; }
.k-card--quiet { background: var(--k-surface-2); border-color: transparent; }

/* Border, fill, radius and shadow each say "separate object". Spend
   them on the one card that matters rather than on all of them. */
.k-card--lifted { border-color: var(--k-accent); }

.k-card__head {
  display: flex; align-items: center; gap: var(--k-sp-2);
  padding-bottom: var(--k-sp-3); margin-bottom: var(--k-sp-3);
  border-bottom: 1px solid var(--k-line-soft);
}

/* Dense card for a board column. Tighter than .k-card and sized to be
   read a dozen at a time. */
.k-card--task { padding: var(--k-sp-3); border-radius: var(--k-radius); }
.k-card--task .k-card__head { padding-bottom: var(--k-sp-2); margin-bottom: var(--k-sp-2); }

/* Clickable card. Pair with .k-card. */
.k-card--link { cursor: pointer; text-decoration: none; display: block; color: inherit; transition: border-color var(--k-dur) var(--k-ease); }
.k-card--link:hover { border-color: var(--k-accent); }

/* Inline annotation: a caveat, a caption, a short aside beside content.
   Quieter than a card and never a whole section. */
.k-note {
  padding: var(--k-sp-2) var(--k-sp-3);
  background: var(--k-surface-2);
  border: 1px solid var(--k-line);
  border-radius: var(--k-radius);
  font-size: var(--k-fs-sm);
  color: var(--k-ink-soft);
}
.k-note strong { color: var(--k-ink); margin-right: var(--k-sp-2); }
/* Accent-edged note, for the one caveat on a page that must not be missed. */
.k-note--accent { border-left: 3px solid var(--k-accent); }

/* Centred single-purpose panel: PIN gate, sign-in, empty first-run. */
.k-panel {
  max-width: 420px;
  margin: var(--k-sp-8) auto;
  padding: var(--k-sp-7) var(--k-sp-6);
  text-align: center;
  background: var(--k-surface);
  border: 1px solid var(--k-line);
  border-radius: var(--k-radius-lg);
}


/* === 10. BADGES AND STATUS ========================================= */

/* Identity tile: a workspace, a person, an account. Square by default,
   --round for an avatar. Put an initial, a glyph or an <img> inside. */
.k-mark {
  width: 46px; height: 46px; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--k-accent); color: var(--k-on-accent);
  border-radius: var(--k-radius-lg);
  font-family: var(--k-display); font-weight: var(--k-fw-bold);
  font-size: var(--k-fs-lede); line-height: 1;
  overflow: hidden;
}
.k-mark img { width: 100%; height: 100%; object-fit: cover; display: block; }
.k-mark--sm { width: 30px; height: 30px; font-size: var(--k-fs-xs); border-radius: var(--k-radius); }
.k-mark--round { border-radius: 50%; }

/* Fixed-width slot so leading glyphs down a list share one optical edge. */
.k-icon { width: 20px; flex: 0 0 auto; text-align: center; display: inline-block; }

.k-chip {
  display: inline-flex; align-items: center; gap: var(--k-sp-1);
  padding: 6px 12px;
  font-size: var(--k-fs-xs);
  background: var(--k-surface);
  border: 1px solid var(--k-line);
  color: var(--k-dim);
  border-radius: var(--k-radius-pill);
  cursor: pointer;
  white-space: nowrap;
}
.k-chip:hover { border-color: var(--k-accent); color: var(--k-ink); }
.k-chip[aria-pressed="true"], .k-chip.is-on {
  background: var(--k-ink); color: var(--k-bg); border-color: var(--k-ink);
}

/* Non-interactive label. A chip you cannot press. */
.k-tag {
  display: inline-flex; align-items: center;
  padding: 3px 9px;
  font-size: var(--k-fs-eyebrow);
  font-weight: var(--k-fw-semi);
  letter-spacing: var(--k-ls-label);
  text-transform: uppercase;
  background: var(--k-surface-2);
  color: var(--k-dim);
  border-radius: var(--k-radius-pill);
  white-space: nowrap;
}

/* Status reads as a MARK plus a WORD. The deck rules out green-for-good
   and red-for-bad outright, and colour alone fails anyone who cannot
   distinguish it. The mark carries the meaning; colour only reinforces. */
.k-status { display: inline-flex; align-items: center; font-size: var(--k-fs-sm); font-weight: var(--k-fw-semi); color: var(--k-ink); }
.k-status::before { content: "\2022\00a0"; }
.k-status--ok::before   { content: "\2713\00a0"; }
.k-status--bad::before  { content: "\00d7\00a0"; }
.k-status--wait::before { content: "\2026\00a0"; }
.k-status--done { color: var(--k-dim); text-decoration: line-through; }

/* Small round marker for ownership or category. Always paired with a
   name or a title attribute, never colour on its own. */
.k-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--k-accent); flex: 0 0 auto; }


/* === 11. TABLES ==================================================== */

/* Wide content scrolls inside its own container so the page body never
   scrolls sideways. Wrap every table in this. */
.k-scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.k-table { width: 100%; border-collapse: collapse; font-size: var(--k-fs-sm); }
.k-table th {
  text-align: left;
  font-size: var(--k-fs-eyebrow);
  letter-spacing: var(--k-ls-label);
  text-transform: uppercase;
  font-weight: var(--k-fw-semi);
  color: var(--k-dim);
  padding: 0 var(--k-sp-3) var(--k-sp-2) 0;
  border-bottom: 1px solid var(--k-line);
  white-space: nowrap;
}
.k-table td {
  padding: var(--k-sp-3) var(--k-sp-3) var(--k-sp-3) 0;
  border-bottom: 1px solid var(--k-line-soft);
  vertical-align: top;
}
.k-table tr:last-child td { border-bottom: none; }
.k-table th:last-child, .k-table td:last-child { padding-right: 0; }
.k-num { font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }

/* Below 768px a wide table becomes one card per row. Give each cell a
   data-label and the header reappears beside its value. */
@media (max-width: 767px) {
  .k-table--stack, .k-table--stack tbody, .k-table--stack tr, .k-table--stack td { display: block; width: 100%; }
  .k-table--stack thead { display: none; }
  .k-table--stack tr {
    border: 1px solid var(--k-line);
    border-radius: var(--k-radius);
    padding: var(--k-sp-3);
    margin-bottom: var(--k-sp-3);
  }
  .k-table--stack td { border: none; padding: 2px 0; display: flex; justify-content: space-between; gap: var(--k-sp-3); }
  .k-table--stack td::before {
    content: attr(data-label);
    font-size: var(--k-fs-eyebrow);
    letter-spacing: var(--k-ls-label);
    text-transform: uppercase;
    color: var(--k-dim);
    flex: 0 0 auto;
  }
}


/* === 12. OVERLAYS ================================================== */

.k-scrim {
  position: fixed; inset: 0;
  background: var(--k-scrim);
  z-index: var(--k-z-overlay);
  opacity: 0; pointer-events: none;
  transition: opacity var(--k-dur) var(--k-ease);
}
.k-scrim.is-open { opacity: 1; pointer-events: auto; }

/* Right-hand detail panel. Full width on a phone. */
.k-drawer {
  position: fixed; top: 0; right: 0; bottom: 0;
  width: 600px; max-width: 100%;
  background: var(--k-surface);
  border-left: 1px solid var(--k-line);
  padding: var(--k-sp-5);
  padding-bottom: calc(var(--k-sp-5) + env(safe-area-inset-bottom));
  overflow-y: auto;
  z-index: var(--k-z-drawer);
  transform: translateX(100%);
  transition: transform var(--k-dur-slow) var(--k-ease);
}
.k-drawer.is-open { transform: translateX(0); }

/* Drawer/modal dismiss. Sits top-right of the head row. */
.k-drawer__close {
  background: none; border: none; cursor: pointer;
  color: var(--k-dim); font-size: 22px; line-height: 1;
  padding: var(--k-sp-1) var(--k-sp-2); margin-left: auto;
  min-height: var(--k-tap); min-width: var(--k-tap);
}
.k-drawer__close:hover { color: var(--k-ink); }

.k-modal {
  position: fixed; top: 50%; left: 50%;
  transform: translate(-50%, -50%) scale(.98);
  width: min(520px, calc(100vw - var(--k-sp-6)));
  max-height: calc(100vh - var(--k-sp-7));
  overflow-y: auto;
  background: var(--k-surface);
  border: 1px solid var(--k-line);
  border-radius: var(--k-radius-lg);
  padding: var(--k-sp-5);
  z-index: var(--k-z-drawer);
  opacity: 0; pointer-events: none;
  transition: opacity var(--k-dur) var(--k-ease), transform var(--k-dur) var(--k-ease);
}
.k-modal.is-open { opacity: 1; pointer-events: auto; transform: translate(-50%, -50%) scale(1); }

/* Transient confirmation. On seven surfaces today. */
.k-toast {
  position: fixed;
  left: 50%; bottom: var(--k-sp-5);
  transform: translateX(-50%) translateY(20px);
  background: var(--k-ink);
  color: var(--k-bg);
  border-radius: var(--k-radius);
  padding: var(--k-sp-3) var(--k-sp-4);
  font-size: var(--k-fs-sm);
  max-width: calc(100vw - var(--k-sp-6));
  z-index: var(--k-z-toast);
  opacity: 0; pointer-events: none;
  transition: opacity var(--k-dur) var(--k-ease), transform var(--k-dur) var(--k-ease);
}
.k-toast.is-open { opacity: 1; transform: translateX(-50%) translateY(0); }


/* === 13. NAVIGATION ================================================ */

.k-topbar {
  display: flex; align-items: center; gap: var(--k-sp-4);
  padding: var(--k-sp-3) var(--k-sp-4);
  padding-top: calc(var(--k-sp-3) + env(safe-area-inset-top));
  background: var(--k-surface);
  border-bottom: 1px solid var(--k-line);
  position: sticky; top: 0; z-index: var(--k-z-sticky);
}
.k-brand { display: inline-flex; align-items: center; gap: var(--k-sp-2); font-family: var(--k-display); font-weight: var(--k-fw-bold); color: var(--k-ink); text-decoration: none; letter-spacing: var(--k-ls-tight); }
.k-brand img { height: 24px; width: auto; display: block; }

.k-nav { display: flex; gap: var(--k-sp-1); flex-wrap: wrap; }
.k-nav a {
  padding: var(--k-sp-2) var(--k-sp-3);
  font-size: var(--k-fs-sm);
  color: var(--k-ink-soft);
  text-decoration: none;
  border-radius: var(--k-radius);
}
.k-nav a:hover { background: var(--k-surface-2); color: var(--k-ink); }
.k-nav a[aria-current] { color: var(--k-accent); font-weight: var(--k-fw-semi); }

/* Segmented control. One choice from a small set, shown all at once.
   Use it where tabs would imply page-level navigation and this does not. */
.k-segmented {
  display: flex; gap: var(--k-sp-1); padding: var(--k-sp-1);
  background: var(--k-surface-2);
  border: 1px solid var(--k-line);
  border-radius: var(--k-radius);
}
.k-segmented__item {
  flex: 1 1 0; min-width: 0;
  font: inherit; font-size: var(--k-fs-xs); font-weight: var(--k-fw-semi);
  text-align: center; white-space: nowrap;
  padding: var(--k-sp-2); min-height: var(--k-tap);
  background: none; border: none; border-radius: var(--k-radius);
  color: var(--k-dim); cursor: pointer;
}
.k-segmented__item:hover { color: var(--k-ink); }
.k-segmented__item[aria-selected="true"] { background: var(--k-surface); color: var(--k-ink); box-shadow: var(--k-shadow); }

.k-tabs { display: flex; gap: var(--k-sp-2); flex-wrap: wrap; margin-bottom: var(--k-sp-4); border-bottom: 1px solid var(--k-line); }
.k-tab {
  font: inherit; font-size: var(--k-fs-sm); font-weight: var(--k-fw-med);
  background: none; border: none; cursor: pointer;
  padding: var(--k-sp-2) var(--k-sp-3);
  min-height: var(--k-tap);
  color: var(--k-dim);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.k-tab:hover { color: var(--k-ink); }
/* Equal-width tabs that fill their container. For a narrow column or a
   phone, where centred labels beat a left-aligned run. */
.k-tabs--fill .k-tab { flex: 1 1 0; text-align: center; }
.k-tab[aria-selected="true"] { color: var(--k-ink); border-bottom-color: var(--k-accent); font-weight: var(--k-fw-semi); }


/* Pagination. Prev/next either side of a position label. */
.k-pager { display: flex; align-items: center; gap: var(--k-sp-3); justify-content: center; }
.k-pager__pos { font-size: var(--k-fs-xs); color: var(--k-dim); font-variant-numeric: tabular-nums; }


/* === 14. STATS ===================================================== */

.k-stat { display: flex; flex-direction: column; gap: 2px; }
.k-stat__val {
  font-family: var(--k-display);
  font-size: var(--k-fs-h3);
  font-weight: var(--k-fw-bold);
  color: var(--k-ink);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.k-stat__val em { font-style: normal; color: var(--k-accent); }
.k-stat__label {
  font-size: var(--k-fs-eyebrow);
  letter-spacing: var(--k-ls-eyebrow);
  text-transform: uppercase;
  color: var(--k-dim);
}

/* Hairline stat strip. Numbers beat adjectives: "500 lbs per cabinet". */
.k-stat-row {
  display: flex; flex-wrap: wrap; gap: var(--k-sp-5);
  padding-block: var(--k-sp-3);
  border-top: 1px solid var(--k-line);
  border-bottom: 1px solid var(--k-line);
}

/* Proportion bar. Track plus fill; set the width inline from data. */
.k-bar { height: 6px; background: var(--k-surface-2); border-radius: var(--k-radius-pill); overflow: hidden; }
.k-bar__fill { height: 100%; background: var(--k-accent); border-radius: inherit; transition: width var(--k-dur-slow) var(--k-ease); }


/* === 15. STATES ==================================================== */

/* Drag and drop. .is-dragging on the lifted element; .k-drop--before or
   --after on the card the pointer would insert next to. */
.is-dragging { opacity: .4; transform: scale(.99); }
.k-drop--before { box-shadow: 0 -3px 0 0 var(--k-accent); }
.k-drop--after  { box-shadow: 0  3px 0 0 var(--k-accent); }

.k-empty {
  padding: var(--k-sp-6);
  text-align: center;
  color: var(--k-faint);
  font-style: italic;
  font-size: var(--k-fs-sm);
}
.k-loading { padding: var(--k-sp-3) var(--k-sp-1); color: var(--k-faint); font-size: var(--k-fs-xs); font-style: italic; }

/* Skeleton. Static under reduced motion rather than pulsing. */
.k-skeleton { background: var(--k-surface-2); border-radius: var(--k-radius); animation: k-pulse 1.4s ease-in-out infinite; }
@keyframes k-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .5; } }
@media (prefers-reduced-motion: reduce) { .k-skeleton { animation: none; } }

/* A class that sets `display` outranks the UA rule for [hidden], so an
   element with both stays visible. This puts that back. */
[hidden] { display: none !important; }


/* === 16. UTILITIES ================================================= */

.k-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;
}
.k-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.k-clamp-2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.k-nowrap { white-space: nowrap; }
.k-tabular { font-variant-numeric: tabular-nums; }
.k-center { text-align: center; }
.k-right { text-align: right; }
.k-mt-0 { margin-top: 0; }
.k-mb-0 { margin-bottom: 0; }
.k-grow { flex: 1 1 auto; min-width: 0; }
.k-push { margin-left: auto; }

@media print {
  .k-topbar, .k-drawer, .k-scrim, .k-toast, .k-btn { display: none !important; }
  .k-root { background: #fff; color: #000; }
}
