/* ============================================================================
   Kodgo Grid — design tokens ("theme")
   ----------------------------------------------------------------------------
   The single source of truth for the app's look. Every value below comes from
   the redesign specification (new-design/README.md §1): spec names, spec
   hexes, nothing invented. Change a value here once and it updates everywhere.

   How it propagates: Bootstrap 5.3 is built on CSS variables (--bs-*). Our
   tokens (--kg-*) are defined first and Bootstrap's variables are pointed at
   them, so every button, link, border, table and utility across the app picks
   up the palette without touching each page.

   Three layers, top to bottom:
     1. TOKENS    — colour, rules, type, radius, layout. The spec, verbatim.
     2. BASE      — body, headings, links, focus, and the type-role classes
                    (.kg-*) that every ported screen is composed from.
     3. BOOTSTRAP — the re-pointing, plus the few component re-skins
                    (buttons, forms, tables, cards) that UNPORTED pages still
                    rely on. Blocks marked LEGACY are deleted when the last
                    page is ported; nothing new may depend on them.

   Governing rules (spec): rank the page; figures are ledgers on hairline
   rules, not boxes; orange is for things you can act on; green and brick are
   read-only signals; no gradients; no shadows except the one on the two
   page-level primary pills; hover is a warm tint and nothing else.
   ========================================================================== */

:root {
    /* ---- 1. TOKENS --------------------------------------------------------- */

    /* Colour (spec §1 "Color") */
    --kg-rail:          #1c2024;   /* left navigation rail background only   */
    --kg-page:          #eeefec;   /* app canvas / every screen background    */
    --kg-panel:         #f9f9f7;   /* the few real panels (sheet, chart card) */
    --kg-field:         #e3e5e1;   /* search input fill                       */
    --kg-ink:           #14181b;   /* primary text, names, headline figures   */
    --kg-body:          #333a3e;   /* body text, table cell text              */
    --kg-secondary:     #5c666d;   /* sub-labels, dates, currency suffixes    */
    --kg-muted:         #78828a;   /* section labels, tertiary text           */
    --kg-faint:         #98a0a5;   /* column heads, meta lines, empty dashes  */
    --kg-hairline-ink:  #b9c0c3;   /* route arrows, separator dots, zeros     */
    --kg-accent:        #e2622a;   /* ACTIONS ONLY: buttons, links, nav mark  */
    --kg-accent-hover:  #c9531f;   /* primary pill hover (spec §4)            */
    --kg-accent-active: #a8401a;   /* primary pill active (spec §4)           */
    --kg-accent-text:   #a8401a;   /* accent as text where contrast matters   */
    --kg-accent-ondark: #f79a68;   /* accent count badges inside the rail     */
    --kg-subcontracted: #f79a68;   /* the resold-load marker on light rows    */
    --kg-on-accent:     #f9f9f7;   /* label colour on an accent fill          */
    --kg-positive:      #2f6b4f;   /* read-only success signal                */
    --kg-warning:       #b3311c;   /* read-only problem signal                */
    --kg-notice:        #9a6b00;   /* read-only heads-up: true but worth a look (an overnight window) */

    /* The same colours as RGB triplets, for Bootstrap's rgba() utilities. */
    --kg-page-rgb:        238, 239, 236;
    --kg-ink-rgb:         20, 24, 27;
    --kg-body-rgb:        51, 58, 62;
    --kg-secondary-rgb:   92, 102, 109;
    --kg-muted-rgb:       120, 130, 138;
    --kg-faint-rgb:       152, 160, 165;
    --kg-accent-rgb:      226, 98, 42;
    --kg-accent-text-rgb: 168, 64, 26;
    --kg-positive-rgb:    47, 107, 79;
    --kg-warning-rgb:     179, 49, 28;

    /* Rail text (spec §1 "Rail text colors") */
    --kg-onrail:            #eeefec;
    --kg-onrail-idle:       rgba(238, 241, 242, .58);
    --kg-onrail-meta:       rgba(238, 241, 242, .42);
    --kg-onrail-tagline:    rgba(238, 241, 242, .4);
    --kg-onrail-group:      rgba(238, 241, 242, .32);
    --kg-onrail-version:    rgba(238, 241, 242, .3);
    --kg-onrail-hover-bg:   rgba(238, 241, 242, .08);
    --kg-onrail-active-bg:  rgba(238, 241, 242, .1);
    --kg-onrail-segment-bg: rgba(238, 241, 242, .14);
    --kg-onrail-name:       rgba(238, 241, 242, .85);   /* user's name in the rail (prototype) */
    --kg-onrail-icon:       rgba(238, 241, 242, .5);    /* log-out icon, idle RO/EN segment     */
    --kg-rule-onrail-strong: rgba(238, 241, 242, .2);   /* the RO/EN toggle's border            */

    /* Rules and separators (spec §1 "Rules and separators") */
    --kg-rule-row:     rgba(20, 24, 27, .09);   /* every table row              */
    --kg-rule-section: rgba(20, 24, 27, .12);   /* section rule, tab track      */
    --kg-rule-strip:   rgba(20, 24, 27, .14);   /* table header, strip edges    */
    --kg-rule-total:   rgba(20, 24, 27, .24);   /* total row                    */
    --kg-rule-context: rgba(20, 24, 27, .2);    /* context-line separators      */
    --kg-rule-divider: rgba(20, 24, 27, .1);    /* inside stat strips, search   */
    --kg-rule-control: rgba(20, 24, 27, .16);   /* control borders              */
    --kg-rule-empty:   rgba(20, 24, 27, .22);   /* dashed empty-state box       */
    --kg-rule-warning: rgba(179, 49, 28, .28);  /* the ruled warning band       */
    --kg-rule-onrail:  rgba(238, 241, 242, .13);

    /* The only tints and the only shadow */
    --kg-hover:         rgba(198, 113, 57, .055);  /* row / nav hover, nothing else */
    --kg-positive-fill: rgba(47, 107, 79, .13);    /* the chart's area fill         */
    --kg-shadow-pill:   0 1px 2px rgba(20, 24, 27, .18);

    /* Type (spec §1 "Type") */
    --kg-font-display: "Archivo", "Figtree", system-ui, sans-serif;
    --kg-font-ui:      "Figtree", -apple-system, BlinkMacSystemFont, "Segoe UI",
                       Roboto, "Helvetica Neue", Arial, sans-serif;
    --kg-font-mono:    "JetBrains Mono", ui-monospace, "Cascadia Mono", Consolas,
                       "Liberation Mono", monospace;

    /* Radius (spec §1 "Space, radius, shape") */
    --kg-r-pill:  999px;   /* every button, pill, toggle and search field */
    --kg-r-panel: 14px;    /* the two real panels                         */
    --kg-r-empty: 12px;    /* the dashed empty-state box                  */
    --kg-r-nav:   9px;     /* nav items                                   */
    --kg-r-icon:  8px;     /* the small icon button                       */

    /* Layout (spec §2 "The shell", §4 "Responsive") */
    --kg-rail-w:        238px;
    --kg-rail-w-narrow: 56px;
    --kg-gutter:        40px;
    --kg-content-max:   1202px;   /* 1440 design width minus the rail */

    /* ---- 3a. BOOTSTRAP RE-POINTING ------------------------------------------
       What carries the palette into every existing page. Bootstrap's own
       warning (yellow) and info (cyan) have no equivalent in the spec and are
       deliberately left at their defaults until the pages using them are
       ported. ------------------------------------------------------------- */
    --bs-body-bg:               var(--kg-page);
    --bs-body-bg-rgb:           var(--kg-page-rgb);
    --bs-body-color:            var(--kg-body);
    --bs-body-color-rgb:        var(--kg-body-rgb);
    --bs-emphasis-color:        var(--kg-ink);
    --bs-emphasis-color-rgb:    var(--kg-ink-rgb);
    --bs-heading-color:         var(--kg-ink);
    --bs-secondary-color:       var(--kg-secondary);
    --bs-secondary-color-rgb:   var(--kg-secondary-rgb);
    --bs-tertiary-color:        var(--kg-faint);
    --bs-tertiary-color-rgb:    var(--kg-faint-rgb);
    --bs-secondary-bg:          var(--kg-field);
    --bs-tertiary-bg:           var(--kg-panel);
    --bs-border-color:          var(--kg-rule-section);
    --bs-border-color-translucent: var(--kg-rule-row);

    --bs-primary:               var(--kg-accent);
    --bs-primary-rgb:           var(--kg-accent-rgb);
    --bs-primary-text-emphasis: var(--kg-accent-text);
    --bs-primary-bg-subtle:     rgba(226, 98, 42, .08);    /* transitional tint of the accent, unported badges/alerts only */
    --bs-primary-border-subtle: rgba(226, 98, 42, .28);
    --bs-success:               var(--kg-positive);
    --bs-success-rgb:           var(--kg-positive-rgb);
    --bs-success-text-emphasis: var(--kg-positive);
    --bs-success-bg-subtle:     rgba(47, 107, 79, .08);
    --bs-success-border-subtle: rgba(47, 107, 79, .28);
    --bs-danger:                var(--kg-warning);
    --bs-danger-rgb:            var(--kg-warning-rgb);
    --bs-danger-text-emphasis:  var(--kg-warning);
    --bs-danger-bg-subtle:      rgba(179, 49, 28, .06);
    --bs-danger-border-subtle:  var(--kg-rule-warning);

    --bs-link-color:            var(--kg-accent);
    --bs-link-color-rgb:        var(--kg-accent-rgb);
    --bs-link-hover-color:      var(--kg-accent-text);
    --bs-link-hover-color-rgb:  var(--kg-accent-text-rgb);

    --bs-body-font-family:      var(--kg-font-ui);

    --bs-border-radius:         var(--kg-r-icon);
    --bs-border-radius-sm:      var(--kg-r-icon);
    --bs-border-radius-lg:      var(--kg-r-empty);
    --bs-border-radius-xl:      var(--kg-r-panel);
    --bs-border-radius-xxl:     var(--kg-r-panel);
    --bs-border-radius-pill:    var(--kg-r-pill);

    /* No shadows. The .shadow/.shadow-sm/.shadow-lg utilities on existing
       markup resolve to these, so the whole app goes flat from here. */
    --bs-box-shadow:            none;
    --bs-box-shadow-sm:         none;
    --bs-box-shadow-lg:         none;
    --bs-box-shadow-inset:      none;

}

/* ---------------------------------------------------------------------------
   2. BASE
   --------------------------------------------------------------------------- */
html, body {
    font-family: var(--kg-font-ui);
    font-weight: 400;
    color: var(--kg-body);
    background-color: var(--kg-page);
    /* Spec: tabular figures on every container that holds numbers. The whole
       product is numbers, so it is set once here rather than per container —
       a figure can never fall out of alignment because one wrapper forgot. */
    font-variant-numeric: tabular-nums;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Display face for page titles and section headings, and nothing else. h4–h6
   stay in the interface face: the spec's display roles stop at h3. */
h1, h2, h3 {
    font-family: var(--kg-font-display);
    font-weight: 800;
    letter-spacing: -.02em;
    color: var(--kg-ink);
}
h2 { font-size: 34px; }
h3 { font-size: 25px; letter-spacing: -.01em; }
h4, h5, h6 {
    font-family: var(--kg-font-ui);
    font-weight: 700;
    letter-spacing: normal;
    color: var(--kg-ink);
}

/* Links: no underline at rest; on hover a 1px underline at 4px offset and the
   accent-text colour (spec §4 "Action link"). */
a { color: var(--kg-accent); text-decoration: none; }
a:hover {
    color: var(--kg-accent-text);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 4px;
}
/* Bootstrap's own link-shaped controls on unported pages are not action links. */
.nav-link:hover,
.navbar-brand:hover,
.dropdown-item:hover,
.page-link:hover { text-decoration: none; }

/* Keyboard focus: 2px accent outline at 2px offset on everything interactive
   (spec §4 "Accessibility"). Replaces Bootstrap's glow rings below. */
:focus-visible {
    outline: 2px solid var(--kg-accent);
    outline-offset: 2px;
}

/* Motion: essentially none. Hover tints are instant or <=120ms. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { transition-duration: 0s !important; }
}

/* ---- Type roles (spec §1 "Type scale actually in use") -----------------------
   Composed by the ported screens. Sizes are the spec's pixel values. */
.kg-display {
    font-family: var(--kg-font-display);
    font-weight: 800;
    letter-spacing: -.02em;
    color: var(--kg-ink);
}
.kg-hero           { font-size: 88px; line-height: .98; letter-spacing: -.025em; } /* dashboard hero figure */
.kg-hero--invoices { font-size: 76px; line-height: 1; }
.kg-title          { font-size: 34px; }                                          /* page title (h2) */
.kg-title--detail  { font-size: 36px; line-height: 1.08; }
.kg-h3             { font-size: 25px; letter-spacing: -.01em; }                  /* section heading */
.kg-figure         { font-size: 32px; }                                          /* stat-strip figure */
.kg-figure--sheet  { font-size: 40px; }                                          /* invoice-sheet figure */
@media (max-width: 1199.98px) {
    .kg-hero, .kg-hero--invoices { font-size: 56px; }
}

/* Phones. The figure is `white-space: nowrap` — deliberately, so a money amount never splits across
   lines mid-digits — which means the only way it can fit is to be smaller. Measured at 320/360/412 px:
   at 56px a five-figure amount overflows its card by 50px on a 360px phone and even five DIGITS
   overflow at 320px. Everything fits at 40px. */
@media (max-width: 719.98px) {
    .kg-hero, .kg-hero--invoices { font-size: 40px; }
}

/* Ledger figure (right column of a label/value row) */
.kg-ledger-figure {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 3px;
    font-weight: 600;
    font-size: 19px;
    color: var(--kg-ink);
}
.kg-ledger-figure .kg-cur { font-size: 13px; }

/* Micro-label: the workhorse heading every table, stat and section. 10.5px in
   muted for section labels; the --head variant is 9.5px in faint for column heads. */
.kg-micro {
    font-family: var(--kg-font-mono);
    font-weight: 500;
    font-size: 10.5px;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--kg-muted);
}
.kg-micro--head { font-size: 9.5px; color: var(--kg-faint); }

/* Status: a 5px dot plus a mono uppercase label. Never a filled badge. The dot
   takes --kg-status-dot when it differs from the label colour. */
.kg-status {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-family: var(--kg-font-mono);
    font-weight: 500;
    font-size: 10.5px;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--kg-body);
}
.kg-status::before {
    content: "";
    flex: none;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--kg-status-dot, currentColor);
}
.kg-status--new      { color: var(--kg-accent-text); --kg-status-dot: var(--kg-accent); }
.kg-status--positive { color: var(--kg-positive); }
.kg-status--transit  { color: var(--kg-body); --kg-status-dot: var(--kg-ink); }
.kg-status--done     { color: var(--kg-muted); --kg-status-dot: var(--kg-hairline-ink); }
.kg-status--warning  { color: var(--kg-warning); }

/* Codes: request/invoice numbers, VAT IDs. */
.kg-code     { font-family: var(--kg-font-mono); font-weight: 500; font-size: 12.5px; }
.kg-code--sm { font-size: 13px; }

/* Money: the figure in the row's weight, the currency as a separate, smaller,
   secondary span. Never a currency glyph. Sizes per context (spec §1 "Money"). */
.kg-cur          { font-weight: 500; color: var(--kg-secondary); }
.kg-cur--hero    { font-size: 30px; }
.kg-cur--sheet   { font-size: 19px; }
.kg-cur--figure  { font-size: 18px; }

/* Row meta (the line under a name), empty values, tabular override. */
.kg-meta { font-size: 12.5px; color: var(--kg-faint); }
.kg-dash { color: var(--kg-faint); }
.kg-tnum { font-variant-numeric: tabular-nums; }

/* Colour utilities in the spec's vocabulary. */
.kg-ink       { color: var(--kg-ink); }
.kg-body      { color: var(--kg-body); }
.kg-secondary { color: var(--kg-secondary); }
.kg-muted     { color: var(--kg-muted); }
.kg-faint     { color: var(--kg-faint); }
.kg-positive  { color: var(--kg-positive); }
.kg-warning   { color: var(--kg-warning); }
.kg-accent-text { color: var(--kg-accent-text); }

/* ---------------------------------------------------------------------------
   3b. BOOTSTRAP COMPONENT RE-SKINS
   Bootstrap bakes hex values into per-component variables, so re-pointing the
   root alone does not reach them. Each block is what an unported page needs
   to read as part of the same product; ported screens use the .kg-* layer.
   --------------------------------------------------------------------------- */

/* Buttons: 999px radius on every button (spec), interface face, 600 weight.
   The base size is the spec's filter pill (13.5px, 9px 15px); -lg is the
   page-level primary pill (14px, 12px 22px). */
.btn {
    --bs-btn-font-family: var(--kg-font-ui);
    --bs-btn-font-weight: 600;
    --bs-btn-font-size: 13.5px;
    --bs-btn-padding-y: 9px;
    --bs-btn-padding-x: 15px;
    --bs-btn-border-radius: var(--kg-r-pill);
    transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}
.btn-sm {
    --bs-btn-font-size: 12.5px;
    --bs-btn-padding-y: 7px;
    --bs-btn-padding-x: 12px;
    --bs-btn-border-radius: var(--kg-r-pill);
}
.btn-lg {
    --bs-btn-font-size: 14px;
    --bs-btn-padding-y: 12px;
    --bs-btn-padding-x: 22px;
    --bs-btn-border-radius: var(--kg-r-pill);
}
.btn:focus-visible,
.btn-check:focus-visible + .btn {
    outline: 2px solid var(--kg-accent);
    outline-offset: 2px;
    box-shadow: none;
}

/* Primary = the accent pill. Hover darkens, active darkens further (spec §4).
   The resting colours are the spec's exactly; see the plan's D4 for the
   contrast figure that decision accepted. */
.btn-primary {
    --bs-btn-color: var(--kg-on-accent);
    --bs-btn-bg: var(--kg-accent);
    --bs-btn-border-color: var(--kg-accent);
    --bs-btn-hover-color: var(--kg-on-accent);
    --bs-btn-hover-bg: var(--kg-accent-hover);
    --bs-btn-hover-border-color: var(--kg-accent-hover);
    --bs-btn-active-color: var(--kg-on-accent);
    --bs-btn-active-bg: var(--kg-accent-active);
    --bs-btn-active-border-color: var(--kg-accent-active);
    --bs-btn-disabled-color: var(--kg-on-accent);
    --bs-btn-disabled-bg: var(--kg-accent);
    --bs-btn-disabled-border-color: var(--kg-accent);
}
.btn-outline-primary {
    --bs-btn-color: var(--kg-accent-text);
    --bs-btn-border-color: var(--kg-rule-control);
    --bs-btn-hover-color: var(--kg-on-accent);
    --bs-btn-hover-bg: var(--kg-accent);
    --bs-btn-hover-border-color: var(--kg-accent);
    --bs-btn-active-color: var(--kg-on-accent);
    --bs-btn-active-bg: var(--kg-accent-active);
    --bs-btn-active-border-color: var(--kg-accent-active);
}
/* Outline-secondary reads as the spec's filter pill; its active state is the
   segmented toggle's ink fill — so period/currency groups on unported pages
   already look like the designed control. */
.btn-outline-secondary {
    --bs-btn-color: var(--kg-body);
    --bs-btn-border-color: var(--kg-rule-control);
    --bs-btn-hover-color: var(--kg-ink);
    --bs-btn-hover-bg: var(--kg-hover);
    --bs-btn-hover-border-color: var(--kg-rule-control);
    --bs-btn-active-color: var(--kg-panel);
    --bs-btn-active-bg: var(--kg-ink);
    --bs-btn-active-border-color: var(--kg-ink);
    --bs-btn-disabled-color: var(--kg-faint);
    --bs-btn-disabled-border-color: var(--kg-rule-control);
}
.btn-light {
    --bs-btn-color: var(--kg-body);
    --bs-btn-bg: var(--kg-field);
    --bs-btn-border-color: var(--kg-field);
    --bs-btn-hover-color: var(--kg-ink);
    --bs-btn-hover-bg: var(--kg-field);
    --bs-btn-hover-border-color: var(--kg-rule-control);
    --bs-btn-active-color: var(--kg-ink);
    --bs-btn-active-bg: var(--kg-field);
    --bs-btn-active-border-color: var(--kg-rule-control);
}
.btn-link {
    --bs-btn-color: var(--kg-accent);
    --bs-btn-hover-color: var(--kg-accent-text);
    --bs-btn-active-color: var(--kg-accent-active);
    text-decoration: none;
}

/* Forms: panel fill, control border, 8px radius (the spec's smallest radius —
   only buttons, pills, toggles and the search field are 999px). */
.form-control,
.form-select {
    background-color: var(--kg-panel);
    border: 1px solid var(--kg-rule-control);
    border-radius: var(--kg-r-icon);
    color: var(--kg-ink);
    font-size: 14px;
}
.form-control::placeholder { color: var(--kg-muted); }
.form-control:focus,
.form-select:focus {
    background-color: var(--kg-panel);
    border-color: var(--kg-rule-control);
    color: var(--kg-ink);
    outline: 2px solid var(--kg-accent);
    outline-offset: 2px;
    box-shadow: none;
}
.form-check-input {
    border-color: var(--kg-rule-control);
}
.form-check-input:checked {
    background-color: var(--kg-accent);
    border-color: var(--kg-accent);
}
.form-check-input:focus {
    border-color: var(--kg-rule-control);
    outline: 2px solid var(--kg-accent);
    outline-offset: 2px;
    box-shadow: none;
}

/* Validation (was in app.css; retuned to the warning token, no glow). */
.invalid,
.invalid:focus,
.modified.invalid,
.modified.invalid:focus,
.form-control.invalid,
.form-select.invalid,
.custom-input.invalid {
    border-color: var(--kg-warning) !important;
    box-shadow: none !important;
}
.invalid:focus,
.form-control.invalid:focus,
.form-select.invalid:focus { outline-color: var(--kg-warning); }
.validation-message { color: var(--kg-warning); font-size: 12.5px; }

/* Floating menus and dialogs: a control border instead of the shadow they
   used to float on. Not designed in the spec; the codebase's own menus stay. */
.dropdown-menu {
    --bs-dropdown-bg: var(--kg-panel);
    --bs-dropdown-color: var(--kg-body);
    --bs-dropdown-link-color: var(--kg-body);
    --bs-dropdown-link-hover-color: var(--kg-ink);
    --bs-dropdown-link-hover-bg: var(--kg-hover);
    --bs-dropdown-link-active-color: var(--kg-panel);
    --bs-dropdown-link-active-bg: var(--kg-ink);
    --bs-dropdown-border-radius: var(--kg-r-empty);
    border: 1px solid var(--kg-rule-control) !important;
}
.modal-content {
    background-color: var(--kg-panel);
    border: 1px solid var(--kg-rule-control);
    border-radius: var(--kg-r-panel);
}
/* ---- LEGACY: alerts on unported pages and in the modal layer -------------------
   Bootstrap's own yellow and cyan are in no part of this palette, and they sit
   loudest inside the modals a ported page opens. STOPGAP: repaint them in the
   spec's two signal colours over the standard tint, so an unported alert reads as
   quiet rather than as a different product. The SHAPE stays Bootstrap's — the real
   answer is the spec's ruled band (.kg-warnband), which needs the page gutter it
   cannot get inside a modal-body. Deleted when the modal layer is ported. */
.alert { border-radius: var(--kg-r-empty); }
.alert-warning, .alert-danger {
    --bs-alert-color: var(--kg-warning);
    --bs-alert-bg: rgba(179, 49, 28, .06);
    --bs-alert-border-color: var(--kg-rule-warning);
    --bs-alert-link-color: var(--kg-accent-text);
}
.alert-info, .alert-secondary, .alert-light {
    --bs-alert-color: var(--kg-body);
    --bs-alert-bg: var(--kg-hover);
    --bs-alert-border-color: var(--kg-rule-control);
    --bs-alert-link-color: var(--kg-accent-text);
}
.alert-success {
    --bs-alert-color: var(--kg-positive);
    --bs-alert-bg: var(--kg-positive-fill);
    --bs-alert-border-color: rgba(47, 107, 79, .28);
    --bs-alert-link-color: var(--kg-accent-text);
}
.pagination {
    --bs-pagination-bg: transparent;
    --bs-pagination-border-color: var(--kg-rule-control);
    --bs-pagination-hover-bg: var(--kg-hover);
    --bs-pagination-hover-border-color: var(--kg-rule-control);
    --bs-pagination-focus-bg: var(--kg-hover);
    --bs-pagination-focus-box-shadow: none;
    --bs-pagination-active-bg: var(--kg-ink);
    --bs-pagination-active-border-color: var(--kg-ink);
    --bs-pagination-disabled-bg: transparent;
    --bs-pagination-disabled-border-color: var(--kg-rule-row);
}

/* Badges keep their weight; their colours follow the re-pointed utilities. */
.badge { font-weight: 600; }

/* ---- LEGACY: tables on unported list pages ------------------------------------
   Column heads as micro-labels over a strip rule, rows on row rules, the warm
   hover tint. Gets the old .table markup most of the way to the spec's ruled
   row without touching it; the ported lists use the .kg-row grid instead. */
.table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--kg-body);
    --bs-table-border-color: var(--kg-rule-row);
    --bs-table-striped-bg: transparent;
    --bs-table-hover-color: var(--kg-body);
    --bs-table-hover-bg: var(--kg-hover);
}
.table-light {
    --bs-table-bg: transparent;
    --bs-table-color: var(--kg-faint);
    --bs-table-border-color: var(--kg-rule-strip);
}
.table > thead th,
.table-light > :not(caption) > * > * {
    background-color: transparent;
    color: var(--kg-faint);
    font-family: var(--kg-font-mono);
    font-weight: 500;
    font-size: 9.5px;
    letter-spacing: .14em;
    text-transform: uppercase;
    border-bottom: 1px solid var(--kg-rule-strip);
}
.table > tbody > tr { border-color: var(--kg-rule-row); }

/* ---- LEGACY: cards on unported pages -------------------------------------------
   A card is rendered as the spec's panel (panel fill, 14px radius, hairline
   border, no shadow) so the old card grids read as calm surfaces until they
   are rebuilt as ledgers. The !important beats the rounded-* utilities and
   per-page overrides the old markup still carries. */
.card {
    --bs-card-bg: var(--kg-panel);
    --bs-card-color: var(--kg-body);
    --bs-card-border-color: var(--kg-rule-divider);
    --bs-card-border-radius: var(--kg-r-panel);
    --bs-card-inner-border-radius: calc(var(--kg-r-panel) - 1px);
    --bs-card-cap-bg: transparent;
    border-radius: var(--kg-r-panel) !important;
    box-shadow: none !important;
}


/* ---------------------------------------------------------------------------
   4. SHELL AND CONTROLS (spec §2)
   The rail, the two page-header patterns, the two repeating structures and
   the shared controls every ported screen is assembled from. Global rather
   than scoped on purpose: NavLink, Icon and LanguageSwitcher render their own
   elements, and the same controls appear on every screen.
   --------------------------------------------------------------------------- */

/* ---- The rail -------------------------------------------------------------- */
.kg-rail {
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100dvh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 20px;
    padding: 24px 14px 18px;
    background: var(--kg-rail);
    color: var(--kg-onrail);
}
.kg-rail-brand {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 0 9px 0 10px;
    color: var(--kg-onrail);
}
.kg-rail-brand:hover { color: var(--kg-onrail); text-decoration: none; }
.kg-rail-brand .kg-brandmark { flex: none; height: 22px; width: auto; }
.kg-rail-brand-text { display: flex; flex-direction: column; min-width: 0; }
.kg-rail-brand-name {
    font-size: 12.5px;
    font-weight: 700;
    letter-spacing: .15em;
    text-transform: uppercase;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.kg-rail-brand-tagline {
    margin-top: 2px;
    font-size: 9px;
    font-weight: 600;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--kg-onrail-tagline);
    white-space: nowrap;
}
.kg-rail-cta { width: 100%; }
.kg-rail-nav { display: flex; flex-direction: column; gap: 2px; }
.kg-rail-link {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 8px 10px;
    border-radius: var(--kg-r-nav);
    font-size: 13.5px;
    font-weight: 500;
    color: var(--kg-onrail-idle);
    transition: background-color .12s ease, color .12s ease;
}
.kg-rail-link .kg-icon { flex: none; }
.kg-rail-link:hover { background: var(--kg-onrail-hover-bg); color: var(--kg-onrail); text-decoration: none; }
/* Active: the 2px orange bar on the inside edge is the only orange in the nav. */
.kg-rail-link.active {
    background: var(--kg-onrail-active-bg);
    color: var(--kg-onrail);
    box-shadow: inset 2px 0 0 var(--kg-accent);
}
.kg-rail-label { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Counts sit right-aligned, tabular. Actionable ones (approvals, issuing problems, unread) are 700 in
   the on-dark accent; informational ones (clients) are 600 in the meta alpha. */
.kg-rail-count {
    margin-left: auto;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--kg-onrail-meta);
    font-variant-numeric: tabular-nums;
}
.kg-rail-count.is-actionable { font-weight: 700; color: var(--kg-accent-ondark); }
.kg-rail-group-label {
    padding: 0 10px;
    margin-bottom: 7px;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--kg-onrail-group);
}
.kg-rail-bottom { margin-top: auto; display: flex; flex-direction: column; gap: 2px; }
.kg-rail-user {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--kg-rule-onrail);
}
.kg-rail-avatar {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--kg-secondary);
    color: var(--kg-onrail);
    font-size: 11px;
    font-weight: 700;
}
.kg-rail-user-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.kg-rail-user-name {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--kg-onrail-name);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.kg-rail-user-role { font-size: 10.5px; color: var(--kg-onrail-meta); }
.kg-rail-logout { display: contents; }
.kg-rail-iconbtn {
    flex: none;
    display: inline-flex;
    padding: 6px;
    border: 0;
    border-radius: var(--kg-r-icon);
    background: transparent;
    color: var(--kg-onrail-icon);
    cursor: pointer;
    transition: background-color .12s ease, color .12s ease;
}
.kg-rail-iconbtn:hover { background: var(--kg-onrail-hover-bg); color: var(--kg-onrail); }
.kg-rail-foot { display: flex; align-items: center; gap: 8px; margin-top: 12px; padding: 0 2px; }

/* The RO/EN pill toggle (rail footer) */
.kg-lang { display: inline-flex; }
.kg-lang-group {
    display: inline-flex;
    border: 1px solid var(--kg-rule-onrail-strong);
    border-radius: var(--kg-r-pill);
    overflow: hidden;
}
.kg-lang-seg {
    padding: 4px 11px;
    border: 0;
    background: transparent;
    font-family: inherit;
    font-size: 11px;
    font-weight: 600;
    color: var(--kg-onrail-icon);
    cursor: pointer;
}
.kg-lang-seg:hover { color: var(--kg-onrail); }
.kg-lang-seg.is-on { background: var(--kg-onrail-segment-bg); color: var(--kg-onrail); }
.kg-lang-seg:focus-visible { outline-offset: -2px; }

/* Below ~900px: icons only, 56px (spec §4). Labels, counts and text collapse; each link's title
   carries its name, and the visually-hidden count sentence stays for screen readers. */
@media (max-width: 899.98px) {
    .kg-rail { padding: 20px 8px 14px; gap: 16px; }
    .kg-rail-brand { justify-content: center; padding: 0; }
    .kg-rail-brand-text,
    .kg-rail-label,
    .kg-rail-count,
    .kg-rail-user-text,
    .kg-rail-group-label { display: none; }
    .kg-rail-cta { width: 40px; height: 40px; padding: 0; margin: 0 auto; border-radius: 50%; }
    .kg-rail-link { justify-content: center; padding: 10px 0; gap: 0; }
    .kg-rail-user { flex-direction: column; gap: 8px; }
    .kg-rail-foot { justify-content: center; padding: 0; }
    .kg-lang-group { flex-direction: column; }
    .kg-lang-seg { padding: 5px 8px; }
}

/* ---- Shared controls (light ground) --------------------------------------- */

/* Primary pill: the accent, for actions only. The rail's New order is the base size; the two
   page-level pills (--page) are larger and carry the product's one shadow. */
.kg-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    padding: 10px 14px;
    border: 0;
    border-radius: var(--kg-r-pill);
    background: var(--kg-accent);
    color: var(--kg-on-accent);
    font-family: var(--kg-font-ui);
    font-size: 13.5px;
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color .12s ease;
}
.kg-pill:hover { background: var(--kg-accent-hover); color: var(--kg-on-accent); text-decoration: none; }
.kg-pill:active { background: var(--kg-accent-active); }
/* Disabled primary (wizard spec §1): the accent at .4, cursor says why — nothing else changes. */
.kg-pill:disabled, .kg-pill[aria-disabled="true"] { background: rgba(226, 98, 42, .4); cursor: not-allowed; box-shadow: none; }
.kg-pill--page { padding: 12px 22px; font-size: 14px; box-shadow: var(--kg-shadow-pill); }

/* Filter pill: transparent, control border, reads as a sentence ("Sorted by billed"). */
.kg-filter {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 9px 15px;
    border: 1px solid var(--kg-rule-control);
    border-radius: var(--kg-r-pill);
    background: transparent;
    font-family: inherit;
    font-size: 13.5px;
    font-weight: 500;
    color: var(--kg-body);
    white-space: nowrap;
    cursor: pointer;
    transition: background-color .12s ease;
}
.kg-filter:hover { background: var(--kg-hover); color: var(--kg-ink); }
.kg-filter .kg-icon { flex: none; }

/* Search field: field fill, magnifier in muted, 270–310px wide per placeholder. */
.kg-search {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 280px;
    padding: 9px 16px;
    border: 1px solid var(--kg-rule-divider);
    border-radius: var(--kg-r-pill);
    background: var(--kg-field);
    color: var(--kg-muted);
}
.kg-search .kg-icon { flex: none; color: var(--kg-muted); }
.kg-search input {
    flex: 1;
    min-width: 0;
    padding: 0;
    border: 0;
    background: transparent;
    font-family: inherit;
    font-size: 13.5px;
    color: var(--kg-ink);
    outline: 0;
}
.kg-search input::placeholder { color: var(--kg-muted); }
.kg-search:focus-within { outline: 2px solid var(--kg-accent); outline-offset: 2px; }

/* Segmented toggle (period, currency): bordered 999px group; active = ink fill, idle = secondary. */
.kg-segmented {
    display: inline-flex;
    border: 1px solid var(--kg-rule-control);
    border-radius: var(--kg-r-pill);
    overflow: hidden;
}
.kg-segment {
    padding: 8px 14px;
    border: 0;
    background: transparent;
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--kg-secondary);
    white-space: nowrap;
    cursor: pointer;
    transition: background-color .12s ease, color .12s ease;
}
.kg-segment:hover { background: var(--kg-hover); color: var(--kg-ink); }
.kg-segment.is-on, .kg-segment.is-on:hover { background: var(--kg-ink); color: var(--kg-panel); }
/* A segment for something not live yet: stated, not hidden — and visibly not a choice. */
.kg-segment:disabled, .kg-segment:disabled:hover { background: transparent; color: var(--kg-hairline-ink); cursor: default; }
.kg-segment:focus-visible { outline-offset: -2px; }

/* Month stepper: the same bordered group with 14px chevrons in secondary around a 13.5px/600 label. */
.kg-stepper {
    display: inline-flex;
    align-items: center;
    border: 1px solid var(--kg-rule-control);
    border-radius: var(--kg-r-pill);
    overflow: hidden;
    font-variant-numeric: tabular-nums;
}
.kg-stepper-btn {
    display: inline-flex;
    padding: 9px 12px;
    border: 0;
    background: transparent;
    color: var(--kg-secondary);
    cursor: pointer;
}
.kg-stepper-btn:hover { background: var(--kg-hover); color: var(--kg-ink); }
.kg-stepper-btn:disabled { color: var(--kg-hairline-ink); cursor: default; background: transparent; }
.kg-stepper-btn:focus-visible { outline-offset: -2px; }
.kg-stepper-label { padding: 0 4px; font-size: 13.5px; font-weight: 600; color: var(--kg-ink); white-space: nowrap; }

/* Action link: 13px/600 accent; hover accent-text + 1px underline at 4px. --quiet is the muted
   variant for "Clear" and "Export CSV". Works as <a> or <button>. */
.kg-action {
    padding: 0;
    border: 0;
    background: none;
    font-family: inherit;
    font-size: 14px;
    font-weight: 600;
    color: var(--kg-accent);
    white-space: nowrap;
    cursor: pointer;
}
.kg-action:hover {
    color: var(--kg-accent-text);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 4px;
}
.kg-action--quiet { font-weight: 500; color: var(--kg-muted); }
.kg-action--quiet:hover { color: var(--kg-body); }

/* Name link (a client or request name in a row): ink, underline on hover, colour unchanged. */
.kg-name { display: block; font-size: 15.5px; font-weight: 600; color: var(--kg-ink); }
.kg-name:hover {
    color: var(--kg-ink);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
}

/* ---- Page-header patterns --------------------------------------------------- */

/* A — list header: title + one-line description left, controls right. */
.kg-listhead {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 30px;
    padding: 34px var(--kg-gutter) 0;
}
.kg-listhead h2 { margin: 0; }
.kg-listhead-desc { margin-top: 7px; font-size: 14px; color: var(--kg-secondary); }
.kg-listhead-controls { flex: none; display: flex; align-items: center; gap: 12px; }

/* B — context bar: a thin ruled bar with a breadcrumb left and controls right. */
.kg-contextbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px 20px;
    padding: 19px var(--kg-gutter);
    border-bottom: 1px solid var(--kg-rule-section);
}
.kg-contextbar-crumb { display: flex; align-items: center; gap: 12px; white-space: nowrap; }
.kg-contextbar-sep { font-size: 13px; color: var(--kg-faint); }
.kg-contextbar-current { font-size: 13px; font-weight: 500; color: var(--kg-body); }
.kg-contextbar-controls { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; }

/* Content bands: the 40px gutter every block keeps, and the inset section rule between bands. */
.kg-band { padding-left: var(--kg-gutter); padding-right: var(--kg-gutter); }
.kg-rule { height: 1px; margin: 0 var(--kg-gutter); background: var(--kg-rule-section); }

/* ---- The two repeating structures ------------------------------------------- */

/* Stat strip: a ruled band of equal cells; micro-label over an Archivo 24px figure. The first cell
   has no left border or padding and the last no right padding, so the strip sits flush with the gutter. */
.kg-strip {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    margin: 28px var(--kg-gutter) 0;
    border-top: 1px solid var(--kg-rule-strip);
    border-bottom: 1px solid var(--kg-rule-strip);
    font-variant-numeric: tabular-nums;
}
.kg-strip-cell { padding: 18px 22px; border-left: 1px solid var(--kg-rule-divider); min-width: 0; }
.kg-strip-cell:first-child { padding-left: 0; border-left: 0; }
.kg-strip-cell:last-child { padding-right: 0; }
.kg-strip-figure { margin-top: 4px; }

/* Ruled row: every table. A grid with explicit column widths (set --kg-row-cols on the container or
   the row), 16px gap, 14px side padding pulled out with a negative margin so the hover tint bleeds
   past the text edge. Text on a hairline grid: no background, no border, no radius. */
.kg-rowhead,
.kg-row {
    display: grid;
    grid-template-columns: var(--kg-row-cols, 1fr);
    gap: 16px;
    margin: 0 -14px;
    font-variant-numeric: tabular-nums;
}
.kg-rowhead {
    padding: 0 14px 9px;
    border-bottom: 1px solid var(--kg-rule-strip);
}
.kg-row {
    align-items: center;
    padding: 15px 14px;
    border-bottom: 1px solid var(--kg-rule-row);
    transition: background-color .12s ease;
}
.kg-row:last-child { border-bottom: 0; }
.kg-row:hover { background: var(--kg-hover); }
.kg-row--dense { padding: 14px; }
.kg-right { text-align: right; }

/* Ledger: label/value rows, baseline-aligned, a divider rule under each but the last. */
.kg-ledger { font-variant-numeric: tabular-nums; }
.kg-ledger-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    padding: 9px 0;
    border-bottom: 1px solid var(--kg-rule-divider);
}
.kg-ledger-row:last-child { border-bottom: 0; }
.kg-ledger-label { font-size: 13.5px; color: var(--kg-body); }
.kg-ledger-sub { display: block; margin-top: 1px; font-size: 11.5px; color: var(--kg-faint); }
.kg-ledger-figure.is-zero { color: var(--kg-faint); }

/* The only two panels and the one empty state the design allows. */
.kg-panel {
    padding: 22px 24px 18px;
    border: 1px solid var(--kg-rule-divider);
    border-radius: var(--kg-r-panel);
    background: var(--kg-panel);
}

/* ---- Page cards -------------------------------------------------------------
   The owner asked (2026-08-26) for the screens to be built out of cards rather than the spec's
   flush-left bands. The SHAPE is still the spec's panel — border, 14px radius, #f9f9f7 on the
   #eeefec canvas, no shadow — just at block scale, and every ported screen now reads the same way:

     1. a header card across the page, carrying the screen's identity and its controls;
     2. figure cards under it — a matched pair per band, stretched to equal height;
     3. a list card holding the filter row, the table and its footer.

   A card zeroes --kg-gutter for everything inside it. That one line is what lets the shared blocks
   whose side margins hang off the page gutter (.kg-table, .kg-foot, .kg-band, .kg-strip,
   .kg-warnband) sit flush against the card's own padding without each growing an inside-a-card
   variant — and .kg-table's -14px/+14px hover bleed keeps working unchanged.

   Flex column, so the block a card ends on can claim its floor with `margin-top: auto`: the pair in
   a row is always the same height, and without that the shorter one's content bunches at the top
   over a hole. */
.kg-card {
    --kg-gutter: 0px;
    display: flex;
    flex-direction: column;
    min-width: 0;
    padding: 26px 28px 24px;
    border: 1px solid var(--kg-rule-divider);
    border-radius: var(--kg-r-panel);
    background: var(--kg-panel);
}
/* The header card: one horizontal bar (a .kg-listhead or a .kg-contextbar), which brings its own
   alignment — only the direction has to come back from the column default above. Its inner block
   keeps its own layout but gives up the page padding it was written with. */
.kg-card--head { flex-direction: row; padding: 20px 26px; }
.kg-card--head > .kg-listhead,
.kg-card--head > .kg-contextbar { padding: 0; border-bottom: 0; }
/* The bar has to FILL the card, or its own `justify-content: space-between` has no space to
   distribute and the controls hug the title instead of holding the right edge. */
.kg-card--head > * { flex: 1; min-width: 0; }

/* What the shared blocks give up when a card holds them: the leading space each was written to keep
   from the top of a page. Zeroing --kg-gutter above already took their SIDE margins; these are the
   vertical halves of the same idea, and they are on .kg-card rather than on any one screen's class
   so a new card composes out of these blocks without a fresh set of overrides.
   The strip also drops its bottom edge — inside a card the border is already there — and the
   footer its bottom padding, which is the page's breathing room and not the card's. */
.kg-card > .kg-listhead { padding-top: 0; }
.kg-card > .kg-filterrow,
.kg-card > .kg-tabs { padding-top: 0; }
.kg-card > .kg-strip { margin-top: 22px; padding-top: 22px; border-bottom: 0; }
.kg-card > .kg-foot { padding-bottom: 0; }

/* A row of cards: the page gutters and the gap between them. --split is the 1fr | right-column
   band the dashboard and Invoices share — fluid rather than the spec's fixed right column, so a
   wide monitor is not left with a blank fifth. */
.kg-cardrow {
    display: grid;
    gap: 24px;
    padding: 24px var(--kg-gutter) 0;
}
.kg-cardrow--split { grid-template-columns: minmax(0, 1fr) clamp(400px, 40%, 680px); }
.kg-cardrow--last { padding-bottom: 44px; }
/* A warning band BETWEEN cards is still a ruled band and never a card (spec) — it just needs the
   same air the cards keep from each other, which its own 15px padding does not give it. */
.kg-cardrow + .kg-warnband { margin-top: 22px; }

/* Below ~1200 the right-hand card stacks under the main one (spec §4). Stacked they are no longer
   a pair, so nothing has to hold a floor. */
@media (max-width: 1199.98px) {
    .kg-cardrow--split { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 719.98px) {
    .kg-card { padding: 20px 18px; }
    .kg-card--head { flex-direction: column; align-items: stretch; gap: 14px; padding: 18px; }
    /* Title over controls rather than beside them: side by side at this width the title column is
       one word wide and the search box is a slot. */
    .kg-card .kg-listhead { flex-direction: column; gap: 16px; }
    .kg-card .kg-listhead-controls { flex-wrap: wrap; }
    /* Four figures across a phone is four squeezed columns; two rows of two, and the dividers come
       off because a column rule between stacked cells separates the wrong things. */
    .kg-card .kg-strip { grid-auto-flow: row; grid-template-columns: 1fr 1fr; gap: 18px 20px; }
    .kg-card .kg-strip-cell { padding: 0; border-left: 0; }
}
.kg-empty {
    padding: 18px 20px;
    border: 1px dashed var(--kg-rule-empty);
    border-radius: var(--kg-r-empty);
    font-size: 13.5px;
    line-height: 1.55;
    color: var(--kg-secondary);
    text-wrap: pretty;
}
.kg-empty .kg-action { display: block; margin-top: 11px; }

/* The line under a hero figure: what the number is made of, as short statements separated by hairlines
   ("4 invoices issued and unpaid · none past due"). Shared, because every hero has one and the two that
   existed had drifted into private copies of the same ten lines. The BAND above it stays per page —
   Bills and the dashboard split their columns differently, and each says why in its own file. */
.kg-context {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 22px;
    margin-top: 16px;
    font-size: 14px;
    color: var(--kg-body);
}
.kg-context strong { font-weight: 600; }
.kg-context-sep { width: 1px; height: 13px; background: var(--kg-rule-context); }

/* The ruled warning band: the one problem on a screen, as rules and a dot — never a card. */
.kg-warnband {
    display: flex;
    align-items: center;
    gap: 14px;
    margin: 0 var(--kg-gutter);
    padding: 15px 0;
    border-top: 1px solid var(--kg-rule-warning);
    border-bottom: 1px solid var(--kg-rule-warning);
    font-size: 13.5px;
    color: var(--kg-body);
}
.kg-warnband::before {
    content: "";
    flex: none;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--kg-warning);
}
.kg-warnband-text { flex: 1; text-wrap: pretty; }
.kg-warnband strong { font-weight: 600; color: var(--kg-warning); }
.kg-warnband .kg-action { flex: none; }

/* A 6px signal dot inline with text (positive / warning context lines). */
.kg-dot {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    vertical-align: middle;
}

/* Service tabs: 14px, count beside in a lighter weight (zero counts in hairline-ink); the active tab
   is ink, 600, with a GRAPHITE underline — not orange. */
.kg-tabs {
    display: flex;
    align-items: center;
    gap: 28px;
    padding: 26px var(--kg-gutter) 0;
    border-bottom: 1px solid var(--kg-rule-section);
}
.kg-tab {
    padding: 0 0 12px;
    border: 0;
    background: none;
    font-family: inherit;
    font-size: 14px;
    font-weight: 500;
    color: var(--kg-muted);
    cursor: pointer;
}
.kg-tab:hover { color: var(--kg-ink); text-decoration: none; }
.kg-tab.is-on { color: var(--kg-ink); font-weight: 600; box-shadow: inset 0 -2px 0 var(--kg-ink); }
.kg-tab-count { margin-left: 5px; font-weight: 500; color: var(--kg-muted); font-variant-numeric: tabular-nums; }
.kg-tab-count.is-zero { color: var(--kg-hairline-ink); }

/* List footer: the plain-language total on the left, quiet links on the right. */
.kg-listfoot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    margin-top: 26px;
    font-size: 12.5px;
    color: var(--kg-muted);
    font-variant-numeric: tabular-nums;
}
.kg-listfoot-links { display: flex; align-items: center; gap: 18px; }

/* ---- 4b. THE REGISTERS (spec 3.5-3.6) -----------------------------------------------
   The skeleton in Register.razor composes these; the pages only set --kg-row-cols. */
.kg-register { display: flex; flex-direction: column; }

/* Filter row: sentence-shaped pills on the left, a plain-language data-quality note on the right. */
.kg-filterrow {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px 16px;
    padding-top: 18px;
    padding-bottom: 14px;
}
.kg-filterrow-filters { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
.kg-filterrow-note { font-size: 13.5px; color: var(--kg-muted); }
.kg-filterrow-note.is-warning { display: inline-flex; align-items: center; gap: 7px; color: var(--kg-warning); }
.kg-filterwrap { position: relative; display: inline-flex; }
.kg-filter { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
.kg-filter.is-active { border-color: var(--kg-ink); color: var(--kg-ink); }

/* The menu behind a filter pill or a row's overflow button: the codebase's own pattern — a
   transparent catcher under an absolutely positioned list — in the spec's panel colours. */
.kg-catcher { position: fixed; inset: 0; z-index: 1040; }
.kg-menu {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 1050;
    min-width: 200px;
    padding: 6px;
    background: var(--kg-panel);
    border: 1px solid var(--kg-rule-control);
    border-radius: var(--kg-r-empty);
}
.kg-menu--right { left: auto; right: 0; min-width: 160px; }
.kg-menu-item {
    display: block;
    width: 100%;
    padding: 8px 10px;
    border: 0;
    border-radius: var(--kg-r-icon);
    background: none;
    text-align: left;
    font: inherit;
    font-size: 13.5px;
    color: var(--kg-body);
    white-space: nowrap;
    cursor: pointer;
}
.kg-menu-item:hover { background: var(--kg-hover); color: var(--kg-ink); }
.kg-menu-item.is-on { color: var(--kg-ink); font-weight: 600; }
.kg-menu-item--danger { color: var(--kg-warning); }
.kg-menu-item--danger:hover { color: var(--kg-warning); }

/* The table: scrolls sideways below ~1100 rather than squeezing the name column (spec 4). The
   rows pull 14px past the text edge for their hover tint, so the scroll box starts 14px inside the
   gutter and pads the same 14px back. */
.kg-table {
    overflow-x: auto;
    margin: 0 calc(var(--kg-gutter) - 14px);
    padding: 0 14px;
}
/* A row's overflow menu is absolutely positioned INSIDE this box, and overflow-x:auto forces
   overflow-y to compute as auto too — so the box clips a menu opened on a low row even when no
   horizontal scrolling is happening. Above the width where a row fits nothing needs to scroll, so
   the box no longer has to clip: the menus escape and the tables are otherwise unchanged.

   1280px is the threshold for the 900px rows declared below. The two wider tables (Bills 1040px,
   Requests 1060px) hold their scroll box until 1440 — each sets that beside its own min-width.
   ponytail: below this width the menus can still be cut off (they stay reachable — the box scrolls
   to them). Escaping there needs the top layer (popover + anchor positioning) or a fixed-position
   menu with JS; worth it only if narrow windows turn out to be a real workflow. */
@media (min-width: 1280px) {
    .kg-table { overflow: visible; }
}

.kg-table .kg-rowhead,
.kg-table .kg-row { min-width: 900px; }
.kg-rowhead > * {
    font-family: var(--kg-font-mono);
    font-weight: 500;
    font-size: 10.5px;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--kg-faint);
    white-space: nowrap;
}
.kg-row--skeleton { min-height: 56px; }
.kg-row--skeleton > span { display: block; height: 10px; width: 38%; border-radius: 999px; background: var(--kg-rule-section); }
.kg-table-empty { margin: 18px 0; }

/* Footer: one sentence of totals above a .24 rule, the pager on the right. */
.kg-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px 16px;
    margin: 18px var(--kg-gutter) 0;
    padding: 14px 0 44px;
    border-top: 1px solid var(--kg-rule-total);
    font-size: 13.5px;
    color: var(--kg-secondary);
    font-variant-numeric: tabular-nums;
}

/* Cells. */
.kg-reg-name { min-width: 0; text-wrap: pretty; }
.kg-name--btn { padding: 0; border: 0; background: none; text-align: left; font-family: inherit; cursor: pointer; }
.kg-reg-meta { display: block; margin-top: 2px; font-size: 12.5px; color: var(--kg-faint); }
.kg-reg-contact { min-width: 0; }
.kg-reg-person { display: block; font-size: 14.5px; font-weight: 500; color: var(--kg-ink); }
.kg-reg-email { display: block; font-size: 12.5px; color: var(--kg-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kg-reg-gap { display: block; font-size: 14px; color: var(--kg-faint); }
.kg-reg-gap + .kg-action { font-size: 13.5px; }
.kg-reg-count { font-size: 15px; color: var(--kg-body); }
.kg-reg-money {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;
    font-size: 15.5px;
    font-weight: 600;
    color: var(--kg-ink);
    white-space: nowrap;
}
.kg-reg-money .kg-cur { margin-left: 4px; font-size: 12.5px; }
.kg-reg-date { font-size: 14px; color: var(--kg-secondary); white-space: nowrap; }
.kg-reg-actions { display: flex; align-items: center; justify-content: flex-end; gap: 4px; }
.kg-iconbtn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 0;
    border-radius: var(--kg-r-icon);
    background: transparent;
    font-size: 16px;
    line-height: 1;
    color: var(--kg-muted);
    cursor: pointer;
}
.kg-iconbtn:hover { background: var(--kg-hover); color: var(--kg-ink); }
.kg-strip-unit { font-family: var(--kg-font-ui); font-size: 16px; font-weight: 500; letter-spacing: 0; color: var(--kg-secondary); }

/* ---- Invoices additions (spec 3.4) --------------------------------------------------
   A dot-and-label read-only signal, used inline in a hero context line, and the warning
   band's action group when it offers more than one way out. */
.kg-signal { display: inline-flex; align-items: center; gap: 7px; }
.kg-warnband-actions { flex: none; display: flex; align-items: center; gap: 16px; }
.kg-hairline { color: var(--kg-hairline-ink); }
/* The stepper's label doubles as "jump to this month" on the Invoices screen. */
.kg-stepper-label--btn { border: 0; background: none; font-family: inherit; cursor: pointer; }
.kg-stepper-label--btn:hover { background: var(--kg-hover); }

/* A money line: the figure right-aligned, its currency code in a fixed column beside it, so a stack
   of them (a ledger, a total row, a strip cell) has its codes in a straight line however wide the
   figures get. The code is the same smaller secondary span it is everywhere else. */
.kg-money {
    display: grid;
    grid-template-columns: 1fr auto;
    column-gap: 5px;
    align-items: baseline;
    white-space: nowrap;
}
.kg-money-value { text-align: right; font-variant-numeric: tabular-nums; }
.kg-money .kg-cur { min-width: 2.4em; text-align: left; }

/* The requests list's search takes the spec's wider field (its placeholder names four things). */
.kg-search--wide { width: 320px; }
/* An action link that is currently ON (the invoice-selection toggle), so the control says which. */
.kg-action.is-on { color: var(--kg-accent-text); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; }

/* ---- Anonymous pages (login, register, access denied, visitor thank-you) ----------------
   One centred panel on the page ground; the brand mark in ink above the form. The max-width
   stays inline per page (it is the page's one layout fact). */
.kg-anon {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    padding: 40px 16px;
    background: var(--kg-page);
}
.kg-anon-card { width: 100%; border: 1px solid var(--kg-rule-divider); }
.kg-anon-mark { color: var(--kg-ink); }

/* A register's footer figures are computed over the whole register; this is the note that says so
   when the table above is filtered. Quieter than the figures, on its own line under them. */
.kg-foot-note {
    display: block;
    margin-top: 3px;
    font-size: 12.5px;
    color: var(--kg-faint);
}

/* A qualifier under a strip figure — what the figure above had to leave out. Never competes with it. */
.kg-strip-note {
    margin-top: 4px;
    font-size: 12px;
    font-weight: 400;
    letter-spacing: 0;
    color: var(--kg-faint);
}

/* ==========================================================================
   WIZARD FORM LAYER (new-design wizard §1–§2, 2026-08-26)

   The form-control vocabulary of the redesigned new-request wizard: white pill
   inputs a step LIGHTER than the panel they sit on, micro field labels with an
   unmarked-required convention, the definition row for authority-returned
   facts, and the panel that every group of information sits in. Global rather
   than page-scoped because five step components share it — and because it is
   the app's form language now, for any ported form that comes later.

   .kg-form is the SCOPE: applied to the wizard's content column, it also
   re-skins descendant .form-control faces (the shared Date/Time pickers) to
   the same white pill without touching those components.
   ========================================================================== */

/* Text input: white, NOT panel — inputs sit ON panels, so they must be a step
   lighter than the surface under them. */
.kg-in {
    width: 100%;
    box-sizing: border-box;
    background: #ffffff;
    border: 1px solid var(--kg-rule-control);
    border-radius: var(--kg-r-pill);
    padding: 10px 15px;
    font-family: inherit;
    font-size: 13.5px;
    color: var(--kg-ink);
}
.kg-in::placeholder { color: var(--kg-faint); }
.kg-in:focus, .kg-in:focus-visible {
    outline: 2px solid var(--kg-accent);
    outline-offset: 1px;
    border-color: transparent;
    box-shadow: none;
}
.kg-in.invalid, .kg-in.modified.invalid { border-color: rgba(179, 49, 28, .45) !important; }
/* Native number spinners eat half of a narrow cell; the design's numeric inputs are plain. */
.kg-in::-webkit-inner-spin-button, .kg-in::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
input.kg-in[type="number"] { -moz-appearance: textfield; appearance: textfield; }
.kg-in--num { font-variant-numeric: tabular-nums; }
/* Narrow numeric cells (dimensions, weight, quantity): centred, tighter padding. */
.kg-in--cell { padding: 10px 8px; text-align: center; font-variant-numeric: tabular-nums; min-width: 0; }

/* Select: the same white pill with room for a chevron, drawn as a background so
   the markup stays a bare <select>/<InputSelect class="kg-in kg-sel">. */
.kg-sel {
    appearance: none;
    -webkit-appearance: none;
    padding-right: 34px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2378828a' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 15px center;
}
/* Compact in-row select (the cargo line's stop binding). */
.kg-sel--compact {
    width: auto;
    padding: 7px 32px 7px 13px;
    font-size: 12.5px;
    font-weight: 500;
    background-position: right 13px center;
    background-size: 11px 11px;
}

/* Field label: micro, above its input. Required is the DEFAULT and unmarked —
   no red asterisks in this design; optional fields say so instead. A label
   heading a GROUP of fields uses the darker variant. */
.kg-flabel {
    display: block;
    margin-bottom: 8px;
    font-family: var(--kg-font-mono);
    font-weight: 500;
    font-size: 9.5px;
    line-height: 1;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--kg-faint);
}
.kg-flabel--group { font-size: 10.5px; color: var(--kg-muted); margin-bottom: 14px; }
.kg-optional { color: var(--kg-faint); font-weight: 400; letter-spacing: .06em; text-transform: none; }

/* Definition row: a read-only fact (what an authority returned), never a
   pre-filled editable field. Label column via --kg-def-label. */
.kg-defrow {
    display: grid;
    grid-template-columns: var(--kg-def-label, 112px) 1fr;
    padding: 9px 0;
    border-bottom: 1px solid var(--kg-rule-row);
}
.kg-defrow:last-child { border-bottom: 0; }
.kg-defrow > .kg-flabel { margin-bottom: 0; line-height: 1.6; align-self: start; }
.kg-defval { font-size: 13.5px; font-weight: 500; color: var(--kg-body); }
.kg-defval--name { font-size: 14.5px; font-weight: 600; color: var(--kg-ink); }
.kg-defqual { color: var(--kg-muted); font-weight: 400; }

/* Toggle: 34×19 pill, knob inset 2.5px. Wrap a hidden checkbox:
   <label class="kg-toggle"><InputCheckbox/><span class="kg-toggle-track"></span></label> */
.kg-toggle { position: relative; display: inline-flex; flex: none; cursor: pointer; }
.kg-toggle input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.kg-toggle-track {
    width: 34px;
    height: 19px;
    border-radius: var(--kg-r-pill);
    background: #c8ced1;
    transition: background-color .12s ease;
    pointer-events: none;
}
.kg-toggle-track::after {
    content: "";
    position: absolute;
    top: 2.5px;
    left: 2.5px;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--kg-panel);
    transition: transform .12s ease;
}
.kg-toggle input:checked + .kg-toggle-track { background: var(--kg-positive); }
.kg-toggle input:checked + .kg-toggle-track::after { transform: translateX(15px); }
.kg-toggle input:focus-visible + .kg-toggle-track { outline: 2px solid var(--kg-accent); outline-offset: 2px; }


/* Segmented control ON A PANEL: white-filled variant of .kg-segmented, so the
   idle segments read as controls against the panel fill. */
.kg-segmented--field { background: #ffffff; }

/* The wizard panel: every group of information sits in one. 16px radius —
   deliberately one step softer than .kg-panel — and panels STACK 18px apart;
   no section is ever separated only by a rule. */
.kg-wpanel {
    background: var(--kg-panel);
    border: 1px solid var(--kg-rule-divider);
    border-radius: 16px;
    padding: 18px 24px 24px;
}
.kg-wpanel + .kg-wpanel, .kg-wpanel-gap { margin-top: 18px; }
/* Stop panels clip a tinted header band to the radius. */
/* Padding is the panel's own; the tinted header rounds ITSELF (see .wsp-head). This used to clip with
   overflow:hidden, which also clipped the date and time popovers that open inside the panel — they are
   z-index 1056 but no z-index escapes a clipping ancestor. */
.kg-wpanel--clip { padding: 0; }
.kg-wpanel-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 24px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--kg-rule-divider);
}
.kg-wpanel-title { font-size: 15px; font-weight: 600; color: var(--kg-ink); }
/* The header's right slot: a summary of what's inside, or ONE accent action — never both. */
.kg-wpanel-note { font-size: 12.5px; color: var(--kg-muted); }

/* One-line explanatory prose under the field it explains. Capped at one line by design. */
.kg-fhint { margin: 10px 0 0; font-size: 12.5px; color: var(--kg-muted); text-wrap: pretty; }

/* Inline validation sentence: a 6px brick dot + one sentence. Never colour-only. */
.kg-fwarn {
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: 12.5px;
    color: var(--kg-warning);
}
.kg-fwarn::before {
    content: "";
    flex: none;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--kg-warning);
}

/* Re-skin the shared pickers' .form-control faces inside a wizard form. */
.kg-form .form-control {
    background: #ffffff;
    border-radius: var(--kg-r-pill);
    border-color: var(--kg-rule-control);
    font-size: 13.5px;
    box-shadow: none;
}
.kg-form .form-control:focus,
.kg-form .form-control:focus-within {
    outline: 2px solid var(--kg-accent);
    outline-offset: 1px;
    border-color: transparent;
}
