/* GridKit Core CSS v0.16.0 */

/* Global link reset */
a {
  text-decoration: none;
  color: inherit;
}
a:hover {
  text-decoration: none;
}

/* === M3 COLOR ROLES === */
.gk-root,
[data-gk-theme] {
  /* Key Colors */
  --gk-primary: #6366f1;
  --gk-on-primary: #ffffff;
  --gk-primary-container: #e0e0ff;
  --gk-on-primary-container: #1a1a6b;

  --gk-secondary: #57606a;
  --gk-on-secondary: #ffffff;
  --gk-secondary-container: #eaeef2;
  --gk-on-secondary-container: #24292f;

  --gk-tertiary: #10b981;
  --gk-on-tertiary: #ffffff;
  --gk-tertiary-container: #d1fae5;
  --gk-on-tertiary-container: #064e3b;

  --gk-error: #f43f5e;
  --gk-on-error: #ffffff;
  --gk-error-container: #ffe4e6;
  --gk-on-error-container: #881337;

  /* Surface Roles */
  --gk-surface-dim: #e8edf2;
  --gk-surface: #ffffff;
  --gk-surface-bright: #ffffff;
  --gk-surface-container-lowest: #ffffff;
  --gk-surface-container-low: #f6f8fa;
  --gk-surface-container: #f1f5f9;
  --gk-surface-container-high: #eaeef2;
  --gk-surface-container-highest: #d8dee4;
  --gk-on-surface: #0f172a;
  --gk-on-surface-variant: #475569;
  --gk-outline: #94a3b8;
  --gk-outline-variant: #e2e8f0;

  /* === SEMANTIC ROLES ===
     Success, warning and info deliberately do NOT follow the theme accent: green
     has to stay green, whatever theme is running. (--gk-success used to be wired
     to --gk-tertiary — in the Forest theme that turned success messages purple,
     because Forest sets tertiary to #8b5cf6.) */
  --gk-success: #10b981;
  --gk-on-success: #ffffff;
  --gk-success-container: #d1fae5;
  --gk-on-success-container: #064e3b;

  /* Backward-compat aliases */
  --gk-bg: var(--gk-surface);
  --gk-bg-muted: var(--gk-surface-container);
  --gk-bg-subtle: var(--gk-surface-container-low);
  --gk-bg-hover: var(--gk-surface-container-high);
  --gk-text: var(--gk-on-surface);
  --gk-text-muted: var(--gk-on-surface-variant);
  --gk-text-subtle: var(--gk-outline);
  --gk-border: var(--gk-outline-variant);
  --gk-warning: #f59e0b;
  --gk-danger: var(--gk-error);
  --gk-info: #0ea5e9;

  /* Warning and info had no role pair until now — without a container/on role,
     components (labels, messages, toasts) had to bring their own literals. */
  --gk-on-warning: #ffffff;

  /* White text on the semantic colours themselves does not carry: measured
     2.54:1 on success, 2.15:1 on warning and 3.67:1 on danger. --gk-primary
     already solves this by pinning its lightness; these do the same with a
     darker fill used only where a button is filled. The role colours above stay
     as they are — they are right for pills, borders and icons. */
  --gk-success-fill: #047857;   /* white: 5.48:1 */
  --gk-warning-fill: #b45309;   /* white: 5.02:1 */
  --gk-danger-fill:  #dc2626;   /* white: 4.83:1 */
  --gk-warning-container: #fef3c7;
  --gk-on-warning-container: #92400e;
  --gk-on-info: #ffffff;
  --gk-info-container: #dbeafe;
  --gk-on-info-container: #1e40af;

  /* === STATE ROLES ===
     Hover and active steps are derived from their own role so that they follow the
     theme. The literals here are the fallback for browsers without relative color
     syntax; the @supports block at the end of this file replaces them with the
     derived variant (same chroma, lower lightness). */
  --gk-primary-hover: #4f46e5;
  --gk-tertiary-hover: #059669;
  --gk-error-hover: #e11d48;
  --gk-warning-hover: #d97706;
  /* Legacy hover aliases */
  --gk-success-hover: #059669;
  --gk-danger-hover: var(--gk-error-hover);

  /* State layers (M3) — they lie as a veil over the base surface */
  --gk-state-hover: color-mix(in oklab, var(--gk-on-surface) 6%, transparent);
  --gk-state-pressed: color-mix(in oklab, var(--gk-on-surface) 10%, transparent);
  --gk-state-primary: color-mix(in oklab, var(--gk-primary) 8%, transparent);
  --gk-state-tertiary: color-mix(in oklab, var(--gk-tertiary) 8%, transparent);
  --gk-state-error: color-mix(in oklab, var(--gk-error) 8%, transparent);
  --gk-state-warning: color-mix(in oklab, var(--gk-warning) 8%, transparent);

  /* Text-safe variants of warning and success.
     --gk-warning/--gk-success are surface colors; as a text color on a light
     surface they break the contrast (#f59e0b on white = 2.15:1). These roles
     are the same color, only darker — and stay above the 3:1 threshold. */
  /* Text-safe variants of the semantic roles, for the one case the role colours
     cannot cover: the colour *is* the text, on a plain surface. Measured on
     white — the role colours themselves give 2.15:1 (warning), 2.54:1 (success)
     and 3.67:1 (error), and the earlier one-step-darker values still only
     reached 3.19:1 and 3.77:1. These clear 4.5:1. */
  --gk-warning-text: #b45309;   /* 5.02:1 */
  --gk-success-text: #047857;   /* 5.48:1 */
  --gk-danger-text:  #c81e3a;   /* 5.67:1 */
  /* --gk-primary is pinned at L 0.55 so that white carries on it. As text on a
     white surface the same colour measured 3.97:1 in forest, 4.20:1 in ocean
     and 4.41:1 in slate — under the 4.5:1 body text needs. Same idea as the two
     roles above: one step darker, used only where the colour is the text. */
  --gk-primary-text: #4f46e5;

  /* Focus ring — one promise, the same everywhere */
  --gk-focus-ring: 0 0 0 3px color-mix(in oklab, var(--gk-primary) 32%, transparent);
  --gk-focus-ring-soft: 0 0 0 3px color-mix(in oklab, var(--gk-primary) 10%, transparent);
  --gk-focus-ring-error: 0 0 0 3px color-mix(in oklab, var(--gk-error) 32%, transparent);

  /* Legacy scale aliases (backward compat) */
  --gk-primary-50: #eef2ff;
  --gk-primary-100: #e0e7ff;
  --gk-primary-200: #c7d2fe;
  --gk-primary-300: #a5b4fc;
  --gk-primary-400: #818cf8;
  --gk-primary-500: #6366f1;
  --gk-primary-600: #4f46e5;
  --gk-primary-700: #4338ca;
  --gk-success-50: #ecfdf5;
  --gk-success-100: #d1fae5;
  --gk-success-200: #a7f3d0;
  --gk-success-400: #34d399;
  --gk-success-500: #10b981;
  --gk-success-600: #059669;
  --gk-success-700: #047857;
  --gk-warning-50: #fffbeb;
  --gk-warning-100: #fef3c7;
  --gk-warning-200: #fde68a;
  --gk-warning-400: #fbbf24;
  --gk-warning-500: #f59e0b;
  --gk-warning-600: #d97706;
  --gk-warning-700: #b45309;
  --gk-danger-50: #fff1f2;
  --gk-danger-100: #ffe4e6;
  --gk-danger-200: #fecdd3;
  --gk-danger-400: #fb7185;
  --gk-danger-500: #f43f5e;
  --gk-danger-600: #e11d48;
  --gk-danger-700: #be123c;
  --gk-neutral-50: #f8fafc;
  --gk-neutral-100: #f1f5f9;
  --gk-neutral-200: #e2e8f0;
  --gk-neutral-300: #cbd5e1;
  --gk-neutral-400: #94a3b8;
  --gk-neutral-500: #64748b;
  --gk-neutral-600: #475569;
  --gk-neutral-700: #334155;
  --gk-neutral-800: #1e293b;
  --gk-neutral-900: #0f172a;

  /* Sidebar Colors */
  /* Sidebar – light mode (dark = the dark mode block below) */
  --gk-sidebar-bg: #f1f5f9;
  --gk-sidebar-text: #374151;
  /* #9ca3af measured 2.27:1 on the light sidebar — group labels, the version
     and the collapse label all sat under half the required 4.5:1. */
  --gk-sidebar-text-muted: #5b6472;
  --gk-sidebar-text-hover: #111827;
  --gk-sidebar-item-hover: rgba(0, 0, 0, 0.05);
  --gk-sidebar-item-active: rgba(0, 0, 0, 0.07);
  --gk-sidebar-border: rgba(0, 0, 0, 0.07);
  --gk-sidebar-brand-bg: transparent;
  --gk-sidebar-accent: var(--gk-primary);
  /* Was 2.37:1. Icons need 3:1, but these sit beside the labels above. */
  --gk-sidebar-icon-muted: #5b6472;

  /* Elevation (M3 uses tonal elevation) */
  --gk-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
  --gk-shadow-lg: 0 10px 25px rgba(0, 0, 0, 0.12);
  --gk-radius: 12px;
  --gk-radius-sm: 8px;
  --gk-radius-lg: 16px;

  /* The rhythm of a table, as tokens rather than numbers scattered through the
     rules. The defaults ARE what tables looked like before these existed, so
     nothing moves until a density variant redefines them. */
  --gk-table-pad-y: 12px;
  --gk-table-pad-x: 16px;
  --gk-label-radius: 9999px;

  --gk-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --gk-font-size: 14px;
  --gk-font-size-sm: 12px;

  /* === TYPE SCALE ===
     Seven roles instead of scattered literals. The values match the sizes that
     are predominantly in use today — the scale gives them names, it does not
     move them. */
  --gk-text-display: 32px;
  --gk-text-title: 20px;
  --gk-text-subtitle: 16px;
  --gk-text-body: 14px;
  --gk-text-label: 13px;
  --gk-text-caption: 12px;
  --gk-text-overline: 11px;

  /* Line heights — they belong to the role, not to chance */
  --gk-leading-tight: 1.3;
  --gk-leading-snug: 1.4;
  --gk-leading-normal: 1.55;

  /* === ICON SCALE ===
     Deliberately kept apart from the type scale: Material icons are sized through
     font-size, but they are not type. Before this, both scales sat
     indistinguishably in the same range of numbers. */
  --gk-icon-xs: 16px;
  --gk-icon-sm: 18px;
  --gk-icon-md: 20px;
  --gk-icon-lg: 22px;
  --gk-icon-xl: 24px;
  --gk-icon-2xl: 28px;
  --gk-icon-3xl: 40px;   /* display symbols only, e.g. in the empty state */

  /* === MOTION ===
     Three durations, two curves. No property is animated wholesale through
     "all" any more — that catches width, height and position too, and is the
     most common cause of jittering layouts. */
  --gk-dur-1: 120ms;   /* state in place: hover, focus, selection */
  --gk-dur-2: 200ms;   /* appearing and disappearing: dropdown, tooltip, toast */
  --gk-dur-3: 320ms;   /* movement through space: modal, drawer, sidebar */
  --gk-ease-out: cubic-bezier(0.2, 0, 0, 1);
  --gk-ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
  /* Ready-made bundles for the two common cases. They name the properties
     explicitly so that width or position is never animated along again. */
  --gk-transition-state:
    background-color var(--gk-dur-1) var(--gk-ease-out),
    border-color var(--gk-dur-1) var(--gk-ease-out),
    color var(--gk-dur-1) var(--gk-ease-out),
    box-shadow var(--gk-dur-1) var(--gk-ease-out),
    opacity var(--gk-dur-1) var(--gk-ease-out);
  --gk-transition-move:
    transform var(--gk-dur-2) var(--gk-ease-out),
    opacity var(--gk-dur-2) var(--gk-ease-out);

  /* === ELEVATION ===
     Four steps, each two-layered: a tight contact shadow for the edge, a soft
     spread for the distance. A single-layer shadow looks glued on. */
  --gk-elev-1: 0 1px 2px rgba(15, 23, 42, 0.06), 0 1px 3px rgba(15, 23, 42, 0.10);
  --gk-elev-2: 0 2px 4px rgba(15, 23, 42, 0.06), 0 4px 12px rgba(15, 23, 42, 0.08);
  --gk-elev-3: 0 4px 8px rgba(15, 23, 42, 0.08), 0 16px 32px rgba(15, 23, 42, 0.12);
  --gk-elev-4: 0 8px 16px rgba(15, 23, 42, 0.10), 0 24px 48px rgba(15, 23, 42, 0.16);
  --gk-spacing: 16px;
  --gk-content-max-width: 1600px;
  font-family: var(--gk-font);
  font-size: var(--gk-font-size);
  color: var(--gk-text);
  box-sizing: border-box;
}
.gk-root *,
.gk-root *::before,
.gk-root *::after {
  box-sizing: border-box;
}
.gk-root {
  background-color: var(--gk-surface-container);
  color: var(--gk-on-surface);
  min-height: 100vh;
}

/* Present to a screen reader, absent on screen. Used to name things that are
   obvious to the eye and invisible to everything else — the header above a
   column of row buttons, for instance, which is empty by design but leaves the
   cells under it unassociated. clip-path rather than display:none, which would
   remove it from the accessibility tree as well and defeat the purpose. */
.gk-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* === TABLE === */
.gk-table-wrap {
  /* A table must never widen the space it was given. Without these two lines
     a table's min-content width blows out every flex or grid track that is
     defined as 1fr instead of minmax(0, 1fr) — and pushes the whole page
     sideways. Only the container is allowed to scroll sideways. */
  min-width: 0;
  max-width: 100%;
  background: var(--gk-surface);
  border: 1px solid var(--gk-outline-variant);
  border-radius: 12px;
  /* overflow: visible so that dropdowns (gk-select-search, status filter etc.)
     from the toolbar can render past the table border. Rounded corners come
     from gk-table-scroll (in case it is scrolled horizontally). */
  overflow: visible;
}
/* When horizontal scrolling is needed: inside a gk-table-scroll container */
.gk-table-scroll {
  overflow-x: auto;
  max-width: 100%;
  border-radius: inherit;
}
.gk-table-scroll > .gk-table {
  width: 100%;
}
/* Cells may become narrower than their content — otherwise a long second
   line (subject, account, no.) blows out the whole table. */
.gk-table-scroll td {
  overflow: hidden;
  min-width: 0;
}
/* Second line inside a cell: truncates with an ellipsis, does not widen the column. */
.gk-cell-sub {
  display: block;
  font-size: var(--gk-text-overline);
  line-height: 1.3;
  color: var(--gk-text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.gk-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  padding: var(--gk-spacing);
  gap: 8px;
  border-bottom: 1px solid var(--gk-border);
}
.gk-toolbar-spacer {
  flex: 1;
}
/* Two-row toolbar: search alone in row 1, all filters in row 2.
   Usage:
     <div class="gk-toolbar gk-toolbar-stacked">
       <div class="gk-toolbar-row gk-toolbar-row-search">
         <input class="gk-search">
       </div>
       <div class="gk-toolbar-row gk-toolbar-row-filters">
         <select class="gk-filter">…</select>
         …
         <div class="gk-toolbar-spacer"></div>
         <button class="gk-btn-text">Reset</button>
       </div>
     </div>
*/
.gk-toolbar.gk-toolbar-stacked {
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
}
.gk-toolbar-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.gk-toolbar-row-search .gk-search {
  flex: 1 1 auto;
  min-width: 240px;
}
.gk-toolbar-row-filters > .gk-filter,
.gk-toolbar-row-filters > .gk-select-search {
  flex: 0 0 auto;
}
/* Toolbar buttons are always pills — consistent with the search bar */
.gk-toolbar .gk-btn-filled,
.gk-toolbar .gk-btn-outlined,
.gk-toolbar .gk-btn-tonal {
  border-radius: 9999px;
}
.gk-toolbar .gk-search {
  margin-right: 4px;
}
/* The value carrier of a searchable select. It used to be type="hidden",
   which the HTML standard bars from constraint validation — so ['required']
   was accepted, emitted, and silently did nothing: the form submitted empty.
   It must stay a real, focusable control for the browser to anchor its
   validation bubble, so it is hidden by opacity rather than display:none, and
   readonly is deliberately absent (readonly also disables validation).

   1.42.0 spliced this block between the selector and the brace of the toolbar
   rule below. Two things broke at once: the carrier was only hidden inside a
   toolbar — a visible 177px text input in every plain form — and the toolbar's
   34px height escaped onto every searchable select on every page. */
.gk-select-value-input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    padding: 0;
    border: 0;
    pointer-events: none;
}

/* Align gk-select-search in a toolbar with gk-search / gk-filter (otherwise 44px instead of ~34px) */
.gk-toolbar .gk-select-search .gk-select-display {
  padding: 6px 12px;
  height: 34px;        /* override the generic height:44px from .gk-select-display */
  min-height: 34px;
  line-height: 1.4;
  border-radius: var(--gk-radius-sm);
}
.gk-toolbar .gk-select-search .gk-select-arrow {
  font-size: var(--gk-icon-sm);
}

/* ── GridKit\TableHeader — unified filter and search bar ── */
.gk-tableheader {
  display: flex;
  flex-direction: column;
}
.gk-tableheader-status {
  padding: 12px 12px 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}
.gk-tableheader-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--gk-border);
}
.gk-tableheader-toolbar .gk-search {
  flex: 1 1 240px;
  min-width: 200px;
}
.gk-tableheader-toolbar .gk-filter,
.gk-tableheader-toolbar select.gk-filter,
.gk-tableheader-toolbar input.gk-filter {
  flex: 0 0 auto;
}
.gk-tableheader-spacer {
  flex: 1;
}
.gk-tableheader-advanced {
  border-bottom: 1px solid var(--gk-border);
}
.gk-tableheader-advanced > summary {
  cursor: pointer;
  user-select: none;
  font-size: var(--gk-text-label);
  color: var(--gk-primary, #5a4eff);
  font-weight: 500;
  padding: 8px 16px;
  list-style: none;
}
.gk-tableheader-advanced > summary::before {
  content: '+ ';
  font-weight: 600;
}
.gk-tableheader-advanced[open] > summary::before {
  content: '− ';
}
.gk-tableheader-advanced > summary::-webkit-details-marker {
  display: none;
}
.gk-tableheader-advanced-body {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 8px 16px 12px;
}
.gk-search {
  padding: 8px 12px 8px 36px;
  border: 1.5px solid var(--gk-border);
  border-radius: 9999px;
  font-size: var(--gk-font-size);
  outline: none;
  min-width: 200px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='M21 21l-4.35-4.35'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 12px center;
  transition:
    border-color 0.15s,
    box-shadow 0.15s;
}
.gk-search:focus-visible {
  border-color: var(--gk-primary);
  box-shadow: var(--gk-focus-ring);
  outline: none;
}

/* Filters */
.gk-filter {
  padding: 7px 32px 7px 12px;
  border: 1px solid var(--gk-border);
  border-radius: var(--gk-radius-sm);
  font-size: var(--gk-font-size);
  font-family: var(--gk-font);
  background: var(--gk-bg);
  color: var(--gk-text);
  outline: none;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  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='%236b7280' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  transition:
    border-color 0.15s,
    box-shadow 0.15s;
}
.gk-filter:hover {
  border-color: var(--gk-text-muted);
}
.gk-filter:focus-visible {
  border-color: var(--gk-primary);
  box-shadow: var(--gk-focus-ring);
  outline: none;
}
.gk-filter option {
  padding: 4px 8px;
}

/* PageSize — rows-per-page dropdown */
.gk-pagesize {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--gk-font-size-sm, 13px);
  color: var(--gk-text-muted);
  white-space: nowrap;
}
.gk-pagesize-text {
  font-size: var(--gk-font-size-sm, 13px);
}
.gk-pagesize-select {
  padding-top: 5px;
  padding-bottom: 5px;
}

/* Tabs */
.gk-tabs-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  border-bottom: 1px solid var(--gk-border);
  margin-bottom: 16px;
}
.gk-tab {
  appearance: none;
  border: 0;
  background: transparent;
  padding: 9px 16px;
  font-size: var(--gk-text-body);
  font-weight: 600;
  color: var(--gk-text-muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  border-radius: 8px 8px 0 0;
}
.gk-tab:hover { color: var(--gk-text); background: var(--gk-surface-variant, #f1f5f9); }
.gk-tab-active { color: var(--gk-primary); border-bottom-color: var(--gk-primary); }

/* RowPager (client-side table pagination) */
.gk-rowpager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  /* Horizontal inner spacing so that the counter "1–15 von 33" and the arrows do not
     stick to the container/card edge (the pager sits as a sibling below .gk-table-wrap). */
  margin: 10px 0 6px;
  padding: 0 12px;
}
.gk-rowpager-info {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  font-size: var(--gk-text-label);
  color: var(--gk-text-muted);
}
.gk-rowpager-count { white-space: nowrap; }
.gk-rowpager-info .gk-pagesize { color: inherit; }
.gk-rowpager-nav { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.gk-pg {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 34px; height: 34px; padding: 0 10px;
  border: 1px solid var(--gk-border); border-radius: 8px;
  background: var(--gk-surface); color: var(--gk-text); font-size: 13px; font-weight: 600;
  cursor: pointer; text-decoration: none;
}
.gk-pg:hover { background: var(--gk-surface-variant, #f1f5f9); }
/* color was a hardcoded #fff. In dark mode --gk-primary is the *light* end of
   the scale (L 0.80), so white on white measured 1.8:1 across every theme. The
   role colour flips with the mode; the literal did not. */
.gk-pg-active { background: var(--gk-primary); border-color: var(--gk-primary); color: var(--gk-on-primary); cursor: default; }
.gk-pg-icon { padding: 0; }
.gk-pg-icon .material-icons { font-size: 18px; }
.gk-pg-off { opacity: .4; pointer-events: none; }
.gk-pg-gap { padding: 0 4px; color: var(--gk-text-muted); }

.gk-table {
  width: 100%;
  border-collapse: collapse;
}
.gk-table th,
.gk-table td {
  padding: var(--gk-table-pad-y) var(--gk-table-pad-x);
  text-align: left;
  border-bottom: 1px solid var(--gk-outline-variant);
  /* Digits on a fixed width, so figures and dates line up down the column
     instead of drifting a little in every row. Only digits are affected —
     prose in the same cell keeps its normal spacing. */
  font-variant-numeric: tabular-nums;
}
.gk-table thead th {
  /* No surface of its own. Caps, size and weight already make the header row
     unmistakably readable as a header — a grey bar underneath it is a second
     announcement of the same thing and makes the card restless. The line below
     it does the separating on its own.
     For that it has to be visible: with the same hairline as between the rows,
     the header floated among them. One step darker, and the head reads as the
     head — in both modes, the token carries its own dark value. */
  border-bottom-color: var(--gk-surface-container-highest);
  font-weight: 600;
  font-size: var(--gk-text-overline);
  color: var(--gk-on-surface-variant);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  user-select: none;
  white-space: nowrap;
}
/* Zebra/hover background on the CELL (td), not the row (tr): only that way does
   the border-radius of the corner cells clip the background. Otherwise a grey
   last row juts out as a square block over the rounded wrap corners — visible
   only when the last row is grey (a white one blends into the white wrap). */
/* One separator system instead of three. Zebra fill, row rule AND card border
   used to separate at the same time — one of them is enough. The hairline stays,
   the zebra fill goes; whoever needs it takes .gk-table-striped.
   That leaves the hover fill carrying alone, and it reads clearly for the first time. */
.gk-table tbody tr:hover > td,
.gk-table tbody tr:focus-within > td {
  background: var(--gk-surface-container-low);
}
/* The row being touched gets an edge in primary — the same language the
   sidebar uses to mark its active entry. */
.gk-table tbody tr:hover > td:first-child,
.gk-table tbody tr:focus-within > td:first-child {
  box-shadow: inset 2px 0 0 var(--gk-primary);
}
/* Last VISIBLE row without a separator line. With a tfoot the tfoot row is the last
   one (the tbody row then keeps its line as the separator before the total); without
   a tfoot it is the last tbody row. Otherwise a 1px line clings just above the round
   wrap edge ("loose line" under the totals row). */
.gk-table tbody:last-child tr:last-child > td,
.gk-table tfoot tr:last-child > td,
.gk-table tfoot tr:last-child > th {
  border-bottom: none;
}
/* Rounded corners when the table sits directly in gk-table-wrap (with no toolbar before it) */
.gk-table-wrap > .gk-table thead tr:first-child th:first-child {
  border-radius: 11px 0 0 0;
}
.gk-table-wrap > .gk-table thead tr:first-child th:last-child {
  border-radius: 0 11px 0 0;
}
/* Bottom corners: descendant selector (not '>'), so the rounding also takes effect
   when the table sits in a live container (e.g. #inv-live) instead of directly in
   the gk-table-wrap. The last row is always the bottom of the card. */
.gk-table-wrap .gk-table tbody tr:last-child td:first-child {
  border-radius: 0 0 0 11px;
}
.gk-table-wrap .gk-table tbody tr:last-child td:last-child {
  border-radius: 0 0 11px 0;
}
/* If a tfoot row (e.g. a totals row) is present, THAT is the last row. */
.gk-table-wrap .gk-table tfoot tr:last-child td:first-child {
  border-radius: 0 0 0 11px;
}
.gk-table-wrap .gk-table tfoot tr:last-child td:last-child {
  border-radius: 0 0 11px 0;
}

/* When a gk-table-wrap sits INSIDE a card it keeps its ROUND look
   (radius 12px) — consistent with standalone tables. Only the shadow goes (the
   card already supplies it) and the border stays the subtle hairline it inherits. The corner shimmer that
   used to make this a problem is gone since the background-on-cell fix (v1.22.9).
   overflow is left untouched (toolbar dropdowns). */
.gk-card .gk-table-wrap {
  box-shadow: none;
}

/* Section title ABOVE a standalone gk-table-wrap. For pages with several
   tables that each need a heading — WITHOUT packing the table into a second
   card (no double border, no wasted padding). The gk-table-wrap stays the
   "closed" card; the title sits above it without a frame. */
.gk-table-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 8px;
  padding: 0 2px;
  font-size: 15px;
  font-weight: 600;
  color: var(--gk-on-surface);
}
.gk-table-title > .material-icons {
  font-size: var(--gk-icon-md);
  flex: 0 0 auto;
  color: var(--gk-on-surface-variant);
}
.gk-table-title h3 {
  margin: 0;
  font-size: inherit;
  font-weight: inherit;
  min-width: 0;
}
.gk-table-title small {
  font-weight: 400;
  font-size: var(--gk-text-label);
  color: var(--gk-on-surface-variant);
}
/* right-aligned actions/links in the title row */
.gk-table-title-actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 6px;
}
/* Spacing between stacked table sections */
.gk-table-section + .gk-table-section,
.gk-table-title:not(:first-child) {
  margin-top: 18px;
}

/* ── gk-table-card: title + table as ONE closed card ──
   Wraps a gk-table-title (becomes the card header) + a gk-table-wrap (table
   flush inside it). The card supplies border/radius/shadow — the table fills it
   edge to edge, no double border, no wasted padding, clean corners
   (overflow clip). For pages with several tables that should appear as cards
   belonging together.
   Note: overflow:hidden clips our own JS dropdowns (gk-select-search) — do NOT
   put such tables in a card. Native <select> is uncritical (OS popup). */
.gk-table-card {
  background: var(--gk-surface, #fff);
  border: 1px solid var(--gk-outline-variant, #d0d7de);
  border-radius: 12px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .07), 0 1px 2px rgba(0, 0, 0, .04);
  overflow: hidden;
}
.gk-table-card > .gk-table-title {
  margin: 0;
  padding: 14px 16px;
  border-bottom: 1px solid var(--gk-outline-variant, #eef0f3);
}
.gk-table-card .gk-table-wrap {
  border: none;
  border-radius: 0;
  box-shadow: none;
  background: transparent;
}
/* Spacing between stacked cards */
.gk-table-card + .gk-table-card {
  margin-top: 16px;
}

/* Nowrap */
.gk-table td.gk-nowrap,
.gk-table th.gk-nowrap {
  white-space: nowrap;
}
.gk-table.gk-table-nowrap td {
  white-space: nowrap;
}

.gk-sortable {
  cursor: pointer;
}

/* The clickable part of a sortable header is a real <button> inside the <th>,
   so the header keeps its columnheader role and its aria-sort. This strips the
   button back to looking like the header text it replaced — inheriting the
   font, colour, alignment and letter-spacing the th already had. */
.gk-sort-btn {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  text-align: inherit;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  width: 100%;
}
.gk-sort-btn:focus-visible {
  outline: 2px solid var(--gk-primary);
  outline-offset: 2px;
  border-radius: 2px;
}

/* The arrow rides on the button, not on the th: on the th it sat outside the
   control, so the one part of the header that looks most like "click me to
   sort" was the one part that did nothing. */
.gk-sortable .gk-sort-btn::after {
  content: "⇅";
  margin-left: 4px;
  opacity: 0.3;
  font-size: var(--gk-text-overline);
}
.gk-sorted-asc .gk-sort-btn::after {
  content: "↑";
  opacity: 0.7;
}
.gk-sorted-desc .gk-sort-btn::after {
  content: "↓";
  opacity: 0.7;
}
/* Header with a Material icon indicator (gk-sort-icon) — suppress the ::after text
   arrow, otherwise there are two indicators. Unifies GK.table with SortLink. */
.gk-sortable-mi .gk-sort-btn::after { content: none !important; }

/* Inline sort icon for custom sort headers (e.g. via material-icons).
   Usage: <a class="gk-sort-link"><span class="material-icons gk-sort-icon">unfold_more</span></a>
   Otherwise material-icons would blow up the table header row with its default size of 24px. */
.gk-sort-icon {
  font-size: 14px !important;
  vertical-align: -3px;
  margin-left: 2px;
  opacity: 0.4;
  transition: opacity var(--gk-dur-1);
}
.gk-sort-link {
  color: inherit;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 2px;
}
.gk-sort-link:hover .gk-sort-icon {
  opacity: 0.7;
}
.gk-sort-icon.is-active {
  opacity: 0.85;
  color: var(--gk-primary);
}


/* Group row in a table (Table::groupBy) */
.gk-table tbody tr.gk-table-group > td {
  padding: 10px 12px 6px;
  background: var(--gk-surface-container);
  border-bottom: 1px solid var(--gk-outline-variant, #e2e8f0);
  font-size: var(--gk-text-caption);
  letter-spacing: 0.02em;
}
.gk-table tbody tr.gk-table-group:hover > td {
  background: var(--gk-surface-container);
}
.gk-table-group-name {
  font-weight: 700;
  color: var(--gk-on-surface, #0f172a);
}
.gk-table-group-n {
  margin-left: 8px;
  color: var(--gk-on-surface-variant);
  font-weight: 500;
}

/* Count and identifier columns */
.gk-td-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.gk-num { font-weight: 600; }
.gk-num-empty {
  font-weight: 400;
  color: var(--gk-text-muted, #cbd5e1);
}
.gk-code {
  display: inline-block;
  min-width: 3.2rem;
  margin-right: 10px;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

[data-gk-mode="dark"] .gk-table tbody tr.gk-table-group > td,
.gk-dark .gk-table tbody tr.gk-table-group > td {
  background: var(--gk-surface-container, #1e293b);
}
[data-gk-mode="dark"] .gk-num-empty,
.gk-dark .gk-num-empty {
  color: var(--gk-outline);
}
.gk-actions {
  white-space: nowrap;
}
.gk-actions-left {
  text-align: left;
}
.gk-actions-right {
  text-align: right;
}
.gk-actions-col {
  width: 1%;
}

/* ── Multi-Select ─────────────────────────────────────────────────────── */
.gk-cb-col {
  width: 36px;
  padding: 0 10px !important;
}
.gk-cb-col input[type="checkbox"] {
  width: 16px;
  height: 16px;
  cursor: pointer;
  accent-color: var(--gk-primary);
  vertical-align: middle;
}
.gk-table tr.gk-row-selected {
  background: color-mix(in srgb, var(--gk-primary) 6%, transparent);
}
/* Selectable table: only the checkbox cell gets the pointer cursor.
   (Up to v1.10.1 it was the whole row — but that confuses, because then every
   unintended click makes the bulk action bar pop up.) */
[data-gk-selectable] tbody tr[data-gk-row-id] td.gk-cb-col {
  cursor: pointer;
}
.gk-bulk-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--gk-primary);
  color: var(--gk-on-primary);
  border-radius: 10px;
  padding: 10px 16px;
  margin: 6px 0 2px;
  font-size: var(--gk-text-label);
  font-weight: 500;
}
.gk-bulk-bar .gk-toolbar-spacer {
  flex: 1;
}
.gk-bulk-bar .material-icons {
  font-size: var(--gk-icon-sm);
}
.gk-bulk-bar [data-gk-bulk-delete] {
  background: var(--gk-error);
  color: var(--gk-on-error);
  border: none;
  border-radius: 7px;
  padding: 0 14px;
  height: 32px;
  font-size: var(--gk-text-caption);
  font-weight: 600;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.gk-bulk-bar [data-gk-bulk-delete]:hover {
  background: var(--gk-error-hover);
}
.gk-bulk-bar [data-gk-bulk-delete] .material-icons {
  font-size: 15px;
}
.gk-bulk-bar [data-gk-bulk-cancel] {
  background: rgba(255, 255, 255, 0.15);
  color: var(--gk-on-primary);
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 7px;
  padding: 0 14px;
  height: 32px;
  font-size: var(--gk-text-caption);
  font-weight: 500;
  cursor: pointer;
}
.gk-bulk-bar [data-gk-bulk-cancel]:hover {
  background: rgba(255, 255, 255, 0.25);
}
/* Button Group — base: no border, no background */
.gk-btn-group {
  display: inline-flex;
  border-radius: 10px;
  overflow: hidden;
}
.gk-btn-group .gk-btn {
  border-radius: 0;
  margin: 0;
  border-right-width: 0;
  border-color: transparent;
}
.gk-btn-group .gk-btn:first-child {
  border-radius: 10px 0 0 10px;
}
.gk-btn-group .gk-btn:last-child {
  border-radius: 0 10px 10px 0;
  border-right-width: 0;
}
.gk-btn-group .gk-btn:only-child {
  border-radius: 10px;
}
/* Bordered variant — explicit opt-in */
.gk-btn-group-bordered {
  box-shadow: var(--gk-elev-1);
  border: 1px solid var(--gk-outline-variant, #e5e7eb);
}
.gk-btn-group-bordered .gk-btn:not(:last-child) {
  border-right: 1px solid var(--gk-outline-variant, #e5e7eb);
}
.gk-btn-icon-text {
  gap: 5px;
}
.gk-btn-icon-text svg {
  flex-shrink: 0;
}

/* === BUTTONS === */
/* Base */
.gk-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 16px;
  border: 1.5px solid transparent;
  border-radius: 8px;
  font-size: var(--gk-text-body);
  font-weight: 500;
  cursor: pointer;
  transition: var(--gk-transition-state);
  line-height: 1.4;
  text-decoration: none;
  white-space: nowrap;
  position: relative;
  font-family: inherit;
}
.gk-btn:focus-visible {
  outline: 2px solid var(--gk-primary, #6366f1);
  outline-offset: 2px;
}

/* Sizes */
.gk-btn-sm {
  padding: 4px 12px;
  font-size: var(--gk-text-caption);
  border-radius: 6px;
  gap: 4px;
}
.gk-btn-lg {
  padding: 12px 24px;
  font-size: var(--gk-text-subtitle);
  border-radius: 10px;
  gap: 8px;
}
.gk-btn-icon-only {
  padding: 8px;
}
.gk-btn-icon-only.gk-btn-sm {
  padding: 4px;
}
.gk-btn-icon-only.gk-btn-lg {
  padding: 12px;
}
.gk-btn-full {
  width: 100%;
}

/* --- Variant: Filled --- */
.gk-btn-filled.gk-btn-primary {
  background: var(--gk-primary);
  color: var(--gk-on-primary);
  border-color: var(--gk-primary);
}
.gk-btn-filled.gk-btn-primary:hover {
  background: var(--gk-primary-hover);
  border-color: var(--gk-primary-hover);
  box-shadow: 0 1px 3px color-mix(in oklab, var(--gk-primary) 30%, transparent);
}
.gk-btn-filled.gk-btn-success {
  background: var(--gk-success-fill);
  color: #ffffff;
  border-color: var(--gk-success-fill);
}
.gk-btn-filled.gk-btn-success:hover {
  background: var(--gk-success-hover);
  border-color: var(--gk-success-hover);
  box-shadow: 0 1px 3px color-mix(in oklab, var(--gk-success) 30%, transparent);
}
.gk-btn-filled.gk-btn-warning {
  background: var(--gk-warning-fill);
  color: #ffffff;
  border-color: var(--gk-warning-fill);
}
.gk-btn-filled.gk-btn-warning:hover {
  background: var(--gk-warning-hover);
  border-color: var(--gk-warning-hover);
}
.gk-btn-filled.gk-btn-danger {
  background: var(--gk-danger-fill);
  color: #ffffff;
  border-color: var(--gk-danger-fill);
}
.gk-btn-filled.gk-btn-danger:hover {
  background: var(--gk-error-hover);
  border-color: var(--gk-error-hover);
  box-shadow: 0 1px 3px color-mix(in oklab, var(--gk-error) 30%, transparent);
}
.gk-btn-filled.gk-btn-neutral {
  background: var(--gk-secondary);
  color: var(--gk-on-secondary);
  border-color: var(--gk-secondary);
}
.gk-btn-filled.gk-btn-neutral:hover {
  background: oklch(from var(--gk-secondary) calc(l - 0.06) c h);
  border-color: oklch(from var(--gk-secondary) calc(l - 0.06) c h);
}

/* --- Variant: Outlined --- */
.gk-btn-outlined {
  background: transparent;
}
.gk-btn-outlined.gk-btn-primary {
  color: var(--gk-primary-text);
  border-color: var(--gk-primary);
}
.gk-btn-outlined.gk-btn-primary:hover {
  background: var(--gk-state-primary);
}
.gk-btn-outlined.gk-btn-success {
  color: var(--gk-success-text);
  border-color: var(--gk-success);
}
.gk-btn-outlined.gk-btn-success:hover {
  background: color-mix(in oklab, var(--gk-success) 8%, transparent);
}
.gk-btn-outlined.gk-btn-warning {
  color: var(--gk-warning-text);
  border-color: var(--gk-warning-text);
}
.gk-btn-outlined.gk-btn-warning:hover {
  background: var(--gk-state-warning);
}
.gk-btn-outlined.gk-btn-danger {
  color: var(--gk-danger-text);
  border-color: var(--gk-error);
}
.gk-btn-outlined.gk-btn-danger:hover {
  background: var(--gk-state-error);
}
.gk-btn-outlined.gk-btn-neutral {
  color: var(--gk-on-surface-variant);
  border-color: #d1d5db;
}
.gk-btn-outlined.gk-btn-neutral:hover {
  background: var(--gk-state-hover);
}

/* --- Variant: Text (no border) --- */
.gk-btn-text {
  background: transparent;
  border-color: transparent;
}
.gk-btn-text.gk-btn-primary {
  color: var(--gk-primary-text);
}
.gk-btn-text.gk-btn-primary:hover {
  background: var(--gk-state-primary);
}
.gk-btn-text.gk-btn-success {
  color: var(--gk-success-text);
}
.gk-btn-text.gk-btn-success:hover {
  background: color-mix(in oklab, var(--gk-success) 8%, transparent);
}
.gk-btn-text.gk-btn-warning {
  color: var(--gk-warning-text);
}
.gk-btn-text.gk-btn-warning:hover {
  background: var(--gk-state-warning);
}
.gk-btn-text.gk-btn-danger {
  color: var(--gk-danger-text);
}
.gk-btn-text.gk-btn-danger:hover {
  background: var(--gk-state-error);
}
.gk-btn-text.gk-btn-neutral {
  color: var(--gk-on-surface-variant);
}
.gk-btn-text.gk-btn-neutral:hover {
  background: var(--gk-state-hover);
  color: var(--gk-on-surface);
}

/* --- Variant: Tonal (soft fill) --- */
.gk-btn-tonal.gk-btn-primary {
  background: var(--gk-primary-container);
  color: var(--gk-on-primary-container);
  border-color: transparent;
}
.gk-btn-tonal.gk-btn-primary:hover {
  background: color-mix(in oklab, var(--gk-on-primary-container) 8%, var(--gk-primary-container));
}
.gk-btn-tonal.gk-btn-success {
  background: var(--gk-success-container);
  color: var(--gk-on-success-container);
  border-color: transparent;
}
.gk-btn-tonal.gk-btn-success:hover {
  background: color-mix(in oklab, var(--gk-on-success-container) 8%, var(--gk-success-container));
}
.gk-btn-tonal.gk-btn-warning {
  background: color-mix(in oklab, var(--gk-warning) 10%, transparent);
  color: var(--gk-on-warning-container);
  border-color: transparent;
}
.gk-btn-tonal.gk-btn-warning:hover {
  background: color-mix(in oklab, var(--gk-warning) 18%, transparent);
}
.gk-btn-tonal.gk-btn-danger {
  background: var(--gk-error-container);
  color: var(--gk-on-error-container);
  border-color: transparent;
}
.gk-btn-tonal.gk-btn-danger:hover {
  background: color-mix(in oklab, var(--gk-on-error-container) 8%, var(--gk-error-container));
}
.gk-btn-tonal.gk-btn-neutral {
  background: var(--gk-surface-container);
  color: var(--gk-on-surface);
  border-color: transparent;
}
.gk-btn-tonal.gk-btn-neutral:hover {
  background: var(--gk-surface-container-high);
}

/* --- States --- */
.gk-btn.disabled,
.gk-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}
.gk-btn-loading {
  pointer-events: none;
}
.gk-btn-spinner {
  display: inline-block;
  width: 16px;
  height: 16px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: gk-spin 0.6s linear infinite;
}
@keyframes gk-spin {
  to {
    transform: rotate(360deg);
  }
}
.gk-btn-badge {
  font-size: 10px;
  font-weight: 700;
  background: var(--gk-error);
  color: var(--gk-on-error);
  min-width: 18px;
  height: 18px;
  border-radius: 9px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 5px;
  margin-left: 2px;
}

/* Default variant: no variant class = filled */
.gk-btn.gk-btn-primary:not(.gk-btn-outlined):not(.gk-btn-text):not(
    .gk-btn-tonal
  ) {
  background: var(--gk-primary);
  color: var(--gk-on-primary);
  border-color: var(--gk-primary);
}
.gk-btn.gk-btn-primary:not(.gk-btn-outlined):not(.gk-btn-text):not(
    .gk-btn-tonal
  ):hover {
  background: var(--gk-primary-hover);
  border-color: var(--gk-primary-hover);
}
.gk-btn.gk-btn-success:not(.gk-btn-outlined):not(.gk-btn-text):not(
    .gk-btn-tonal
  ) {
    background: var(--gk-success-fill);
    color: #ffffff;
    border-color: var(--gk-success-fill);
}
.gk-btn.gk-btn-success:not(.gk-btn-outlined):not(.gk-btn-text):not(
    .gk-btn-tonal
  ):hover {
  background: var(--gk-success-hover);
  border-color: var(--gk-success-hover);
}
.gk-btn.gk-btn-warning:not(.gk-btn-outlined):not(.gk-btn-text):not(
    .gk-btn-tonal
  ) {
    background: var(--gk-warning-fill);
    color: #ffffff;
    border-color: var(--gk-warning-fill);
}
.gk-btn.gk-btn-warning:not(.gk-btn-outlined):not(.gk-btn-text):not(
    .gk-btn-tonal
  ):hover {
  background: var(--gk-warning-hover);
  border-color: var(--gk-warning-hover);
}
.gk-btn.gk-btn-danger:not(.gk-btn-outlined):not(.gk-btn-text):not(
    .gk-btn-tonal
  ) {
    background: var(--gk-danger-fill);
    color: #ffffff;
    border-color: var(--gk-danger-fill);
}
.gk-btn.gk-btn-danger:not(.gk-btn-outlined):not(.gk-btn-text):not(
    .gk-btn-tonal
  ):hover {
  background: var(--gk-error-hover);
  border-color: var(--gk-error-hover);
}
.gk-btn.gk-btn-neutral:not(.gk-btn-outlined):not(.gk-btn-text):not(
    .gk-btn-tonal
  ) {
  background: var(--gk-secondary);
  color: var(--gk-on-secondary);
  border-color: var(--gk-secondary);
}
.gk-btn.gk-btn-neutral:not(.gk-btn-outlined):not(.gk-btn-text):not(
    .gk-btn-tonal
  ):hover {
  background: color-mix(in oklab, var(--gk-on-surface) 18%, var(--gk-secondary));
  border-color: color-mix(in oklab, var(--gk-on-surface) 18%, var(--gk-secondary));
}

/* --- Shapes --- */
.gk-btn-pill {
  border-radius: 9999px;
}
.gk-btn-pill.gk-btn-sm {
  border-radius: 9999px;
}
.gk-btn-pill.gk-btn-lg {
  border-radius: 9999px;
}
.gk-btn-circle {
  border-radius: 50%;
  width: 40px;
  height: 40px;
  padding: 0;
}
.gk-btn-circle.gk-btn-lg {
  width: 56px;
  height: 56px;
}
.gk-btn-circle.gk-btn-sm {
  width: 32px;
  height: 32px;
}
.gk-btn-square {
  border-radius: 4px;
}
.gk-btn-square.gk-btn-sm {
  border-radius: 3px;
}
.gk-btn-square.gk-btn-lg {
  border-radius: 6px;
}

/* --- FAB (Floating Action Button) --- */
.gk-fab {
  border-radius: 16px;
  width: 56px;
  height: 56px;
  padding: 0;
  box-shadow:
    0 3px 5px -1px rgba(0, 0, 0, 0.1),
    0 6px 10px rgba(0, 0, 0, 0.07);
}
.gk-fab:hover {
  box-shadow:
    0 5px 8px -2px rgba(0, 0, 0, 0.12),
    0 8px 16px rgba(0, 0, 0, 0.1);
}
.gk-fab-sm {
  width: 40px;
  height: 40px;
  border-radius: 12px;
}
.gk-fab-lg {
  width: 96px;
  height: 96px;
  border-radius: 28px;
}
.gk-fab-lg .material-icons {
  font-size: 36px !important;
}
.gk-fab-extended {
  width: auto;
  height: auto;
  padding: 16px 24px;
  border-radius: 9999px;
  gap: 8px;
}
.gk-fab-extended.gk-fab-sm {
  padding: 10px 18px;
}
.gk-fab-extended.gk-fab-lg {
  padding: 20px 32px;
  font-size: var(--gk-icon-sm);
}

/* Icon-only in tables (small) */
.gk-btn-icon {
  padding: 5px 7px;
}
.gk-btn-icon svg {
  display: block;
}

/* === PAGINATION === */
.gk-table-footer td {
  padding: 8px 12px;
  font-size: var(--gk-text-caption);
  color: var(--gk-on-surface-variant);
  border-top: 1px solid var(--gk-border);
  background: var(--gk-surface-variant, rgba(0,0,0,.02));
}
td.gk-table-meta {
  font-size: var(--gk-text-overline);
  opacity: 0.5;
  text-align: right;
  font-weight: 400;
}
.gk-pagination {
  display: flex;
  gap: 4px;
  padding: var(--gk-spacing);
  justify-content: center;
  border-top: 1px solid var(--gk-border);
}
.gk-page-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 32px;
  height: 32px;
  padding: 0 4px;
  border: 1px solid var(--gk-border);
  border-radius: 9999px;
  background: var(--gk-bg);
  cursor: pointer;
  font-size: var(--gk-font-size-sm);
  text-decoration: none;
  color: var(--gk-on-surface);
  transition: var(--gk-transition-state);
}
.gk-page-btn:hover {
  background: var(--gk-bg-hover);
}
.gk-page-btn.gk-active {
  background: var(--gk-primary-container);
  color: var(--gk-on-primary-container);
  border-color: transparent;
  font-weight: 600;
}

/* === LABELS === */
.gk-label {
  display: inline-block;
  padding: 2px 8px;
  border-radius: var(--gk-label-radius);
  font-size: var(--gk-font-size-sm);
  font-weight: 500;
  white-space: nowrap;
  vertical-align: middle;
}
.gk-label-green {
  background: var(--gk-success-container);
  color: var(--gk-on-success-container);
}
.gk-label-orange {
  background: var(--gk-warning-container);
  color: var(--gk-on-warning-container);
}
.gk-label-red {
  background: var(--gk-error-container);
  color: var(--gk-on-error-container);
}
.gk-label-gray {
  background: var(--gk-surface-container-high);
  color: var(--gk-on-surface-variant);
}
.gk-label-blue {
  background: var(--gk-info-container);
  color: var(--gk-on-info-container);
}
/* Dark Mode Labels */
[data-gk-mode="dark"] .gk-label-green,
.gk-dark .gk-label-green {
  font-weight: 600;
  background: var(--gk-success-container);
  color: var(--gk-on-success-container);
}
[data-gk-mode="dark"] .gk-label-orange,
.gk-dark .gk-label-orange {
  font-weight: 600;
  background: var(--gk-warning-container);
  color: var(--gk-on-warning-container);
}
[data-gk-mode="dark"] .gk-label-red,
.gk-dark .gk-label-red {
  font-weight: 600;
  background: var(--gk-error-container);
  color: var(--gk-on-error-container);
}
[data-gk-mode="dark"] .gk-label-gray,
.gk-dark .gk-label-gray {
  font-weight: 600;
  background: var(--gk-surface-container-high);
  color: var(--gk-on-surface-variant);
}
[data-gk-mode="dark"] .gk-label-blue,
.gk-dark .gk-label-blue {
  font-weight: 600;
  background: var(--gk-info-container);
  color: var(--gk-on-info-container);
}

/* --gk-success is a FILL colour: as 14px text on the table surface the raw
   #10b981 measured 2.54:1, and the ✓ is the only carrier of the cell's meaning.
   --gk-success-text is the on-surface variant of the same hue (5.48:1 light,
   #34d399 dark, theme-derived elsewhere) — the same idiom .gk-stat-trend-up
   already uses. Bold 14px is not "large text", so 4.5:1 is the bar to clear. */
.gk-bool-yes {
  color: var(--gk-success-text, var(--gk-success));
  font-weight: bold;
}
.gk-bool-no {
  color: var(--gk-text-muted);
}

/* === FORM === */
.gk-form {
  width: 100%;
  max-width: 960px;
}
.gk-form-wide {
  max-width: none;
}

/* Grid-based row layout (16-column grid) */
.gk-form-row {
  display: grid;
  grid-template-columns: repeat(16, 1fr);
  gap: 16px;
  align-items: start;
  margin-bottom: 20px;
}
.gk-form-row > .gk-field {
  margin-bottom: 0;
}
.gk-form-col-1 {
  grid-column: span 1;
}
.gk-form-col-2 {
  grid-column: span 2;
}
.gk-form-col-3 {
  grid-column: span 3;
}
.gk-form-col-4 {
  grid-column: span 4;
}
.gk-form-col-5 {
  grid-column: span 5;
}
.gk-form-col-6 {
  grid-column: span 6;
}
.gk-form-col-7 {
  grid-column: span 7;
}
.gk-form-col-8 {
  grid-column: span 8;
}
.gk-form-col-9 {
  grid-column: span 9;
}
.gk-form-col-10 {
  grid-column: span 10;
}
.gk-form-col-11 {
  grid-column: span 11;
}
.gk-form-col-12 {
  grid-column: span 12;
}
.gk-form-col-13 {
  grid-column: span 13;
}
.gk-form-col-14 {
  grid-column: span 14;
}
.gk-form-col-15 {
  grid-column: span 15;
}
.gk-form-col-16 {
  grid-column: span 16;
}
.gk-form-col-auto {
  grid-column: auto;
}

/* Legacy flex row (backwards compat) */
.gk-row {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
}
.gk-field {
  margin-bottom: 20px;
}
.gk-w-1 {
  width: 6.25%;
}
.gk-w-2 {
  width: 12.5%;
}
.gk-w-3 {
  width: 18.75%;
}
.gk-w-4 {
  width: 25%;
}
.gk-w-5 {
  width: 31.25%;
}
.gk-w-6 {
  width: 37.5%;
}
.gk-w-7 {
  width: 43.75%;
}
.gk-w-8 {
  width: 50%;
}
.gk-w-9 {
  width: 56.25%;
}
.gk-w-10 {
  width: 62.5%;
}
.gk-w-11 {
  width: 68.75%;
}
.gk-w-12 {
  width: 75%;
}
.gk-w-13 {
  width: 81.25%;
}
.gk-w-14 {
  width: 87.5%;
}
.gk-w-15 {
  width: 93.75%;
}
.gk-w-16 {
  width: 100%;
}
.gk-row > .gk-field {
  flex: 1;
  min-width: 0;
  margin-bottom: 0;
}
.gk-row > .gk-w-1 {
  flex: 0 0 calc(6.25% - 14px);
  min-width: 0;
}
.gk-row > .gk-w-2 {
  flex: 0 0 calc(12.5% - 13px);
  min-width: 0;
}
.gk-row > .gk-w-3 {
  flex: 0 0 calc(18.75% - 13px);
  min-width: 0;
}
.gk-row > .gk-w-4 {
  flex: 0 0 calc(25% - 12px);
  min-width: 0;
}
.gk-row > .gk-w-5 {
  flex: 0 0 calc(31.25% - 11px);
  min-width: 0;
}
.gk-row > .gk-w-6 {
  flex: 0 0 calc(37.5% - 10px);
  min-width: 0;
}
.gk-row > .gk-w-7 {
  flex: 0 0 calc(43.75% - 9px);
  min-width: 0;
}
.gk-row > .gk-w-8 {
  flex: 0 0 calc(50% - 8px);
  min-width: 0;
}
.gk-row > .gk-w-9 {
  flex: 0 0 calc(56.25% - 7px);
  min-width: 0;
}
.gk-row > .gk-w-10 {
  flex: 0 0 calc(62.5% - 6px);
  min-width: 0;
}
.gk-row > .gk-w-11 {
  flex: 0 0 calc(68.75% - 5px);
  min-width: 0;
}
.gk-row > .gk-w-12 {
  flex: 0 0 calc(75% - 4px);
  min-width: 0;
}
.gk-row > .gk-w-13 {
  flex: 0 0 calc(81.25% - 3px);
  min-width: 0;
}
.gk-row > .gk-w-14 {
  flex: 0 0 calc(87.5% - 2px);
  min-width: 0;
}
.gk-row > .gk-w-15 {
  flex: 0 0 calc(93.75% - 1px);
  min-width: 0;
}
.gk-row > .gk-w-16 {
  flex: 0 0 100%;
  min-width: 0;
}

/* Inline field (label + input side by side) */
.gk-field-inline {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.gk-field-inline > .gk-label-text {
  margin-bottom: 0;
  flex-shrink: 0;
}
.gk-field-inline > .gk-input-wrap {
  flex: 1;
}

/* Form labels in mixed case instead of all caps.
   12px capitals with letter-spacing read measurably slower — and at that size
   this is the wrong kind of economy. Caps stay where they carry: table headers
   and section marks (--gk-text-overline). */
.gk-label-text {
  display: block;
  margin-bottom: 6px;
  font-size: var(--gk-text-label);
  font-weight: 500;
  line-height: var(--gk-leading-snug);
  color: var(--gk-on-surface-variant, #475569);
}
.gk-label-text .material-icons,
.gk-label-text .material-symbols-outlined,
.gk-label-text .material-symbols-rounded {
  text-transform: none;
  font-size: 1em;
  vertical-align: middle;
}
/* The required marker is the only thing that says a field is mandatory, so it
   is read as text, not decoration. --gk-danger is the FILL red: at 13px it
   measured 3.67:1 on the form surface. --gk-danger-text is the on-surface red
   of the same family (5.67:1 light, #fda4af dark) — the idiom .gk-btn-text
   .gk-btn-danger and .gk-stat-trend-down already use. */
.gk-required {
  color: var(--gk-danger-text, var(--gk-danger));
}
.gk-input {
  width: 100%;
  padding: 10px 14px;
  border: 1px solid var(--gk-outline-variant);
  border-radius: 8px;
  font-size: var(--gk-text-body);
  font-family: var(--gk-font);
  background: var(--gk-surface);
  color: var(--gk-text);
  outline: none;
  transition:
    border-color 0.15s,
    box-shadow 0.15s;
  box-sizing: border-box;
  height: 44px;
}
.gk-input::placeholder {
  color: #6e7781;
}
.gk-input:hover {
  border-color: var(--gk-outline, #94a3b8);
}
.gk-input:focus-visible {
  border-color: var(--gk-primary);
  border-width: 1.5px;
  padding: 9.75px 13.75px;
  box-shadow: var(--gk-focus-ring);
  outline: none;
}
textarea.gk-input {
  resize: vertical;
  height: auto;
  min-height: 80px;
}
/* Number: remove the browser spinner for a consistent layout */
input[type="number"].gk-input {
  -moz-appearance: textfield;
}
input[type="number"].gk-input::-webkit-outer-spin-button,
input[type="number"].gk-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.gk-input-clearable {
  position: relative;
  display: flex;
  align-items: center;
}
.gk-input-clearable .gk-input {
  padding-right: 40px;
}
.gk-input-clear {
  position: absolute;
  right: 8px;
  border: none;
  background: none;
  cursor: pointer;
  color: var(--gk-text-muted);
  padding: 4px;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    color 0.15s,
    background 0.15s;
}
.gk-input-clear:hover {
  color: var(--gk-danger);
  background: var(--gk-bg-muted);
}
.gk-input-clear .material-icons {
  font-size: var(--gk-icon-sm);
}
/* === COLOR PICKER === */
.gk-color-wrap {
  display: flex;
  align-items: center;
  height: 44px;
  border: 1.5px solid var(--gk-outline-variant, #cbd5e1);
  border-radius: 8px;
  overflow: hidden;
  background: var(--gk-surface-container-lowest, #fff);
  transition: border-color var(--gk-dur-1);
  box-sizing: border-box;
}
.gk-color-wrap:hover {
  border-color: var(--gk-outline, #94a3b8);
}
.gk-color-wrap:focus-within {
  border-color: var(--gk-primary);
  border-width: 2px;
}
.gk-color-swatch {
  width: 52px;
  height: 100%;
  border: none;
  border-right: 1.5px solid var(--gk-outline-variant, #cbd5e1);
  cursor: pointer;
  padding: 6px;
  background: none;
  flex-shrink: 0;
  box-sizing: border-box;
}
.gk-color-swatch input[type="color"] {
  display: block;
  width: 100%;
  height: 100%;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  padding: 0;
  appearance: none;
  -webkit-appearance: none;
}
.gk-color-swatch input[type="color"]::-webkit-color-swatch-wrapper {
  padding: 0;
  border-radius: 5px;
}
.gk-color-swatch input[type="color"]::-webkit-color-swatch {
  border: none;
  border-radius: 5px;
}
.gk-color-swatch input[type="color"]::-moz-color-swatch {
  border: none;
  border-radius: 5px;
}
.gk-color-hex {
  border: none;
  outline: none;
  font-size: var(--gk-text-body);
  font-family: inherit;
  color: var(--gk-text);
  background: none;
  width: 100%;
  padding: 0 12px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
select.gk-input {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 40px;
  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='%236b7280' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  cursor: pointer;
}

/* Toggle – M3 Style */
.gk-toggle {
  position: relative;
  display: inline-block;
  width: 48px;
  height: 28px;
  cursor: pointer;
}
.gk-toggle input {
  opacity: 0;
  width: 0;
  height: 0;
}
.gk-toggle-slider {
  position: absolute;
  inset: 0;
  background: var(--gk-surface-container-highest);
  border-radius: 14px;
  transition:
    background 0.2s,
    box-shadow 0.2s;
}
.gk-toggle-slider::before {
  content: "";
  position: absolute;
  width: 20px;
  height: 20px;
  left: 4px;
  top: 4px;
  background: #fff;
  border-radius: 50%;
  transition:
    transform 0.2s,
    width 0.2s;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
}
.gk-toggle input:checked + .gk-toggle-slider {
  background: var(--gk-primary);
}
.gk-toggle input:checked + .gk-toggle-slider::before {
  transform: translateX(20px);
}

.gk-form-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  padding-top: 16px;
  border-top: 1px solid var(--gk-outline-variant);
  margin-top: 16px;
}
.gk-field-hint {
  font-size: var(--gk-text-caption);
  color: var(--gk-text-secondary, #64748b);
  margin-top: 4px;
}

/* ── Form Density: Compact ─────────────────────────────── */
.gk-form-compact .gk-field {
  margin-bottom: 10px;
}
.gk-form-compact .gk-form-row {
  gap: 10px;
  margin-bottom: 10px;
}
.gk-form-compact .gk-label-text {
  margin-bottom: 3px;
  font-size: var(--gk-text-overline);
}
.gk-form-compact .gk-input {
  padding: 6px 10px;
  height: 34px;
  font-size: var(--gk-text-label);
  border-radius: 6px;
}
.gk-form-compact .gk-input:focus-visible {
  padding: 5.75px 9.75px;
}
.gk-form-compact select.gk-input {
  padding-right: 32px;
  background-position: right 10px center;
}
.gk-form-compact textarea.gk-input {
  height: auto;
  min-height: 56px;
}
.gk-form-compact .gk-section-title {
  font-size: var(--gk-text-overline);
  font-weight: 700;
  margin-bottom: 10px;
  color: var(--gk-primary, #6366f1);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.gk-form-compact .gk-field-hint {
  font-size: var(--gk-text-overline);
  margin-top: 2px;
}
.gk-form-compact .gk-toggle {
  width: 38px;
  height: 22px;
}
.gk-form-compact .gk-toggle-slider {
  border-radius: 11px;
}
.gk-form-compact .gk-toggle-slider::before {
  width: 16px;
  height: 16px;
  left: 3px;
  top: 3px;
}
.gk-form-compact .gk-toggle input:checked + .gk-toggle-slider::before {
  transform: translateX(16px);
}
.gk-form-compact .gk-checkbox-custom {
  width: 16px;
  height: 16px;
  border-radius: 3px;
}
.gk-form-compact .gk-checkbox-custom::after {
  width: 4px;
  height: 8px;
  border-width: 0 1.5px 1.5px 0;
}
.gk-form-compact .gk-checkbox-wrap {
  gap: 6px;
  font-size: var(--gk-text-label);
}
.gk-form-compact .gk-field-inline {
  gap: 8px;
}
.gk-form-compact .gk-select-display {
  padding: 6px 10px;
  height: 34px;
  font-size: var(--gk-text-label);
  border-radius: 6px;
}
.gk-form-compact .gk-select-display.open {
  padding: 5.75px 9.75px;
}
.gk-form-compact .gk-select-arrow {
  font-size: var(--gk-icon-xs);
}
.gk-form-compact .gk-select-option {
  padding: 6px 10px;
  font-size: var(--gk-text-label);
}
.gk-form-compact .gk-ajax-select .gk-select-display {
  height: 34px;
  padding: 6px 10px;
  font-size: var(--gk-text-label);
  border-radius: 6px;
  border-width: 1px;
}
.gk-form-compact .gk-ajax-search-input {
  font-size: var(--gk-text-label);
}
.gk-form-compact .gk-select-search-input {
  padding: 6px 10px;
}
.gk-form-compact .gk-select-search-input input {
  font-size: var(--gk-text-label);
}
.gk-field-error {
  color: var(--gk-danger);
  font-size: var(--gk-text-caption);
  min-height: 0;
  margin-top: 4px;
}
.gk-field-error:not(:empty) {
  min-height: 18px;
}
.gk-input.gk-has-error {
  border-color: var(--gk-danger);
}
.gk-input.gk-has-error:focus-visible {
  box-shadow: var(--gk-focus-ring-error);
}
.gk-field.gk-field-has-error .gk-label-text {
  color: var(--gk-danger);
}

/* === CHECKBOX (M3 Style) === */
.gk-checkbox-wrap {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font-size: var(--gk-font-size);
  user-select: none;
}
.gk-checkbox-wrap input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.gk-checkbox-custom {
  width: 20px;
  height: 20px;
  /* The box border IS the control when nothing is ticked, so WCAG 1.4.11 asks
     3:1 of it. neutral-400 (#94a3b8) on white is 2.56:1 — an empty checkbox
     that some people simply cannot see. neutral-500 is 4.76:1. */
  border: 2px solid var(--gk-neutral-500);
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: var(--gk-transition-state);
  flex-shrink: 0;
  position: relative;
}
.gk-checkbox-custom::after {
  content: "";
  display: block;
  width: 5px;
  height: 10px;
  border: solid var(--gk-on-primary);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) scale(0);
  transition: transform var(--gk-dur-1) ease;
  margin-top: -2px;
}
.gk-checkbox-wrap input:checked + .gk-checkbox-custom {
  background: var(--gk-primary);
  border-color: var(--gk-primary);
}
.gk-checkbox-wrap input:checked + .gk-checkbox-custom::after {
  transform: rotate(45deg) scale(1);
}
.gk-checkbox-wrap:hover .gk-checkbox-custom {
  border-color: var(--gk-primary);
}
.gk-checkbox-text {
  line-height: 1.4;
}

/* === RADIO (M3 Style) === */
.gk-radio-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.gk-radio-group-inline {
  display: flex;
  flex-direction: row;
  gap: 16px;
  flex-wrap: wrap;
}
.gk-radio-wrap {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font-size: var(--gk-font-size);
  user-select: none;
}
.gk-radio-wrap input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.gk-radio-custom {
  width: 20px;
  height: 20px;
  /* Same as the checkbox above: this ring is the whole control when unselected. */
  border: 2px solid var(--gk-neutral-500);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: var(--gk-transition-state);
  flex-shrink: 0;
}
.gk-radio-custom::after {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--gk-primary);
  transform: scale(0);
  transition: transform var(--gk-dur-1) ease;
}
.gk-radio-wrap input:checked + .gk-radio-custom {
  border-color: var(--gk-primary);
}
.gk-radio-wrap input:checked + .gk-radio-custom::after {
  transform: scale(1);
}
.gk-radio-wrap:hover .gk-radio-custom {
  border-color: var(--gk-primary);
}

/* === RANGE / SLIDER (M3 Style) === */
.gk-range-wrap {
  display: flex;
  align-items: center;
  gap: 12px;
}
.gk-range {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 4px;
  border-radius: 2px;
  background: var(--gk-neutral-200);
  outline: none;
  cursor: pointer;
}
.gk-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--gk-primary);
  border: none;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
  cursor: pointer;
  transition: box-shadow var(--gk-dur-1);
}
.gk-range::-webkit-slider-thumb:hover {
  box-shadow: 0 0 0 6px color-mix(in oklab, var(--gk-primary) 15%, transparent);
}
.gk-range::-moz-range-thumb {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--gk-primary);
  border: none;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
  cursor: pointer;
}
.gk-range::-moz-range-progress {
  background: var(--gk-primary);
  height: 4px;
  border-radius: 2px;
}
.gk-range-value {
  font-size: var(--gk-text-label);
  font-weight: 600;
  color: var(--gk-text);
  min-width: 32px;
  text-align: center;
}

/* === FILE UPLOAD (Drag & Drop Zone) === */
.gk-upload-zone {
  position: relative;
  border: 2px dashed #d0d7de;
  border-radius: 8px;
  padding: 24px;
  text-align: center;
  cursor: pointer;
  transition: var(--gk-transition-state);
  width: 100%;
  box-sizing: border-box;
}
.gk-upload-zone:hover {
  border-color: var(--gk-primary);
  background: var(--gk-primary-50);
}
.gk-upload-zone.gk-dragover {
  border-color: var(--gk-primary);
  background: var(--gk-primary-50);
}
.gk-upload-input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}
.gk-upload-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  pointer-events: none;
}
.gk-upload-icon {
  font-size: 32px;
  color: var(--gk-neutral-500);
}
.gk-upload-zone:hover .gk-upload-icon,
.gk-upload-zone.gk-dragover .gk-upload-icon {
  color: var(--gk-primary);
}
.gk-upload-text {
  font-size: var(--gk-text-body);
  color: var(--gk-text-muted);
}
.gk-upload-hint {
  font-size: var(--gk-text-caption);
  /* neutral-500, not neutral-400: #94a3b8 on white measures 2.56:1, which is
     under the 4.5:1 AA asks of body text and under the 3:1 it asks of icons —
     and this is caption-sized text, the hardest kind to read. #64748b is
     4.76:1. The same swap covers .gk-upload-icon and the rich-text
     placeholder, which had inherited the same value. Dark mode was already
     compliant at 4.76:1 and is untouched. */
  color: var(--gk-neutral-500);
}
.gk-upload-idle {
  display: flex;
}
.gk-upload-progress {
  display: none;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  pointer-events: none;
}
.gk-upload-progress-label {
  font-size: var(--gk-text-body);
  color: var(--gk-text-muted);
}

/* === UPLOAD QUEUE === */
.gk-upload-queue {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
}
.gk-uq-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: 8px;
  border: 1px solid var(--gk-border);
  background: var(--gk-bg);
  transition:
    opacity 0.2s,
    transform 0.2s;
}
.gk-uq-removing {
  opacity: 0;
  transform: translateX(8px);
}
.gk-uq-thumb {
  width: 36px;
  height: 36px;
  border-radius: 6px;
  overflow: hidden;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--gk-bg-muted);
}
.gk-uq-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.gk-uq-icon {
  font-size: var(--gk-icon-md);
  color: var(--gk-text-muted);
}
.gk-uq-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.gk-uq-name {
  font-size: var(--gk-text-label);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.gk-uq-size {
  font-size: var(--gk-text-overline);
  color: var(--gk-text-muted);
}
.gk-uq-status {
  font-size: var(--gk-text-overline);
  white-space: nowrap;
  padding: 2px 8px;
  border-radius: 20px;
}
.gk-uq-remove {
  border: none;
  background: none;
  cursor: pointer;
  color: var(--gk-text-muted);
  padding: 4px;
  border-radius: 4px;
  display: flex;
  align-items: center;
  flex-shrink: 0;
}
.gk-uq-remove:hover {
  background: var(--gk-bg-muted);
  color: var(--gk-danger);
}
/* States */
.gk-uq-pending .gk-uq-status {
  background: var(--gk-surface-container);
  color: var(--gk-text-muted);
}
.gk-uq-uploading {
  border-color: var(--gk-primary);
}
.gk-uq-uploading .gk-uq-status {
  background: var(--gk-primary-50, #eef2ff);
  color: var(--gk-primary);
}
.gk-uq-done {
  border-color: var(--gk-success);
}
.gk-uq-done .gk-uq-status {
  background: var(--gk-success-container);
  color: var(--gk-on-success-container);
}
.gk-uq-error {
  border-color: var(--gk-danger);
}
.gk-uq-error .gk-uq-status {
  background: var(--gk-error-container);
  color: var(--gk-on-error-container);
}

/* === RICHTEXT EDITOR === */
.gk-richtext {
  border: 1.5px solid var(--gk-border);
  border-radius: 8px;
  overflow: hidden;
  transition:
    border-color 0.15s,
    box-shadow 0.15s;
}
.gk-richtext:focus-within {
  border-color: var(--gk-primary);
  border-width: 2px;
  box-shadow: var(--gk-focus-ring-soft);
}
.gk-richtext-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  padding: 6px 8px;
  background: var(--gk-neutral-50);
  border-bottom: 1px solid var(--gk-border);
}
.gk-richtext-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border: none;
  border-radius: 4px;
  background: transparent;
  cursor: pointer;
  color: var(--gk-text-muted);
  transition: var(--gk-transition-state);
}
.gk-richtext-btn:hover {
  background: var(--gk-neutral-200);
  color: var(--gk-text);
}
.gk-richtext-btn.active {
  background: var(--gk-primary-100);
  color: var(--gk-primary-700);
}
.gk-richtext-btn .material-icons {
  font-size: var(--gk-icon-sm);
}
.gk-richtext-content {
  min-height: 120px;
  padding: 12px 16px;
  font-size: var(--gk-text-body);
  font-family: var(--gk-font);
  color: var(--gk-text);
  outline: none;
  line-height: 1.6;
}
.gk-richtext-content:empty::before {
  content: attr(data-placeholder);
  color: var(--gk-neutral-500);
}

/* Legacy checkbox/radio labels */
.gk-checkbox-label,
.gk-radio-label {
  display: flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  font-size: var(--gk-font-size);
}

/* === MODAL === */
.gk-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  backdrop-filter: blur(4px);
}
.gk-modal {
  background: var(--gk-surface);
  border-radius: 16px;
  box-shadow:
    var(--gk-elev-4),
    0 0 0 1px var(--gk-outline-variant);
  width: 90%;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.gk-modal-small {
  max-width: 420px;
}
.gk-modal-medium {
  max-width: 640px;
}
.gk-modal-large {
  max-width: 860px;
}
.gk-modal-large {
  max-width: 900px;
}
.gk-modal-full {
  max-width: none;
  width: calc(100% - 32px);
  height: calc(100% - 32px);
  display: flex;
  flex-direction: column;
}
.gk-modal-full .gk-modal-body {
  flex: 1;
  overflow-y: auto;
}
.gk-modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 24px;
  border-bottom: 1px solid var(--gk-outline-variant);
  background: var(--gk-surface);
}
.gk-modal-title {
  margin: 0;
  font-size: 17px;
  font-weight: 600;
  color: var(--gk-on-surface);
}
.gk-modal-close {
  background: none;
  border: none;
  font-size: var(--gk-icon-lg);
  cursor: pointer;
  color: var(--gk-on-surface-variant);
  /* Square hit target, vertically centered; the negative margin aligns the icon
     optically with the header's inner edge without it "sticking to the edge". */
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  margin: -4px -8px -4px 8px;
  line-height: 1;
  border-radius: 8px;
  transition: background var(--gk-dur-1), color var(--gk-dur-1);
}
.gk-modal-close:hover {
  color: var(--gk-on-surface);
  background: var(--gk-surface-container-high);
}
.gk-modal-close:focus-visible {
  outline: 2px solid var(--gk-primary, #4f46e5);
  outline-offset: 1px;
}
/* Center the Material icon used as the close glyph (instead of &times;) cleanly */
.gk-modal-close .material-icons { font-size: 20px; }
.gk-modal-body {
  padding: 24px;
  overflow-y: auto;
  background: var(--gk-surface);
}
.gk-modal-body .gk-form {
  margin: 0;
}
/* Modal footer: action bar at the end of the modal (close/save). It has its own
   padding because it sits OUTSIDE the padded gk-modal-body. */
.gk-modal-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  padding: 16px 24px;
  border-top: 1px solid var(--gk-outline-variant);
  background: var(--gk-surface);
  flex: 0 0 auto;
}
/* Compatibility: many views use gk-form-actions directly in the modal as a footer.
   gk-form-actions has no side or bottom padding (it is meant for use INSIDE forms)
   — placed directly in the modal, the buttons clung to the edge. */
.gk-modal > .gk-form-actions {
  margin-top: 0;
  padding: 16px 24px;
  background: var(--gk-surface);
}

/* Loading spinner */
.gk-loading::after {
  content: "";
  display: block;
  width: 24px;
  height: 24px;
  margin: 20px auto;
  border: 3px solid var(--gk-border);
  border-top-color: var(--gk-primary);
  border-radius: 50%;
  animation: gk-spin 0.6s linear infinite;
}

/* === FILTER CHIPS === */
.gk-filter-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  margin-bottom: 8px;
}
.gk-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 14px;
  border-radius: 9999px;
  font-size: var(--gk-font-size-sm);
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  transition: var(--gk-transition-state);
  border: 1px solid var(--gk-border);
  background: var(--gk-bg);
  color: var(--gk-text);
  line-height: 1.4;
}
.gk-chip:hover {
  background: var(--gk-bg-hover);
  border-color: var(--gk-text-muted);
}
.gk-chip-active {
  background: var(--gk-primary);
  color: var(--gk-on-primary);
  border-color: var(--gk-primary);
}
.gk-chip-active:hover {
  background: var(--gk-primary-hover);
}
/* Chip colours. FilterChips passes ['color' => x] straight through as
   .gk-chip-x, so whatever the caller writes has to have a rule here. Three
   existed; the demo ships green, orange, red and blue, and the skill document
   teaches primary — all of which rendered as an unstyled chip. The literal
   names are aliases of the semantic ones rather than a second palette. */
/* --gk-*-fill, not --gk-*: 1.38.0 introduced the darker pair precisely because
   white does not carry on the bright ones. 1.47.0 gave every chip colour a rule
   at last — and reached for the bright token, so the active green chip went
   from carrying its label to 2.54:1. The buttons have used -fill all along. */
.gk-chip-danger.gk-chip-active,
.gk-chip-red.gk-chip-active {
  background: var(--gk-danger-fill);
  border-color: var(--gk-danger-fill);
  color: var(--gk-on-primary, #fff);
}
.gk-chip-success.gk-chip-active,
.gk-chip-green.gk-chip-active {
  background: var(--gk-success-fill);
  border-color: var(--gk-success-fill);
  color: var(--gk-on-primary, #fff);
}
.gk-chip-warning.gk-chip-active,
.gk-chip-orange.gk-chip-active {
  background: var(--gk-warning);
  border-color: var(--gk-warning);
  color: #1f2937;
}
.gk-chip-primary.gk-chip-active,
.gk-chip-blue.gk-chip-active {
  background: var(--gk-primary);
  border-color: var(--gk-primary);
  color: var(--gk-on-primary, #fff);
}
.gk-chip-neutral.gk-chip-active {
  background: var(--gk-surface-container-highest);
  border-color: var(--gk-outline);
  color: var(--gk-on-surface);
}
.gk-chip-sm {
  padding: 4px 10px;
  font-size: var(--gk-text-caption);
}
.gk-chip-icon {
  font-size: var(--gk-icon-xs);
  line-height: 1;
}
.gk-chip-count {
  background: rgba(0, 0, 0, 0.08);
  padding: 1px 6px;
  border-radius: 9999px;
  font-size: var(--gk-text-overline);
  margin-left: 2px;
}
.gk-chip-active .gk-chip-count {
  background: rgba(255, 255, 255, 0.2);
}

/* === STAT CARDS === */
.gk-stat-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--gk-spacing);
  margin-bottom: 16px;
}
.gk-stat-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  background: var(--gk-bg);
  border-radius: var(--gk-radius);
  box-shadow: var(--gk-shadow);
  border: 1px solid var(--gk-border);
  text-decoration: none;
  color: inherit;
  transition: box-shadow var(--gk-dur-1);
}
a.gk-stat-card:hover {
  box-shadow: var(--gk-shadow-lg);
}
.gk-stat-content {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.gk-stat-label {
  font-size: var(--gk-font-size-sm);
  color: var(--gk-text-muted);
  font-weight: 500;
}
.gk-stat-value {
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--gk-text);
  line-height: 1.2;
}
.gk-stat-highlight {
  color: var(--gk-danger);
}

/* Trend indicator on a KPI tile. --gk-success and --gk-error are both
   redeclared for dark mode, so this needs no dark-mode block of its own. */
.gk-stat-trend {
    font-size: 0.8125rem;
    font-weight: 600;
    margin-top: 2px;
}
.gk-stat-trend-up   { color: var(--gk-success-text, var(--gk-success)); }
.gk-stat-trend-down { color: var(--gk-danger-text,  var(--gk-error)); }
.gk-stat-icon {
  font-size: var(--gk-icon-2xl);
  color: var(--gk-primary);
  opacity: 0.7;
}
.gk-stat-danger .gk-stat-icon {
  color: var(--gk-danger);
}
.gk-stat-danger .gk-stat-value {
  color: var(--gk-danger);
}
.gk-stat-success .gk-stat-icon {
  color: var(--gk-success);
}
.gk-stat-success .gk-stat-value {
  color: var(--gk-success);
}
.gk-stat-warning .gk-stat-icon {
  color: var(--gk-warning);
}
.gk-stat-warning .gk-stat-value {
  color: var(--gk-warning);
}
.gk-stat-blue .gk-stat-icon {
  color: var(--gk-primary);
}
.gk-stat-primary .gk-stat-icon {
  color: var(--gk-primary);
}
.gk-stat-info .gk-stat-icon {
  color: var(--gk-info);
}

/* === YEAR FILTER === */
.gk-year-filter {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  align-items: center;
  margin-bottom: 12px;
}

/* === SIDEBAR === */
/* Sidebar background set directly (high specificity, more reliable than a var() chain) */
[data-gk-theme] .gk-sidebar {
  background: var(--gk-sidebar-bg);
  color: var(--gk-sidebar-text);
  border-right: 1px solid var(--gk-sidebar-border);
}
[data-gk-mode="dark"] .gk-sidebar {
  color: rgba(255, 255, 255, 0.78);
}

/* Seven rules forced the dark sidebar of every theme to a uniform #010409 and
   thereby overrode the theme-specific values from themes.css (#0d1225 indigo,
   #071a2d ocean, #071a12 forest, ...). The sidebar now draws its surface from
   the role, like every other component. */
[data-gk-mode="dark"] .gk-sidebar {
  border-right-color: var(--gk-sidebar-border);
}

.gk-sidebar {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: 260px;
  background: var(--gk-sidebar-bg);
  color: var(--gk-sidebar-text);
  display: flex;
  flex-direction: column;
  z-index: 1000;
  transition:
    width 0.25s ease,
    transform 0.25s ease;
  overflow-y: auto;
  overflow-x: hidden;
  border-right: 1px solid var(--gk-sidebar-border);
}
.gk-sidebar-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 12px;
  border-bottom: 1px solid var(--gk-sidebar-border);
  background: var(--gk-sidebar-brand-bg);
}
.gk-sidebar-brand-icon {
  font-size: var(--gk-icon-2xl);
  color: var(--gk-sidebar-accent, #818cf8);
}
.gk-sidebar-brand-text {
  flex: 1;
  min-width: 0;
}
.gk-sidebar-brand-title {
  display: block;
  font-size: var(--gk-text-subtitle);
  font-weight: 700;
  letter-spacing: -0.3px;
  white-space: nowrap;
}
.gk-sidebar-brand-version {
  font-size: var(--gk-text-overline);
  color: var(--gk-sidebar-text-muted);
}
.gk-sidebar-close-mobile {
  display: none;
  background: none;
  border: none;
  color: var(--gk-sidebar-text-muted);
  cursor: pointer;
  padding: 4px;
}
.gk-sidebar-close-mobile:hover {
  color: var(--gk-sidebar-text-hover);
}
.gk-sidebar-nav {
  flex: 1;
  padding: 12px 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.gk-sidebar-group-label {
  font-size: var(--gk-text-overline);
  font-weight: 600;
  color: var(--gk-sidebar-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 16px 12px 6px;
}
.gk-sidebar-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-radius: 6px;
  color: var(--gk-sidebar-text);
  text-decoration: none;
  font-size: var(--gk-text-label);
  font-weight: 500;
  transition: var(--gk-transition-state);
  border-left: 3px solid transparent;
}
.gk-sidebar-item:hover {
  background: var(--gk-sidebar-item-hover);
  color: var(--gk-sidebar-text-hover);
}
.gk-sidebar-item:hover .gk-sidebar-icon {
  color: var(--gk-sidebar-text-hover);
}
.gk-sidebar-item.active {
  background: var(--gk-sidebar-item-active);
  color: var(--gk-sidebar-text-hover);
  border-left-color: var(--gk-sidebar-accent);
  padding-left: 9px;
}
.gk-sidebar-item.active .gk-sidebar-icon {
  color: var(--gk-sidebar-accent);
}
.gk-sidebar-icon {
  font-size: var(--gk-icon-md);
  color: var(--gk-sidebar-icon-muted);
  width: 24px;
  text-align: center;
  flex-shrink: 0;
  transition: color var(--gk-dur-1);
}
.gk-sidebar-label {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: opacity var(--gk-dur-2) ease;
}
.gk-sidebar.collapsed .gk-sidebar-label {
  opacity: 0;
  width: 0;
  overflow: hidden;
  padding: 0;
  margin: 0;
}
/* Sidebar groups with subitems */
.gk-sidebar-group-toggle {
  width: 100%;
  text-align: left;
  cursor: pointer;
  border: none;
  font: inherit;
  background: none;
}
.gk-sidebar-chevron {
  font-size: 18px !important;
  margin-left: auto;
  opacity: 0.5;
  transition: transform var(--gk-dur-2) ease;
  flex-shrink: 0;
}
.gk-sidebar-group-toggle.collapsed .gk-sidebar-chevron {
  transform: rotate(-90deg);
}
.gk-sidebar-subitems {
  display: flex;
  flex-direction: column;
  gap: 1px;
  overflow: hidden;
  max-height: 500px;
  transition:
    max-height 0.25s ease,
    opacity 0.2s ease;
  opacity: 1;
}
.gk-sidebar-subitems.collapsed {
  max-height: 0;
  opacity: 0;
}
.gk-sidebar-subitem {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px 8px 46px;
  border-radius: 6px;
  color: var(--gk-sidebar-text);
  text-decoration: none;
  font-size: var(--gk-text-label);
  transition: var(--gk-transition-state);
  opacity: 0.85;
}
.gk-sidebar-subitem:hover {
  background: var(--gk-sidebar-item-hover);
  color: var(--gk-sidebar-text);
}
.gk-sidebar-subitem.active {
  color: var(--gk-sidebar-text-hover);
  background: var(--gk-sidebar-item-active);
}
.gk-sidebar-subitem .gk-sidebar-icon {
  font-size: 17px;
  width: 20px;
  color: var(--gk-sidebar-icon-muted);
}
.gk-sidebar-subitem:hover .gk-sidebar-icon {
  color: var(--gk-sidebar-text-hover);
}
.gk-sidebar-subitem.active .gk-sidebar-icon {
  color: var(--gk-sidebar-accent);
}
.gk-sidebar-divider {
  height: 1px;
  background: var(--gk-sidebar-border);
  margin: 10px 14px;
}
.gk-sidebar.collapsed .gk-sidebar-subitems {
  max-height: 0;
  opacity: 0;
}
.gk-sidebar.collapsed .gk-sidebar-chevron {
  display: none;
}
.gk-sidebar.collapsed .gk-sidebar-badge {
  display: none;
}

.gk-sidebar-badge {
  font-size: var(--gk-text-overline);
  font-weight: 600;
  background: var(--gk-sidebar-accent);
  color: var(--gk-on-primary);
  padding: 1px 7px;
  border-radius: 9999px;
  min-width: 20px;
  text-align: center;
}
.gk-sidebar-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  z-index: 999;
}
.gk-sidebar-toggle {
  display: none;
  background: none;
  border: none;
  border-radius: 8px;
  padding: 8px;
  cursor: pointer;
  color: var(--gk-on-surface-variant);
  transition: var(--gk-transition-state);
}
.gk-sidebar-toggle:hover {
  background: var(--gk-surface-container-high);
  color: var(--gk-text);
}

/* Sidebar: collapsed state (icons only) */
.gk-sidebar.collapsed {
  width: 60px;
}
.gk-sidebar.collapsed .gk-sidebar-brand-text,
.gk-sidebar.collapsed .gk-sidebar-badge,
.gk-sidebar.collapsed .gk-sidebar-group-label,
.gk-sidebar.collapsed .gk-sidebar-collapse-label {
  opacity: 0;
  width: 0;
  overflow: hidden;
  pointer-events: none;
  transition:
    opacity 0.15s ease,
    width 0.15s ease;
}
.gk-sidebar-brand-text,
.gk-sidebar-badge,
.gk-sidebar-group-label,
.gk-sidebar-collapse-label {
  transition: opacity var(--gk-dur-2) ease;
}
.gk-sidebar.collapsed .gk-sidebar-brand {
  padding: 10px 0;
  justify-content: center;
  gap: 0;
}
.gk-sidebar.collapsed .gk-sidebar-brand-icon {
  display: none;
}
.gk-sidebar.collapsed .gk-sidebar-brand-text {
  display: none;
}
.gk-sidebar.collapsed .gk-sidebar-close-mobile {
  display: none;
}
.gk-sidebar.collapsed .gk-sidebar-collapse-btn {
  margin: 0 auto;
  width: 40px;
  height: 40px;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.07);
}
.gk-sidebar.collapsed .gk-sidebar-collapse-btn {
  margin: 0 auto;
}
.gk-sidebar.collapsed .gk-sidebar-item {
  justify-content: center !important;
  padding: 10px 0 !important;
  gap: 0 !important;
  text-align: center;
}
.gk-sidebar.collapsed .gk-sidebar-group-toggle {
  justify-content: center !important;
  padding: 10px 0 !important;
  gap: 0 !important;
}
.gk-sidebar.collapsed .gk-sidebar-icon {
  width: auto !important;
  font-size: var(--gk-icon-lg);
  margin: 0 !important;
  flex-shrink: 0;
}
.gk-sidebar.collapsed .gk-sidebar-label {
  display: none !important;
}
.gk-sidebar.collapsed .gk-sidebar-nav {
  padding: 8px 4px;
  gap: 2px;
}
.gk-sidebar.collapsed .gk-sidebar-close-mobile {
  display: none;
}
.gk-sidebar-collapse-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  color: var(--gk-sidebar-text-muted);
  cursor: pointer;
  padding: 8px;
  border-radius: 8px;
  flex-shrink: 0;
  transition: var(--gk-transition-state);
}
.gk-sidebar-collapse-btn:hover {
  background: var(--gk-sidebar-item-hover);
  color: var(--gk-sidebar-text-hover);
}
.gk-sidebar.collapsed
  .gk-sidebar-collapse-btn:not(.gk-sidebar-collapse-bottom) {
  padding: 10px;
  border-radius: 10px;
  margin: 0 auto;
  display: flex;
  background: var(--gk-sidebar-item-hover, rgba(255, 255, 255, 0.08));
}
.gk-sidebar-collapse-bottom {
  gap: 8px;
  padding: 12px 14px;
  margin: 4px 10px 12px;
  border-top: 1px solid var(--gk-sidebar-border);
  border-radius: 6px;
  width: calc(100% - 20px);
  font-size: var(--gk-text-label);
  justify-content: flex-start;
}
.gk-sidebar-collapse-bottom .material-icons {
  font-size: var(--gk-icon-md);
  transition: transform var(--gk-dur-2);
}
.gk-sidebar.collapsed .gk-sidebar-collapse-bottom {
  justify-content: center;
  margin: 4px 6px 12px;
  width: calc(100% - 12px);
}
.gk-sidebar.collapsed .gk-sidebar-collapse-bottom .material-icons {
  transform: rotate(180deg);
}

.gk-sidebar.collapsed .gk-sidebar-item {
  position: relative;
}
.gk-sidebar.collapsed .gk-sidebar-item::after {
  content: attr(data-label);
  position: absolute;
  left: 100%;
  top: 50%;
  transform: translateY(-50%);
  background: var(--gk-sidebar-bg);
  color: var(--gk-sidebar-text-hover);
  padding: 4px 10px;
  border-radius: 4px;
  font-size: var(--gk-text-caption);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--gk-dur-1);
  margin-left: 8px;
  z-index: 1001;
}
.gk-sidebar.collapsed .gk-sidebar-item:hover::after {
  opacity: 1;
}

/* Sidebar: content offset */
.gk-with-sidebar {
  margin-left: 260px;
  min-width: 0; /* otherwise a wide table blows the column out to the viewport edge */
  transition: margin-left var(--gk-dur-2) ease;
}

/* === LAYOUT MAX-WIDTH (--gk-content-max-width) ===
   The sidebar stays on the left. The content area is capped at (max-width - sidebar). */
.gk-with-sidebar {
  max-width: calc(var(--gk-content-max-width, 1600px) - 260px);
}
.gk-sidebar.collapsed ~ .gk-with-sidebar {
  max-width: calc(var(--gk-content-max-width, 1600px) - 60px);
}
.gk-sidebar.collapsed ~ .gk-with-sidebar {
  margin-left: 60px;
}

@media (max-width: 768px) {
  .gk-sidebar {
    transform: translateX(-100%);
  }
  .gk-sidebar.open {
    transform: translateX(0);
  }
  .gk-sidebar-close-mobile {
    display: block;
  }
  .gk-sidebar-collapse-btn {
    display: none;
  }
  .gk-sidebar-overlay.open {
    display: block;
  }
  .gk-sidebar-toggle {
    display: inline-flex;
  }
  .gk-with-sidebar {
    margin-left: 0;
  }
}

/* === TOOLTIP === */
.gk-tooltip {
  position: relative;
}
/* CSS-only button tooltips removed (v1.23.0): GK.tip takes over ALL title
   attributes panel-wide — one uniform popup, no double tooltip. */
.gk-tip {
  position: fixed;
  z-index: 100050;
  max-width: 360px;
  background: #1e293b;
  color: #fff;
  font-size: var(--gk-text-caption);
  font-weight: 500;
  line-height: 1.45;
  padding: 6px 10px;
  border-radius: 6px;
  white-space: pre-line;
  pointer-events: none;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
  animation: gk-tip-in 0.12s ease;
}
.gk-tip[hidden] {
  display: none;
}
@keyframes gk-tip-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes gk-tooltip-in {
  from {
    opacity: 0;
    transform: translateX(-50%) translateY(4px);
  }
  to {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
}

/* === CARD === */
.gk-card {
  background: var(--gk-surface, #fff);
  border: 1px solid var(--gk-outline-variant, #d0d7de);
  border-radius: 12px;
  padding: 20px 24px;
  margin-bottom: 16px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.07), 0 1px 2px rgba(0, 0, 0, 0.04);
}
.gk-card-title {
  margin: 0 0 16px;
  font-size: var(--gk-text-body);
  font-weight: 700;
  color: var(--gk-primary, #6366f1);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.gk-card-flat {
  box-shadow: none;
  border: 1px solid var(--gk-outline-variant, #e2e8f0);
}
.gk-card-elevated {
  box-shadow:
    0 1px 4px rgba(0, 0, 0, 0.06),
    0 4px 12px rgba(0, 0, 0, 0.04);
  border: none;
}

/* Form field spacing */
.gk-field {
  margin-bottom: 16px;
}
.gk-field:last-child {
  margin-bottom: 0;
}

/* === TOAST === */
/* Toast / Snackbar (M3) */
.gk-toast-container {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column-reverse;
  gap: 8px;
  z-index: 10000;
  pointer-events: none;
}
.gk-toast {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 48px;
  padding: 14px 16px;
  border-radius: 12px;
  min-width: 300px;
  max-width: 560px;
  pointer-events: auto;
  animation: gk-toast-in 0.3s cubic-bezier(0.2, 0, 0, 1);
  font-size: var(--gk-text-body);
  font-weight: 400;
  line-height: 1.4;
  box-shadow:
    0 3px 5px -1px rgba(0, 0, 0, 0.1),
    0 6px 10px rgba(0, 0, 0, 0.07),
    0 1px 18px rgba(0, 0, 0, 0.06);
}
.gk-toast-info {
  background: #1e293b;
  color: #f1f5f9;
}
.gk-toast-success {
  background: #065f46;
  color: #d1fae5;
}
.gk-toast-error {
  background: #881337;
  color: #ffe4e6;
}
.gk-toast-warning {
  background: #78350f;
  color: #fef3c7;
}
.gk-toast-icon {
  font-size: var(--gk-icon-lg);
  flex-shrink: 0;
  opacity: 0.9;
}
.gk-toast-close {
  background: none;
  border: none;
  color: inherit;
  opacity: 0.6;
  cursor: pointer;
  font-size: var(--gk-icon-sm);
  padding: 4px;
  margin-left: auto;
  border-radius: 50%;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    opacity 0.15s,
    background 0.15s;
  flex-shrink: 0;
}
.gk-toast-close:hover {
  opacity: 1;
  background: rgba(255, 255, 255, 0.1);
}
@keyframes gk-toast-in {
  from {
    transform: translateY(16px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}
.gk-toast-out {
  animation: gk-toast-out 0.2s ease forwards;
}
@keyframes gk-toast-out {
  to {
    transform: translateY(16px);
    opacity: 0;
  }
}

/* === CONFIRM DIALOG === */
.gk-confirm-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10001;
  animation: gk-fade-in 0.15s ease;
}
.gk-confirm-box {
  background: var(--gk-surface);
  border-radius: var(--gk-radius);
  box-shadow: var(--gk-shadow-lg);
  width: 90%;
  max-width: 420px;
  overflow: hidden;
  animation: gk-scale-in 0.2s ease;
}
.gk-confirm-header {
  padding: 16px 20px 0;
}
.gk-confirm-header h3 {
  margin: 0;
  font-size: var(--gk-text-subtitle);
  font-weight: 600;
}
.gk-confirm-body {
  padding: 12px 20px 20px;
}
.gk-confirm-body p {
  margin: 0;
  font-size: var(--gk-text-body);
  color: var(--gk-on-surface-variant);
  line-height: 1.5;
}
.gk-confirm-footer {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 12px 20px;
  border-top: 1px solid var(--gk-outline-variant);
  background: var(--gk-surface-container-low);
}
@keyframes gk-fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes gk-scale-in {
  from {
    opacity: 0;
    transform: scale(0.95);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

/* === RESPONSIVE === */
/* (Consolidated into mobile blocks at end of file) */

/* === HEADER === */
.gk-header {
  display: flex !important;
  flex-direction: row !important;
  align-items: center;
  justify-content: space-between;
  height: auto;
  min-height: 56px;
  padding: 8px 24px;
  background: var(--gk-surface);
  border-bottom: 1px solid var(--gk-outline-variant);
  gap: 16px;
  z-index: 200;
  width: 100%;
  box-sizing: border-box;
}
.gk-header > * {
  flex-shrink: 0;
}

/* Fixed Header (full-width, pinned to the top) */
.gk-header-fixed {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
}

/* Sticky Header (scrolls along, sticks to the top) */
.gk-header-sticky {
  position: sticky;
  top: 0;
  backdrop-filter: blur(12px);
  background: rgba(255, 255, 255, 0.85);
}

/* Backward-compat utility */
.gk-body-with-header {
  padding-top: 56px;
}

/* === LAYOUT: header-first (Default) === */
[data-gk-layout="header-first"] .gk-header-fixed,
.gk-layout-header-first .gk-header-fixed {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1100;
}
[data-gk-layout="header-first"] .gk-sidebar,
.gk-layout-header-first .gk-sidebar {
  top: 56px;
  height: calc(100vh - 56px);
}
[data-gk-layout="header-first"] .gk-with-sidebar,
.gk-layout-header-first .gk-with-sidebar {
  padding-top: 56px;
}

/* === LAYOUT: sidebar-first === */
[data-gk-layout="sidebar-first"] .gk-header-fixed,
.gk-layout-sidebar-first .gk-header-fixed {
  position: fixed;
  top: 0;
  left: 260px;
  right: 0;
  /* .gk-header carries width:100%, and on a fixed element an explicit width
     beats the right offset — so the header started at 260px and was still a
     full viewport wide, running 260px past the right edge with the user menu
     off screen and unreachable. Nothing in PHP or the console says a word;
     you only see it by measuring. width:auto hands the sizing back to
     left/right. */
  width: auto;
  z-index: 200;
  transition: left var(--gk-dur-2) ease;
}
[data-gk-layout="sidebar-first"] .gk-sidebar,
.gk-layout-sidebar-first .gk-sidebar {
  top: 0;
  height: 100vh;
  z-index: 300; /* Sidebar above the header */
}
[data-gk-layout="sidebar-first"]
  .gk-sidebar.collapsed
  ~ .gk-with-sidebar
  .gk-header-fixed,
.gk-layout-sidebar-first
  .gk-sidebar.collapsed
  ~ .gk-with-sidebar
  .gk-header-fixed,
[data-gk-layout="sidebar-first"] .gk-sidebar.collapsed + .gk-header-fixed,
.gk-layout-sidebar-first .gk-sidebar.collapsed + .gk-header-fixed {
  left: 60px;
}
[data-gk-layout="sidebar-first"] .gk-with-sidebar,
.gk-layout-sidebar-first .gk-with-sidebar {
  padding-top: 56px;
}

/* Mobile: always header-first */
@media (max-width: 768px) {
  [data-gk-layout="sidebar-first"] .gk-header-fixed {
    left: 0 !important;
  }
  [data-gk-layout="sidebar-first"] .gk-sidebar {
    top: 0;
    height: 100vh;
  }
}

.gk-header-left {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 12px;
  flex: 0 0 auto;
}
.gk-header-center {
  flex: 1 1 auto;
  display: flex;
  justify-content: center;
  max-width: 400px;
}
.gk-header-right {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 12px;
  flex: 0 0 auto;
}

.gk-header-title {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
  flex: 1 1 auto;
  overflow: hidden;
}
.gk-header-title h1 {
  font-size: var(--gk-text-subtitle);
  font-weight: 600;
  margin: 0;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Breadcrumb */
/* === BREADCRUMB === */
.gk-breadcrumb {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--gk-text-label);
  color: var(--gk-on-surface-variant);
  padding: 8px 0;
  margin-bottom: 16px;
}
.gk-header-title .gk-breadcrumb {
  padding: 2px 0 0;
  margin: 0;
  font-size: var(--gk-text-caption);
  gap: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.gk-breadcrumb a {
  color: var(--gk-on-surface-variant);
  text-decoration: none;
  transition: color var(--gk-dur-1);
}
.gk-breadcrumb a:hover {
  color: var(--gk-primary);
}
.gk-breadcrumb-sep {
  font-size: var(--gk-text-overline);
  color: var(--gk-on-surface-variant);
  display: flex;
  align-items: center;
}
.gk-breadcrumb-sep .material-icons {
  font-size: var(--gk-icon-xs);
}
.gk-breadcrumb-current {
  color: var(--gk-on-surface);
  font-weight: 500;
}
.gk-breadcrumb .material-icons {
  font-size: var(--gk-icon-xs);
  vertical-align: middle;
}

/* Header Search (pill) */
.gk-header-search {
  display: flex;
  align-items: center;
  background: var(--gk-surface-container);
  border-radius: 9999px;
  padding: 8px 16px;
  gap: 8px;
  width: 100%;
}
.gk-header-search input {
  border: none;
  background: none;
  outline: none;
  font-size: var(--gk-text-body);
  width: 100%;
  font-family: inherit;
}
.gk-header-search .material-icons {
  color: var(--gk-on-surface-variant);
  font-size: var(--gk-icon-md);
}

/* Header actions */
.gk-header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Menu toggle (mobile) */
.gk-header-menu-toggle {
  display: none;
  background: none;
  border: none;
  cursor: pointer;
  padding: 8px;
  border-radius: 8px;
  color: var(--gk-text);
}
.gk-header-menu-toggle:hover {
  background: var(--gk-surface-container-high);
}

/* Avatar */
.gk-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  object-fit: cover;
}
.gk-avatar-initials {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--gk-primary, #6366f1);
  color: var(--gk-on-primary);
  font-size: 14px;
  font-weight: 600;
}

/* User dropdown */
.gk-header-user {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 8px;
  position: relative;
  white-space: nowrap;
}
.gk-header-user:hover {
  background: var(--gk-surface-container-high);
}
.gk-header-user-name {
  font-size: var(--gk-text-body);
  font-weight: 500;
}
.gk-header-user .gk-dropdown-menu {
  display: none !important;
}
.gk-header-user.open .gk-dropdown-menu {
  display: block !important;
}

/* Dropdown menu */
.gk-dropdown-menu {
  display: none;
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: 8px;
  background: var(--gk-surface);
  border-radius: 12px;
  box-shadow: var(--gk-elev-2);
  min-width: 200px;
  padding: 8px 0;
  z-index: 200;
}
[data-gk-dropdown].open .gk-dropdown-menu {
  display: block;
}
.gk-dropdown-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  font-size: var(--gk-text-body);
  color: var(--gk-text);
  text-decoration: none;
  transition: background var(--gk-dur-1);
}
.gk-dropdown-item:hover {
  background: var(--gk-surface-container-high);
}
.gk-dropdown-item .material-icons {
  font-size: var(--gk-icon-md);
  color: var(--gk-text-muted);
}
.gk-dropdown-divider {
  height: 1px;
  background: var(--gk-outline-variant);
  margin: 4px 0;
}

/* === TABLE SIZES === */
.gk-table-sm th {
  padding: 6px 10px;
  font-size: var(--gk-text-overline);
}
.gk-table-sm td {
  padding: 6px 10px;
  font-size: var(--gk-text-label);
}
.gk-table-md th {
  padding: 10px 16px;
  font-size: var(--gk-text-caption);
}
.gk-table-md td {
  padding: 12px 16px;
  font-size: var(--gk-text-body);
}
.gk-table-lg th {
  padding: 14px 20px;
  font-size: var(--gk-text-label);
}
.gk-table-lg td {
  padding: 16px 20px;
  font-size: 15px;
}

/* === TABLE VARIANTS === */
.gk-table-bordered th,
.gk-table-bordered td {
  border: 1px solid var(--gk-outline-variant);
}
.gk-table-striped tbody tr:nth-child(even) {
  background: var(--gk-surface-container-low);
}
.gk-table-minimal th {
  border: none;
  background: transparent;
  color: var(--gk-on-surface-variant);
}
.gk-table-minimal td {
  border-bottom: 1px solid var(--gk-outline-variant);
}
.gk-table-minimal {
  box-shadow: none;
}
.gk-table-flat {
  box-shadow: none;
  border-radius: 0;
  border: none;
}
.gk-table-flat th {
  background: transparent;
  border-bottom: 2px solid var(--gk-outline-variant);
}
.gk-table-flat td {
  border-bottom: 1px solid var(--gk-outline-variant);
}

/* Celled: complete grid of borders */
.gk-table-celled,
.gk-table-celled th,
.gk-table-celled td {
  border: 1px solid var(--gk-outline-variant, #d0d7de);
}
.gk-table-celled {
  border-collapse: collapse;
}

/* Padded: extra padding for better readability */
.gk-table-padded th {
  padding: 14px 20px;
}
.gk-table-padded td {
  padding: 16px 20px;
  font-size: 15px;
}

/* Very Compact: denser still than sm */
.gk-table-xs th {
  padding: 4px 8px;
  font-size: 10px;
}
.gk-table-xs td {
  padding: 4px 8px;
  font-size: var(--gk-text-caption);
}

/* Compact — a hybrid since v1.17.0: readable 14px type, more compact vertical padding.
   It used to be 6px 12px / 13px — raised to 8px 12px / 14px on user request (Panel). */
.gk-table-compact th,
.gk-table-compact td {
  padding: 8px 12px;
  font-size: var(--gk-text-body);
}
.gk-table-very-compact th,
.gk-table-very-compact td {
  padding: 4px 8px;
  font-size: var(--gk-text-caption);
}

/* Single Line: no text wrapping */
.gk-table-single-line td {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 200px;
}

/* Fixed: equal column widths */
.gk-table-fixed {
  table-layout: fixed;
}

/* Selectable: rows look clickable */
.gk-table-selectable tbody tr {
  cursor: pointer;
  transition: background var(--gk-dur-1);
}
.gk-table-selectable tbody tr:hover {
  background: var(--gk-state-primary);
}

/* Definition: first column as a label */
.gk-table-definition td:first-child {
  font-weight: 600;
  color: var(--gk-on-surface-variant);
  background: var(--gk-surface-container, #f6f8fa);
  white-space: nowrap;
}
.gk-table-definition thead th:first-child {
  background: transparent;
}

/* Inverted: dark table in light mode */
.gk-table-inverted {
  background: #1e293b;
  color: #e2e8f0;
}
/* Both selectors, and the thead one on purpose: `.gk-table thead th` (0,1,2)
   outranks a plain `.gk-table-inverted th` (0,1,1), so the light-mode header
   colour --gk-on-surface-variant kept winning while the dark background here
   still applied. The header of an inverted table rendered as #475569 on
   #0f172a — 2.36:1, unreadable. Matching that specificity lets the intended
   #94a3b8 through again (6.96:1). The bare `th` selector stays for a `tbody th`
   in a definition table, which has no thead to match. */
.gk-table-inverted th,
.gk-table-inverted thead th {
  background: #0f172a;
  color: #94a3b8;
  border-bottom-color: rgba(255, 255, 255, 0.1);
}
.gk-table-inverted td {
  border-bottom-color: rgba(255, 255, 255, 0.06);
}
.gk-table-inverted tbody tr:nth-child(even) {
  background: rgba(255, 255, 255, 0.03);
}
.gk-table-inverted tbody tr:hover {
  background: rgba(255, 255, 255, 0.06);
}

/* === TABLE MOBILE: Card === */
@media (max-width: 768px) {
  .gk-table-mobile-card table {
    display: block;
  }
  .gk-table-mobile-card thead {
    display: none;
  }
  .gk-table-mobile-card tbody {
    display: block;
  }
  .gk-table-mobile-card tr {
    display: block;
    background: var(--gk-surface);
    border-radius: 12px;
    box-shadow: var(--gk-elev-1);
    padding: 16px;
    margin-bottom: 12px;
  }
  .gk-table-mobile-card td {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    padding: 6px 0;
    border: none;
    border-bottom: 1px solid var(--gk-outline-variant);
    /* A column's declared width belongs to the table layout. Carried into a
       card row it squeezes the label and the value into a strip — a column at
       `'width' => '140px'` left "Invoice no." overlapping its own value on a
       390 px screen. The competing declaration is inline, so !important is the
       only way to reach it. */
    width: auto !important;
    min-width: 0 !important;
    max-width: none !important;
    text-align: left !important;
  }
  .gk-table-mobile-card td > * {
    min-width: 0;
  }
  .gk-table-mobile-card td:last-child {
    border-bottom: none;
  }
  .gk-table-mobile-card td::before {
    content: attr(data-label);
    font-weight: 600;
    font-size: var(--gk-text-caption);
    color: var(--gk-on-surface-variant);
    text-transform: uppercase;
    /* Shrinks below 40% rather than pushing the value off the card. */
    flex: 0 1 40%;
    min-width: 0;
  }
  .gk-table-mobile-card td.gk-actions {
    justify-content: flex-end;
    padding-top: 12px;
    border-bottom: none;
  }
  .gk-table-mobile-card td.gk-actions::before {
    display: none;
  }
}

/* === TABLE MOBILE: Scroll === */
@media (max-width: 768px) {
  .gk-table-mobile-scroll .gk-table-container {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .gk-table-mobile-scroll table {
    min-width: 600px;
  }
}

/* === TABLE MOBILE: Hide Cols === */
@media (max-width: 768px) {
  .gk-hide-mobile {
    display: none !important;
  }
}

/* === SEGMENT === */
.gk-segment {
  background: var(--gk-surface, #fff);
  border: 1px solid var(--gk-outline-variant, #d0d7de);
  border-radius: var(--gk-radius, 12px);
  padding: 20px 24px;
  margin-bottom: 16px;
}
.gk-segment-raised {
  box-shadow: var(--gk-shadow-lg);
  border: none;
}
.gk-segment-basic {
  border: none;
  box-shadow: none;
  background: transparent;
  padding: 20px 0;
}
.gk-segment-compact {
  padding: 12px 16px;
}
.gk-segment-padded {
  padding: 28px 32px;
}
.gk-segment + .gk-segment {
  margin-top: 0;
  border-top: none;
  border-radius: 0;
}
.gk-segment:first-child {
  border-radius: var(--gk-radius) var(--gk-radius) 0 0;
}
.gk-segment:last-child {
  border-radius: 0 0 var(--gk-radius) var(--gk-radius);
}
.gk-segment:only-child {
  border-radius: var(--gk-radius);
}
.gk-segments {
  display: flex;
  flex-direction: column;
}
.gk-segments .gk-segment {
  margin-bottom: 0;
}
.gk-segment-header {
  font-size: 15px;
  font-weight: 600;
  margin-bottom: 12px;
  color: var(--gk-on-surface);
}
.gk-segment-muted {
  background: var(--gk-surface-container);
}

/* === MESSAGE === */
.gk-message {
  padding: 14px 20px;
  border-radius: var(--gk-radius-sm, 8px);
  border: 1px solid var(--gk-outline-variant);
  background: var(--gk-surface-container);
  color: var(--gk-on-surface);
  font-size: var(--gk-text-body);
  line-height: 1.5;
  margin-bottom: 16px;
  display: flex;
  align-items: flex-start;
  gap: 12px;
}
.gk-message .material-icons {
  font-size: var(--gk-icon-md);
  flex-shrink: 0;
  margin-top: 1px;
}
.gk-message-content {
  flex: 1;
}
.gk-message-header {
  font-weight: 600;
  margin-bottom: 4px;
}
.gk-message-dismiss {
  background: none;
  border: none;
  cursor: pointer;
  padding: 2px;
  color: inherit;
  opacity: 0.5;
  transition: opacity var(--gk-dur-1);
  flex-shrink: 0;
}
.gk-message-dismiss:hover {
  opacity: 1;
}
.gk-message-info {
  background: color-mix(in oklab, var(--gk-info) 8%, transparent);
  border-color: color-mix(in oklab, var(--gk-info) 25%, transparent);
  color: var(--gk-on-info-container);
}
.gk-message-success {
  background: color-mix(in oklab, var(--gk-success) 8%, transparent);
  border-color: color-mix(in oklab, var(--gk-success) 25%, transparent);
  color: var(--gk-on-success-container);
}
.gk-message-warning {
  background: color-mix(in oklab, var(--gk-warning) 8%, transparent);
  border-color: color-mix(in oklab, var(--gk-warning) 25%, transparent);
  color: var(--gk-on-warning-container);
}
.gk-message-error {
  background: color-mix(in oklab, var(--gk-error) 8%, transparent);
  border-color: color-mix(in oklab, var(--gk-error) 25%, transparent);
  color: var(--gk-on-error-container);
}
.gk-message-info .material-icons {
  color: var(--gk-info);
}
.gk-message-success .material-icons {
  color: var(--gk-success);
}
.gk-message-warning .material-icons {
  color: var(--gk-warning);
}
.gk-message-error .material-icons {
  color: var(--gk-error);
}
.gk-message-compact {
  padding: 10px 16px;
  font-size: var(--gk-text-label);
}
.gk-message-list {
  margin: 8px 0 0;
  padding-left: 18px;
}
.gk-message-list li {
  margin-bottom: 4px;
}

/* === CARDS GRID === */
.gk-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 20px;
  margin-bottom: 16px;
}
.gk-cards-2 {
  grid-template-columns: repeat(2, 1fr);
}
.gk-cards-3 {
  grid-template-columns: repeat(3, 1fr);
}
.gk-cards-4 {
  grid-template-columns: repeat(4, 1fr);
}

.gk-card-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--gk-outline-variant);
  font-weight: 600;
  font-size: 15px;
}
/* Icon + heading on one line: the h3 inherits the header typography (instead of
   a browser h3 with its own margins), icons get a fixed size. */
.gk-card-header h3 {
  margin: 0;
  font-size: inherit;
  font-weight: inherit;
  min-width: 0;
}
.gk-card-header > .material-icons {
  font-size: var(--gk-icon-md);
  flex: 0 0 auto;
  color: var(--gk-on-surface-variant);
}
/* Actions (buttons/links) right-aligned in the card header */
.gk-card-actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}
.gk-card-body {
  padding: 20px;
}
.gk-card-footer {
  padding: 12px 20px;
  border-top: 1px solid var(--gk-outline-variant);
  font-size: var(--gk-text-label);
  color: var(--gk-on-surface-variant);
}
.gk-card-image {
  border-radius: var(--gk-radius) var(--gk-radius) 0 0;
  width: 100%;
  display: block;
}
.gk-card-meta {
  font-size: var(--gk-text-caption);
  color: var(--gk-on-surface-variant);
  margin-bottom: 8px;
}
.gk-card-description {
  font-size: var(--gk-text-body);
  line-height: 1.6;
  color: var(--gk-on-surface);
}
.gk-card-link {
  display: block;
  text-decoration: none;
  color: inherit;
  transition:
    box-shadow 0.15s,
    transform 0.15s;
}
.gk-card-link:hover {
  box-shadow: var(--gk-shadow-lg);
  transform: translateY(-2px);
}

/* === ACCORDION === */
.gk-accordion {
  border: 1px solid var(--gk-outline-variant);
  border-radius: var(--gk-radius);
  overflow: hidden;
}
.gk-accordion-item {
  border-bottom: 1px solid var(--gk-outline-variant);
}
.gk-accordion-item:last-child {
  border-bottom: none;
}
.gk-accordion-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 14px 20px;
  border: none;
  background: var(--gk-surface);
  font-size: var(--gk-text-body);
  font-weight: 500;
  color: var(--gk-on-surface);
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  transition: background var(--gk-dur-1);
}
.gk-accordion-trigger:hover {
  background: var(--gk-surface-container);
}
.gk-accordion-trigger .material-icons {
  font-size: var(--gk-icon-md);
  color: var(--gk-on-surface-variant);
  transition: transform var(--gk-dur-2) ease;
}
.gk-accordion-item.open .gk-accordion-trigger .material-icons {
  transform: rotate(180deg);
}
.gk-accordion-content {
  max-height: 0;
  overflow: hidden;
  transition: max-height var(--gk-dur-3) ease;
}
.gk-accordion-item.open .gk-accordion-content {
  max-height: 500px;
}
.gk-accordion-body {
  padding: 0 20px 16px;
  font-size: var(--gk-text-body);
  line-height: 1.6;
  color: var(--gk-on-surface-variant);
}
.gk-accordion-flush {
  border: none;
  border-radius: 0;
}
.gk-accordion-flush .gk-accordion-item {
  border-bottom: 1px solid var(--gk-outline-variant);
}
.gk-accordion-flush .gk-accordion-trigger {
  padding-left: 0;
  padding-right: 0;
}
.gk-accordion-flush .gk-accordion-body {
  padding-left: 0;
  padding-right: 0;
}

/* ============================================================
   RESPONSIVE — Consolidated Mobile Breakpoints
   ============================================================ */

/* === TABLET / MOBILE (max-width: 768px) === */
@media (max-width: 768px) {
  /* Form rows */
  .gk-form-row {
    grid-template-columns: 1fr;
  }
  .gk-form-row > .gk-field {
    grid-column: span 1 !important;
    width: 100% !important;
  }

  /* Legacy flex rows */
  .gk-row {
    flex-direction: column;
  }
  .gk-row > .gk-field {
    flex: 1 1 100% !important;
  }

  /* Table: Default Mobile (horizontal scroll) */
  .gk-table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  /* 540px keeps the columns readable while the wrapper scrolls sideways —
     which is the point of the scroll mode. In card mode the same rule made
     every card 540px wide on a 390px phone, so the values sat off-screen and
     the very layout it exists to avoid came back. */
  .gk-table-wrap:not(.gk-table-mobile-card) .gk-table {
    min-width: 540px;
  }
  .gk-table-mobile-card .gk-table {
    min-width: 0;
    width: 100%;
  }

  /* Table: Touch-friendly padding */
  .gk-table th,
  .gk-table td {
    padding: 10px 12px;
  }
  .gk-table-sm th,
  .gk-table-sm td {
    padding: 8px 10px;
  }
  .gk-pagination {
    flex-wrap: wrap;
  }
  .gk-page-btn {
    min-width: 36px;
    height: 36px;
  }

  /* Toolbar */
  .gk-toolbar {
    flex-direction: column;
    align-items: stretch;
  }
  .gk-search {
    width: 100%;
    min-width: 0;
  }
  .gk-filter {
    width: 100%;
  }

  /* Header */
  .gk-header {
    padding: 0 12px;
    height: 56px;
  }
  .gk-header-title {
    font-size: 15px;
  }
  .gk-header-actions {
    gap: 4px;
  }
  .gk-header-search {
    display: none;
  }
  .gk-header-menu-toggle {
    display: flex;
  }
  .gk-header-center {
    display: none;
  }
  .gk-header-user-name {
    display: none;
  }

    /* The header's children are flex-shrink: 0 by design, so whatever does not
       fit is pushed off the screen rather than wrapped — silently, because
       nothing scrolls to reveal it. On a 390px phone the six accent swatches
       alone carried the New button and the mode toggle out of reach. */
    .gk-header-right,
    .gk-header-actions {
      min-width: 0;
      flex-shrink: 1;
    }
    /* Shrinking a flex box does not shrink what is inside it. The row got
       narrower and the buttons kept their width, so they were painted straight
       over the avatar beside them instead of being cut off: at 320px the
       actions row measured 33px wide while holding 63px of buttons, and the
       New button covered gk-header-user by 17px. Same story for a header in a
       container narrower than the viewport (the demo card at 390px): the row
       collapsed to 0 and its buttons spilled 48px past the header.
       Carry the overflow here, so a squeeze scrolls instead of colliding. The
       scrollbar itself stays hidden — it would sit across the header bar. */
    .gk-header-actions {
      overflow-x: auto;
      scrollbar-width: none;
    }
    .gk-header-actions::-webkit-scrollbar {
      display: none;
    }
    /* The accent is a preference set once. The light/dark toggle beside it is
       used daily, so that is the one that stays. */
    .gk-theme-switcher .gk-theme-dot {
      display: none;
    }

  /* Cards Grid */
  .gk-cards {
    grid-template-columns: 1fr;
    gap: 12px;
  }
  .gk-cards-2,
  .gk-cards-3,
  .gk-cards-4 {
    grid-template-columns: 1fr;
  }

  /* Stat Cards */
  .gk-stat-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 8px;
  }
  .gk-stat-card {
    padding: 12px 14px;
  }
  .gk-stat-value {
    font-size: 22px;
  }

  /* Modal */
  .gk-modal {
    width: 95% !important;
    max-width: none !important;
    max-height: 90vh;
    margin: 5vh auto;
  }
  .gk-modal-large {
    width: 95% !important;
  }

  /* Segment & Message */
  .gk-segment {
    padding: 14px 16px;
  }
  .gk-segment-padded {
    padding: 18px 20px;
  }
  .gk-message {
    padding: 12px 14px;
    gap: 10px;
    font-size: var(--gk-text-label);
  }

  /* Accordion */
  .gk-accordion-trigger {
    padding: 12px 16px;
  }
  .gk-accordion-body {
    padding: 0 16px 14px;
  }

  /* Breadcrumb */
  .gk-breadcrumb {
    font-size: var(--gk-text-caption);
    gap: 4px;
    flex-wrap: wrap;
  }

  /* Form Actions */
  .gk-form-actions {
    flex-direction: column;
  }
  .gk-form-actions .gk-btn {
    width: 100%;
  }
  .gk-field-inline {
    flex-direction: column;
    align-items: stretch;
  }
  .gk-field-inline > .gk-label-text {
    margin-bottom: 6px;
  }

  /* Toast */
  .gk-toast-container {
    left: 12px;
    right: 12px;
    transform: none;
    bottom: 12px;
  }
  .gk-toast {
    min-width: auto;
    max-width: none;
    width: 100%;
  }
}

/* === TABLET (769px - 1024px) === */
@media (min-width: 769px) and (max-width: 1024px) {
  .gk-cards-3,
  .gk-cards-4 {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* === PHONE ONLY (max-width: 480px) === */
@media (max-width: 480px) {
  /* Stat Cards: single column */
  .gk-stat-grid {
    grid-template-columns: 1fr;
  }

  /* Button Groups: vertical stack */
  .gk-btn-group {
    flex-direction: column;
    border-radius: var(--gk-radius-sm);
  }
  .gk-btn-group .gk-btn {
    border-radius: 0;
    border-right-width: 1.5px;
    border-bottom-width: 0;
  }
  .gk-btn-group .gk-btn:first-child {
    border-radius: var(--gk-radius-sm) var(--gk-radius-sm) 0 0;
  }
  .gk-btn-group .gk-btn:last-child {
    border-radius: 0 0 var(--gk-radius-sm) var(--gk-radius-sm);
    border-bottom-width: 1.5px;
  }

  /* Row actions are icon-only and belong side by side. The stack above is
     meant for segmented groups of labelled buttons; applied to a table row it
     turned two icons into a 51px-tall column inside every card. */
  .gk-actions .gk-btn-group,
  .gk-action-group {
    flex-direction: row;
  }
  .gk-actions .gk-btn-group .gk-btn {
    border-radius: var(--gk-radius-sm);
    border-bottom-width: 1.5px;
  }

  /* A finger is not a mouse pointer. Icon-only row buttons rendered at
     26x25 px, well under every touch-target guideline. */
  .gk-actions .gk-btn-icon-only,
  .gk-action-group .gk-btn-icon-only {
    min-width: 40px;
    min-height: 40px;
  }
}

/* === AVATAR === */
.gk-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  /*
   * No overflow:hidden here. It was clipping the status dot.
   *
   * The dot is positioned at bottom:0 right:0 — the corner of the square the
   * avatar occupies, which on a circle is outside the shape. A round clip then
   * sliced it into a crescent, which is what it looked like: a little leaf
   * stuck to the avatar rather than a status badge.
   *
   * The clip only ever existed to round a photo, so the photo rounds itself
   * (border-radius: inherit below) and the badge is free to sit on the edge.
   */
  flex-shrink: 0;
  background: var(--gk-primary-container);
  color: var(--gk-primary-700, #4338ca);
  font-weight: 600;
  text-transform: uppercase;
  position: relative;
}
.gk-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* inherit, so a square avatar variant keeps its corners without a second rule */
  border-radius: inherit;
}
.gk-avatar-xs {
  width: 24px;
  height: 24px;
  font-size: 10px;
}
.gk-avatar-sm {
  width: 32px;
  height: 32px;
  font-size: 12px;
}
.gk-avatar-md {
  width: 40px;
  height: 40px;
  font-size: 14px;
}
.gk-avatar-lg {
  width: 56px;
  height: 56px;
  font-size: var(--gk-icon-sm);
}
.gk-avatar-xl {
  width: 80px;
  height: 80px;
  font-size: var(--gk-icon-xl);
}
.gk-avatar-status {
  position: absolute;
  bottom: 0;
  right: 0;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 2px solid var(--gk-surface, #fff);
}
.gk-avatar-status.online {
  background: var(--gk-success);
}
.gk-avatar-status.offline {
  background: var(--gk-outline);
}
.gk-avatar-status.busy {
  background: var(--gk-error);
}
.gk-avatar-status.away {
  background: var(--gk-warning);
}
.gk-avatar-lg .gk-avatar-status {
  width: 14px;
  height: 14px;
}
.gk-avatar-xl .gk-avatar-status {
  width: 16px;
  height: 16px;
  border-width: 3px;
}
.gk-avatar-group {
  display: flex;
}
.gk-avatar-group .gk-avatar {
  margin-left: -8px;
  border: 2px solid var(--gk-surface, #fff);
}
.gk-avatar-group .gk-avatar:first-child {
  margin-left: 0;
}
.gk-avatar-square {
  border-radius: var(--gk-radius-sm, 8px);
}

/* === GALLERY === */
.gk-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 8px;
}
.gk-gallery-sm {
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  gap: 6px;
}
.gk-gallery-lg {
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
}
.gk-gallery-item {
  position: relative;
  overflow: hidden;
  border-radius: var(--gk-radius-sm, 8px);
  aspect-ratio: 1;
  cursor: pointer;
  background: var(--gk-surface-container);
}
.gk-gallery-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition:
    transform 0.2s ease,
    opacity 0.3s;
}
.gk-gallery-item:hover img {
  transform: scale(1.05);
}
.gk-gallery-item[data-lazy] img {
  opacity: 0;
}
.gk-gallery-item[data-lazy].loaded img {
  opacity: 1;
}
.gk-gallery-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(transparent 50%, rgba(0, 0, 0, 0.6));
  opacity: 0;
  transition: opacity var(--gk-dur-2);
  display: flex;
  align-items: flex-end;
  padding: 10px;
  color: #fff;
  font-size: var(--gk-text-caption);
}
.gk-gallery-item:hover .gk-gallery-overlay {
  opacity: 1;
}
.gk-gallery-caption {
  font-weight: 500;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}
/* Masonry variant */
.gk-gallery-masonry {
  columns: 4;
  column-gap: 8px;
  display: block;
}
.gk-gallery-masonry .gk-gallery-item {
  aspect-ratio: auto;
  break-inside: avoid;
  margin-bottom: 8px;
  display: block;
}
@media (max-width: 768px) {
  .gk-gallery {
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  }
  .gk-gallery-masonry {
    columns: 2;
  }
}

/* === LIGHTBOX === */
.gk-lightbox {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 10002;
  background: rgba(0, 0, 0, 0.92);
  align-items: center;
  justify-content: center;
  animation: gk-fade-in 0.2s ease;
}
.gk-lightbox.open {
  display: flex;
}
.gk-lightbox-img {
  max-width: 90vw;
  max-height: 85vh;
  object-fit: contain;
  border-radius: 4px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
  animation: gk-scale-in 0.2s ease;
  user-select: none;
}
.gk-lightbox-close {
  position: absolute;
  top: 16px;
  right: 16px;
  background: rgba(255, 255, 255, 0.1);
  border: none;
  color: #fff;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  cursor: pointer;
  font-size: var(--gk-icon-md);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--gk-dur-1);
}
.gk-lightbox-close:hover {
  background: rgba(255, 255, 255, 0.25);
}
.gk-lightbox-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background: rgba(255, 255, 255, 0.1);
  border: none;
  color: #fff;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  cursor: pointer;
  font-size: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--gk-dur-1);
}
.gk-lightbox-nav:hover {
  background: rgba(255, 255, 255, 0.25);
}
.gk-lightbox-prev {
  left: 16px;
}
.gk-lightbox-next {
  right: 16px;
}
.gk-lightbox-caption {
  position: absolute;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  color: rgba(255, 255, 255, 0.8);
  font-size: var(--gk-text-label);
  background: rgba(0, 0, 0, 0.5);
  padding: 6px 16px;
  border-radius: 20px;
  white-space: nowrap;
}
.gk-lightbox-counter {
  position: absolute;
  top: 18px;
  left: 20px;
  color: rgba(255, 255, 255, 0.6);
  font-size: var(--gk-text-label);
}

/* === DARK MODE === */
[data-gk-mode="dark"],
.gk-dark {
  --gk-primary: #a5b4fc;
  --gk-on-primary: #2e2e8a;
  --gk-primary-container: #4345b0;
  --gk-on-primary-container: #e0e0ff;

  --gk-secondary: #ccc2dc;
  --gk-on-secondary: #332d41;
  --gk-secondary-container: #4a4458;
  --gk-on-secondary-container: #e8def8;

  --gk-tertiary: #6ee7b7;
  --gk-on-tertiary: #064e3b;
  --gk-tertiary-container: #065f46;
  --gk-on-tertiary-container: #d1fae5;

  --gk-success: #34d399;
  --gk-on-success: #064e3b;
  --gk-success-container: #065f46;
  --gk-on-success-container: #d1fae5;

  --gk-error: #fda4af;
  --gk-on-error: #6b1028;
  --gk-error-container: #881337;
  --gk-on-error-container: #ffe4e6;

  --gk-surface-dim: #0d1117;
  --gk-surface: #0d1117;
  --gk-surface-bright: #3a4250;
  --gk-surface-container-lowest: #010409;
  --gk-surface-container-low: #0d1117;
  --gk-surface-container: #161b22;
  --gk-surface-container-high: #21262d;
  --gk-surface-container-highest: #2d333b;
  --gk-on-surface: #e6edf3;
  --gk-on-surface-variant: #8b949e;
  --gk-outline: #484f58;
  --gk-outline-variant: rgba(255, 255, 255, 0.08);

  --gk-warning: #fbbf24;
  --gk-on-warning: #78350f;
  --gk-warning-container: #78350f;
  --gk-on-warning-container: #fde68a;
  --gk-info: #38bdf8;
  --gk-on-info: #0c4a6e;
  --gk-info-container: #1e40af;
  --gk-on-info-container: #bfdbfe;
  --gk-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  --gk-shadow-lg: 0 10px 25px rgba(0, 0, 0, 0.4);
  /* Shadows barely carry on a dark ground — hence deeper, plus a light edge
     that lifts the layer above the surface the way M3 does. */
  --gk-elev-1: 0 1px 2px rgba(0, 0, 0, 0.30), 0 1px 3px rgba(0, 0, 0, 0.40);
  --gk-elev-2: 0 2px 4px rgba(0, 0, 0, 0.32), 0 4px 12px rgba(0, 0, 0, 0.44);
  --gk-elev-3: 0 4px 8px rgba(0, 0, 0, 0.36), 0 16px 32px rgba(0, 0, 0, 0.50);
  --gk-elev-4: 0 8px 16px rgba(0, 0, 0, 0.40), 0 24px 48px rgba(0, 0, 0, 0.56);

  /* Override the alias variables explicitly (make sure the fallback chain holds) */
  --gk-bg: #0d1117;
  --gk-bg-muted: #161b22;
  --gk-bg-subtle: #0d1117;
  --gk-bg-hover: #21262d;
  --gk-text: #e6edf3;
  --gk-text-muted: #8b949e;
  --gk-text-subtle: #484f58;
  --gk-border: rgba(255, 255, 255, 0.08);

  /* Legacy dark overrides */
  /* Hover steps: the @supports block at the end of the file derives them from
     whichever role applies. These values are only the fallback for browsers
     without relative color syntax — they have to be turned along in dark mode,
     otherwise the fallback path runs the light-mode direction there. */
  --gk-primary-hover: #93a1e8;
  --gk-tertiary-hover: #59d3a4;
  --gk-success-hover: #01bf87;
  --gk-warning-hover: #e7ac00;
  --gk-error-hover: #e8919c;
  --gk-warning-text: #fbbf24;
  --gk-success-text: #34d399;
  --gk-danger-text:  #fda4af;
  /* On a dark surface the primary is already light (L 0.80) and reads well. */
  --gk-primary-text: var(--gk-primary);
  --gk-neutral-50: #2d333b;
  --gk-neutral-100: #21262d;
  --gk-neutral-200: #161b22;
  --gk-neutral-800: #e6edf3;
  --gk-neutral-900: #f8fafc;

  /* Sidebar dark mode */
  --gk-sidebar-bg: #010409;
  --gk-sidebar-text: rgba(255, 255, 255, 0.7);
  /* 0.38 measured 3.40:1 on the dark sidebar — under the 4.5:1 that group
     labels, the version and the collapse label need. 0.55 reaches 5.48:1. */
  --gk-sidebar-text-muted: rgba(255, 255, 255, 0.55);
  --gk-sidebar-text-hover: #ffffff;
  --gk-sidebar-item-hover: rgba(255, 255, 255, 0.09);
  --gk-sidebar-item-active: rgba(255, 255, 255, 0.1);
  --gk-sidebar-border: rgba(255, 255, 255, 0.06);
  --gk-sidebar-accent: #a5b4fc;
  /* Icons need 3:1, which 0.45 (4.17:1) already met — raised to match the
     label beside them rather than sit a shade below it. */
  --gk-sidebar-icon-muted: rgba(255, 255, 255, 0.55);

  color-scheme: dark;
}

/* Dark mode: Component adjustments */
[data-gk-mode="dark"] .gk-header,
.gk-dark .gk-header {
  background: var(--gk-surface);
  border-color: var(--gk-outline-variant);
}
[data-gk-mode="dark"] .gk-header-sticky,
.gk-dark .gk-header-sticky {
  background: rgba(13, 17, 23, 0.92);
}
[data-gk-mode="dark"] .gk-modal,
.gk-dark .gk-modal {
  background: #161b22;
}
/* (Dark table overrides consolidated below in Comprehensive Overrides section) */
[data-gk-mode="dark"] .gk-search,
.gk-dark .gk-search {
  background-color: #0d1117;
  border-color: rgba(255, 255, 255, 0.15);
  color: var(--gk-on-surface);
}
[data-gk-mode="dark"] .gk-filter,
.gk-dark .gk-filter {
  background-color: #0d1117;
  border-color: rgba(255, 255, 255, 0.12);
  color: #8b949e;
}
[data-gk-mode="dark"] input,
[data-gk-mode="dark"] select,
[data-gk-mode="dark"] textarea,
.gk-dark input,
.gk-dark select,
.gk-dark textarea {
  background: #0d1117;
  color: #e6edf3;
  border-color: rgba(255, 255, 255, 0.15);
}
[data-gk-mode="dark"] .gk-confirm-box,
.gk-dark .gk-confirm-box {
  background: #161b22;
}
[data-gk-mode="dark"] .gk-toast,
.gk-dark .gk-toast {
  background: #2d333b;
  color: var(--gk-on-surface);
}

/* Dark mode: components that have to be switched over explicitly */
[data-gk-mode="dark"] .gk-stat-card,
.gk-dark .gk-stat-card {
  background: #161b22;
  border-color: rgba(255, 255, 255, 0.1);
  color: var(--gk-on-surface);
}
[data-gk-mode="dark"] .gk-stat-label,
.gk-dark .gk-stat-label {
  color: var(--gk-on-surface-variant);
}
[data-gk-mode="dark"] .gk-stat-value,
.gk-dark .gk-stat-value {
  color: #f0f6fc;
}

[data-gk-mode="dark"] .gk-chip,
.gk-dark .gk-chip {
  background: #161b22;
  border-color: rgba(255, 255, 255, 0.12);
  color: var(--gk-on-surface);
}
[data-gk-mode="dark"] .gk-chip:hover,
.gk-dark .gk-chip:hover {
  background: #21262d;
}
[data-gk-mode="dark"] .gk-chip.gk-chip-active,
.gk-dark .gk-chip.gk-chip-active {
  background: var(--gk-primary-container);
  color: var(--gk-on-primary-container);
  border-color: var(--gk-primary-container);
}

[data-gk-mode="dark"] .gk-card,
.gk-dark .gk-card {
  background: #161b22;
  border-color: rgba(255, 255, 255, 0.1);
  color: var(--gk-on-surface);
}

/* Segment dark mode */
[data-gk-mode="dark"] .gk-segment,
.gk-dark .gk-segment {
  background: #161b22;
  border-color: rgba(255, 255, 255, 0.1);
}
[data-gk-mode="dark"] .gk-segment-muted,
.gk-dark .gk-segment-muted {
  background: #0d1117;
}

/* Message dark mode */
[data-gk-mode="dark"] .gk-message,
.gk-dark .gk-message {
  background: #161b22;
  border-color: rgba(255, 255, 255, 0.1);
  color: #e6edf3;
}
[data-gk-mode="dark"] .gk-message-info,
.gk-dark .gk-message-info {
  background: rgba(14, 165, 233, 0.12);
  border-color: rgba(14, 165, 233, 0.2);
  color: #38bdf8;
}
[data-gk-mode="dark"] .gk-message-success,
.gk-dark .gk-message-success {
  background: rgba(16, 185, 129, 0.12);
  border-color: rgba(16, 185, 129, 0.2);
  color: #6ee7b7;
}
[data-gk-mode="dark"] .gk-message-warning,
.gk-dark .gk-message-warning {
  background: rgba(245, 158, 11, 0.12);
  border-color: rgba(245, 158, 11, 0.2);
  color: #fcd34d;
}
[data-gk-mode="dark"] .gk-message-error,
.gk-dark .gk-message-error {
  background: rgba(244, 63, 94, 0.12);
  border-color: rgba(244, 63, 94, 0.2);
  color: #fda4af;
}

/* Cards grid dark mode */
[data-gk-mode="dark"] .gk-card-footer,
.gk-dark .gk-card-footer {
  border-top-color: rgba(255, 255, 255, 0.08);
  color: #8b949e;
}

[data-gk-mode="dark"] .gk-page-btn,
.gk-dark .gk-page-btn {
  background: #161b22;
  border-color: #484f58;
  color: var(--gk-on-surface);
}
[data-gk-mode="dark"] .gk-page-btn:hover,
.gk-dark .gk-page-btn:hover {
  background: #21262d;
}
[data-gk-mode="dark"] .gk-page-btn.active,
.gk-dark .gk-page-btn.active {
  background: var(--gk-primary);
  color: var(--gk-on-primary);
  border-color: var(--gk-primary);
}

/* Dark Mode: tonal buttons – replace light backgrounds with dark variants */
[data-gk-mode="dark"] .gk-btn-tonal.gk-btn-primary,
.gk-dark .gk-btn-tonal.gk-btn-primary {
  background: rgba(99, 102, 241, 0.22);
  color: #c7d2fe;
}
[data-gk-mode="dark"] .gk-btn-tonal.gk-btn-primary:hover,
.gk-dark .gk-btn-tonal.gk-btn-primary:hover {
  background: rgba(99, 102, 241, 0.32);
}
[data-gk-mode="dark"] .gk-btn-tonal.gk-btn-success,
.gk-dark .gk-btn-tonal.gk-btn-success {
  background: rgba(16, 185, 129, 0.18);
  color: #a7f3d0;
}
[data-gk-mode="dark"] .gk-btn-tonal.gk-btn-success:hover,
.gk-dark .gk-btn-tonal.gk-btn-success:hover {
  background: rgba(16, 185, 129, 0.28);
}
[data-gk-mode="dark"] .gk-btn-tonal.gk-btn-warning,
.gk-dark .gk-btn-tonal.gk-btn-warning {
  background: rgba(245, 158, 11, 0.18);
  color: #fde68a;
}
[data-gk-mode="dark"] .gk-btn-tonal.gk-btn-warning:hover,
.gk-dark .gk-btn-tonal.gk-btn-warning:hover {
  background: rgba(245, 158, 11, 0.28);
}
[data-gk-mode="dark"] .gk-btn-tonal.gk-btn-danger,
.gk-dark .gk-btn-tonal.gk-btn-danger {
  background: rgba(239, 68, 68, 0.18);
  color: #fecaca;
}
[data-gk-mode="dark"] .gk-btn-tonal.gk-btn-danger:hover,
.gk-dark .gk-btn-tonal.gk-btn-danger:hover {
  background: rgba(239, 68, 68, 0.28);
}
[data-gk-mode="dark"] .gk-btn-tonal.gk-btn-neutral,
.gk-dark .gk-btn-tonal.gk-btn-neutral {
  background: rgba(255, 255, 255, 0.09);
  color: #e6edf3;
}
[data-gk-mode="dark"] .gk-btn-tonal.gk-btn-neutral:hover,
.gk-dark .gk-btn-tonal.gk-btn-neutral:hover {
  background: rgba(255, 255, 255, 0.15);
}

[data-gk-mode="dark"] .gk-header-search,
.gk-dark .gk-header-search {
  background: #21262d;
  color: var(--gk-on-surface);
}
[data-gk-mode="dark"] .gk-header-search input,
.gk-dark .gk-header-search input {
  background: transparent;
  border: none;
  color: var(--gk-on-surface);
}
[data-gk-mode="dark"] .gk-header-user:hover,
.gk-dark .gk-header-user:hover {
  background: #21262d;
}
[data-gk-mode="dark"] .gk-dropdown-menu,
.gk-dark .gk-dropdown-menu {
  background: #2d333b;
  border: 1px solid rgba(255, 255, 255, 0.1);
}
[data-gk-mode="dark"] .gk-dropdown-item:hover,
.gk-dark .gk-dropdown-item:hover {
  background: #21262d;
}

[data-gk-mode="dark"] .gk-confirm-footer,
.gk-dark .gk-confirm-footer {
  background: #21262d;
  border-color: rgba(255, 255, 255, 0.08);
}

/* Dark Mode: Upload Zone */
[data-gk-mode="dark"] .gk-upload-zone,
.gk-dark .gk-upload-zone {
  border-color: rgba(255, 255, 255, 0.15);
  background: #0d1117;
}
[data-gk-mode="dark"] .gk-upload-zone:hover,
[data-gk-mode="dark"] .gk-upload-zone.gk-dragover,
.gk-dark .gk-upload-zone:hover,
.gk-dark .gk-upload-zone.gk-dragover {
  border-color: var(--gk-primary);
  background: rgba(99, 102, 241, 0.08);
}
[data-gk-mode="dark"] .gk-upload-icon,
.gk-dark .gk-upload-icon {
  color: #8b949e;
}
[data-gk-mode="dark"] .gk-upload-zone:hover .gk-upload-icon,
.gk-dark .gk-upload-zone:hover .gk-upload-icon {
  color: var(--gk-primary);
}
[data-gk-mode="dark"] .gk-upload-hint,
.gk-dark .gk-upload-hint {
  color: #8b949e;
}

/* Dark Mode: Upload Queue */
[data-gk-mode="dark"] .gk-uq-item,
.gk-dark .gk-uq-item {
  background: #161b22;
  border-color: rgba(255, 255, 255, 0.08);
}
[data-gk-mode="dark"] .gk-uq-uploading .gk-uq-status,
.gk-dark .gk-uq-uploading .gk-uq-status {
  background: rgba(99, 102, 241, 0.15);
  color: var(--gk-primary);
}

/* Dark Mode: Toggle */
[data-gk-mode="dark"] .gk-toggle-slider,
.gk-dark .gk-toggle-slider {
  background: rgba(255, 255, 255, 0.15);
}

/* Dark Mode: Form field hints */
[data-gk-mode="dark"] .gk-field-hint,
.gk-dark .gk-field-hint {
  color: #8b949e;
}

/* Dark Mode: Page buttons (pagination) */
[data-gk-mode="dark"] .gk-page-btn.gk-active,
.gk-dark .gk-page-btn.gk-active {
  background: var(--gk-primary);
  /* The same trap as .gk-pg-active: in dark mode the primary is the light end
     of the scale, so a literal white sat on white. */
  color: var(--gk-on-primary);
}

/* Dark Mode: Select dropdowns */
[data-gk-mode="dark"] .gk-select-dropdown,
.gk-dark .gk-select-dropdown {
  background: #2d333b;
  border-color: rgba(255, 255, 255, 0.1);
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
}
[data-gk-mode="dark"] .gk-select-option:hover,
.gk-dark .gk-select-option:hover {
  background: #21262d;
}
[data-gk-mode="dark"] .gk-select-display,
.gk-dark .gk-select-display {
  background: #0d1117;
  border-color: rgba(255, 255, 255, 0.15);
  color: var(--gk-on-surface);
}

/* Dark Mode: Breadcrumbs */
[data-gk-mode="dark"] .gk-breadcrumb a,
.gk-dark .gk-breadcrumb a {
  color: #8b949e;
}
[data-gk-mode="dark"] .gk-breadcrumb a:hover,
.gk-dark .gk-breadcrumb a:hover {
  color: var(--gk-primary);
}
[data-gk-mode="dark"] .gk-breadcrumb-current,
.gk-dark .gk-breadcrumb-current {
  color: #e6edf3;
}

/* Dark Mode: Accordion */
[data-gk-mode="dark"] .gk-accordion,
.gk-dark .gk-accordion {
  border-color: rgba(255, 255, 255, 0.1);
}
[data-gk-mode="dark"] .gk-accordion-trigger,
.gk-dark .gk-accordion-trigger {
  background: #161b22;
  color: #e6edf3;
}
[data-gk-mode="dark"] .gk-accordion-trigger:hover,
.gk-dark .gk-accordion-trigger:hover {
  background: #21262d;
}
[data-gk-mode="dark"] .gk-accordion-item,
.gk-dark .gk-accordion-item {
  border-color: rgba(255, 255, 255, 0.08);
}
[data-gk-mode="dark"] .gk-accordion-body,
.gk-dark .gk-accordion-body {
  color: #8b949e;
}

/* Dark Mode: Form labels */
[data-gk-mode="dark"] .gk-label-text,
.gk-dark .gk-label-text {
  color: #8b949e;
}

/* Dark Mode: Richtext/CKEditor */
[data-gk-mode="dark"] .gk-richtext-wrap,
.gk-dark .gk-richtext-wrap {
  border-color: rgba(255, 255, 255, 0.15);
  background: #0d1117;
}

/* === THEME SWITCHER WIDGET === */
.gk-theme-switcher {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 2px 0;
}
.gk-theme-colors {
  display: flex;
  gap: 8px;
}
.gk-theme-dot {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, 0.18);
  cursor: pointer;
  transition: var(--gk-transition-state), transform var(--gk-dur-2) var(--gk-ease-out);
  box-shadow: 0 0 0 0 transparent;
}
.gk-theme-dot:hover {
  transform: scale(1.15);
  border-color: rgba(255, 255, 255, 0.45);
  box-shadow: 0 0 6px rgba(0, 0, 0, 0.3);
}
.gk-theme-dot.gk-theme-active {
  border-color: rgba(255, 255, 255, 0.7);
  transform: scale(1.15);
  box-shadow: 0 0 0 2.5px var(--gk-primary);
}
[data-gk-mode="light"] .gk-theme-dot {
  border-color: rgba(0, 0, 0, 0.12);
  box-shadow: none;
}
[data-gk-mode="light"] .gk-theme-dot:hover {
  border-color: rgba(0, 0, 0, 0.3);
  box-shadow: 0 0 4px rgba(0, 0, 0, 0.15);
}
[data-gk-mode="light"] .gk-theme-dot.gk-theme-active {
  border-color: var(--gk-primary);
  box-shadow: 0 0 0 2.5px var(--gk-primary);
}
.gk-mode-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 1.5px solid var(--gk-outline-variant);
  background: var(--gk-surface-container);
  cursor: pointer;
  color: var(--gk-on-surface);
  transition: var(--gk-transition-state);
  flex-shrink: 0;
}
.gk-mode-toggle:hover {
  background: var(--gk-surface-container-high);
  border-color: var(--gk-outline);
}
.gk-mode-toggle .material-icons {
  font-size: 14px;
}
/* Dropdown HTML items (e.g. the theme switcher in the avatar menu) */
.gk-dropdown-html {
  cursor: default;
  padding: 6px 16px;
}
.gk-dropdown-html:hover {
  background: transparent;
}
[data-gk-mode="light"] .gk-mode-dark {
  display: none;
}
[data-gk-mode="dark"] .gk-mode-light {
  display: none;
}
.gk-mode-dark {
  display: none;
}

/* === SEARCHABLE SELECT === */
.gk-select-search,
[data-gk-select-search] {
  position: relative;
}
.gk-select-display {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px;
  border: 1px solid var(--gk-outline-variant);
  border-radius: 8px;
  background: var(--gk-surface-container-lowest, #fff);
  cursor: pointer;
  font-size: var(--gk-text-body);
  color: var(--gk-text);
  transition: border-color var(--gk-dur-1);
  box-sizing: border-box;
  height: 44px;
}
.gk-select-display:hover {
  border-color: var(--gk-outline, #94a3b8);
}
.gk-select-display.open {
  border-color: var(--gk-primary);
  border-width: 2px;
  padding: 9.5px 13.5px;
}
.gk-select-arrow {
  font-size: var(--gk-icon-md);
  color: var(--gk-on-surface-variant);
  transition: transform var(--gk-dur-2);
}
.gk-select-display.open .gk-select-arrow {
  transform: rotate(180deg);
}
.gk-select-dropdown {
  display: none;
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  background: var(--gk-surface, #fff);
  border: 1px solid var(--gk-outline-variant);
  border-radius: 12px;
  box-shadow: var(--gk-elev-2);
  z-index: 500;
  max-height: 300px;
  overflow: hidden;
}
.gk-select-display.open + .gk-select-dropdown {
  display: block;
}
.gk-select-search-input {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--gk-outline-variant);
}
.gk-select-search-input input {
  border: none;
  outline: none;
  font-size: var(--gk-text-body);
  width: 100%;
  background: none;
  font-family: inherit;
  color: var(--gk-text);
}
.gk-select-search-input .material-icons {
  color: var(--gk-outline);
  font-size: var(--gk-icon-md);
}
.gk-select-options {
  overflow-y: auto;
  max-height: 240px;
  padding: 4px 0;
}
.gk-select-option {
  padding: 10px 14px;
  cursor: pointer;
  font-size: var(--gk-text-body);
  transition: background var(--gk-dur-1);
}
.gk-select-option:hover {
  background: var(--gk-surface-container-high);
}
.gk-select-option.selected {
  background: var(--gk-state-primary);
  color: var(--gk-primary);
  font-weight: 500;
}
.gk-select-option.hidden {
  display: none;
}
.gk-select-empty {
  padding: 16px;
  text-align: center;
  color: var(--gk-outline);
  font-size: var(--gk-text-label);
}
.gk-select-disabled .gk-select-display {
  opacity: 0.55;
  cursor: not-allowed;
  pointer-events: none;
  background: var(--gk-bg-muted);
}

/* === MULTI-SELECT === */
.gk-multiselect {
  position: relative;
}
.gk-multiselect-display {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px;
  border: 1.5px solid var(--gk-outline-variant, #cbd5e1);
  border-radius: 8px;
  background: var(--gk-surface-container-lowest, #fff);
  cursor: text;
  min-height: 44px;
  flex-wrap: wrap;
}
.gk-multiselect-display:hover {
  border-color: var(--gk-outline, #94a3b8);
}
.gk-multiselect-display.open {
  border-color: var(--gk-primary);
  border-width: 2px;
  padding: 5.5px 13.5px;
}
.gk-multiselect-display.open + .gk-select-dropdown {
  display: block;
}
.gk-multiselect-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  flex: 1;
  align-items: center;
}
.gk-multiselect-input {
  border: none;
  outline: none;
  font-size: var(--gk-text-body);
  min-width: 80px;
  flex: 1;
  background: none;
  padding: 4px 0;
  font-family: inherit;
}
.gk-chip-selected {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px 3px 10px;
  border-radius: 6px;
  font-size: var(--gk-text-label);
  font-weight: 500;
  background: var(--gk-primary-container, #e0e0ff);
  color: var(--gk-on-primary-container, #1a1a6b);
}
.gk-chip-remove {
  border: none;
  background: none;
  cursor: pointer;
  font-size: var(--gk-text-body);
  line-height: 1;
  color: var(--gk-on-primary-container, #1a1a6b);
  opacity: 0.6;
  padding: 0 2px;
}
.gk-chip-remove:hover {
  opacity: 1;
}

/* === AJAX SELECT === */
.gk-ajax-select {
  position: relative;
}
.gk-ajax-select .gk-select-display {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  border: 1px solid var(--gk-outline-variant);
  border-radius: 8px;
  background: var(--gk-surface-container-lowest, #fff);
  height: 44px;
  box-sizing: border-box;
}
.gk-ajax-select .gk-select-display:hover {
  border-color: var(--gk-outline);
}
.gk-ajax-search-input {
  border: none;
  outline: none;
  font-size: var(--gk-text-body);
  width: 100%;
  background: none;
  font-family: inherit;
  color: var(--gk-text);
}
.gk-ajax-clear {
  border: none;
  background: none;
  cursor: pointer;
  font-size: var(--gk-icon-sm);
  color: var(--gk-outline);
  padding: 0 4px;
}
.gk-ajax-clear:hover {
  color: var(--gk-danger);
}
.gk-select-icon {
  color: var(--gk-outline);
  font-size: var(--gk-icon-md);
}
.gk-select-loading {
  padding: 16px;
  text-align: center;
  color: var(--gk-outline);
  font-size: var(--gk-text-label);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.gk-select-option-sub {
  font-size: var(--gk-text-caption);
  color: var(--gk-outline);
  margin-top: 2px;
}

/* === PAGE HEADER === */
.gk-page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 20px;
}
.gk-page-header h1,
.gk-page-header h2 {
  font-size: var(--gk-text-title);
  font-weight: 700;
  margin: 0;
  color: var(--gk-on-surface);
}
.gk-page-header h3 {
  font-size: var(--gk-text-subtitle);
  font-weight: 600;
  margin: 0;
  color: var(--gk-on-surface);
}

/* === SECTION TITLE === */
/* === TABS === */
.gk-tabs {
  width: 100%;
}
.gk-tab-nav {
  display: flex;
  gap: 2px;
  border-bottom: 2px solid var(--gk-border);
  margin-bottom: 20px;
}
.gk-tab-btn {
  padding: 9px 18px;
  font-size: var(--gk-text-body);
  font-weight: 500;
  color: var(--gk-text-muted);
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -2px;
  cursor: pointer;
  transition:
    color 0.15s,
    border-color 0.15s;
  border-radius: 4px 4px 0 0;
  display: flex;
  align-items: center;
  gap: 6px;
}
.gk-tab-btn:hover {
  color: var(--gk-text);
  background: var(--gk-bg-hover);
}
.gk-tab-btn.gk-active {
  color: var(--gk-primary);
  border-bottom-color: var(--gk-primary);
}
.gk-tab-panel {
  display: none;
}
.gk-tab-panel.gk-active {
  display: block;
}

.gk-section-title {
  font-size: 15px;
  font-weight: 600;
  margin: 0 0 12px 0;
  color: var(--gk-on-surface);
}

/* === SPACER === */
.gk-spacer {
  height: 16px;
}
.gk-spacer-sm {
  height: 8px;
}
.gk-spacer-md {
  height: 20px;
}
.gk-spacer-lg {
  height: 24px;
}
.gk-spacer-xl {
  height: 32px;
}

/* === TEXT UTILITIES === */
.gk-text-muted {
  color: var(--gk-on-surface-variant);
}

/* === GRID === */
.gk-grid {
  display: grid;
  gap: 16px;
}
.gk-grid-2 {
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.gk-grid-4 {
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}

/* === FORM PAGE LAYOUT === */
.gk-form-page {
  max-width: 800px;
}

/* === CKEDITOR5 in GridKit === */
.gk-richtext-wrap {
  border: 1px solid var(--gk-border);
  border-radius: var(--gk-radius-sm);
  overflow: hidden;
  transition: border-color var(--gk-dur-1);
}
.gk-richtext-wrap:focus-within {
  border-color: var(--gk-primary);
  box-shadow: var(--gk-focus-ring-soft);
}
.gk-richtext-wrap .ck-editor__editable {
  min-height: 320px;
  font-family: var(--gk-font);
  font-size: var(--gk-text-body);
  border: none !important;
  box-shadow: none !important;
}
.gk-richtext-wrap .ck.ck-toolbar {
  border: none;
  border-bottom: 1px solid var(--gk-border) !important;
  background: var(--gk-bg-muted) !important;
}

/* ============================================================
   DARK MODE — Comprehensive Overrides
   Fixes for all hardcoded light-mode colors
   ============================================================ */

/* --- Buttons: outlined neutral (white border → subtle) --- */
[data-gk-mode="dark"] .gk-btn-outlined.gk-btn-neutral,
.gk-dark .gk-btn-outlined.gk-btn-neutral {
  color: var(--gk-on-surface-variant);
  border-color: var(--gk-outline);
}
[data-gk-mode="dark"] .gk-btn-outlined.gk-btn-neutral:hover,
.gk-dark .gk-btn-outlined.gk-btn-neutral:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--gk-on-surface);
  border-color: var(--gk-on-surface-variant);
}

/* --- Buttons: outlined primary/colors → theme-aware --- */
[data-gk-mode="dark"] .gk-btn-outlined.gk-btn-primary:hover,
.gk-dark .gk-btn-outlined.gk-btn-primary:hover {
  background: rgba(var(--gk-primary-rgb, 99, 102, 241), 0.12);
}

/* --- Buttons: filled primary → theme-aware --- */
[data-gk-mode="dark"] .gk-btn-filled.gk-btn-primary:hover,
.gk-dark .gk-btn-filled.gk-btn-primary:hover {
  filter: brightness(1.1);
}

/* --- Buttons: text neutral --- */
[data-gk-mode="dark"] .gk-btn-text.gk-btn-neutral:hover,
.gk-dark .gk-btn-text.gk-btn-neutral:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--gk-on-surface);
}

/* --- Tables: 4-level dark mode (page → panel → interactive → elevated) --- */
[data-gk-mode="dark"] .gk-table thead th,
.gk-dark .gk-table thead th {
  background: #161b22;
  color: #8b949e;
  font-size: var(--gk-text-overline);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-weight: 600;
  border-bottom-color: rgba(255, 255, 255, 0.06);
}
[data-gk-mode="dark"] .gk-table th,
[data-gk-mode="dark"] .gk-table td,
.gk-dark .gk-table th,
.gk-dark .gk-table td {
  border-bottom-color: rgba(255, 255, 255, 0.06);
  color: var(--gk-on-surface);
}
[data-gk-mode="dark"] .gk-table tbody tr:hover,
.gk-dark .gk-table tbody tr:hover {
  background: #262d38;
}
[data-gk-mode="dark"] .gk-table tbody tr:nth-child(even),
.gk-dark .gk-table tbody tr:nth-child(even) {
  background: #1c2128;
}
[data-gk-mode="dark"] .gk-table tbody tr:nth-child(even):hover,
.gk-dark .gk-table tbody tr:nth-child(even):hover {
  background: #262d38;
}
[data-gk-mode="dark"] .gk-table-wrap,
.gk-dark .gk-table-wrap {
  background: #161b22;
  border-color: rgba(255, 255, 255, 0.1);
}

/* Dark: Celled */
[data-gk-mode="dark"] .gk-table-celled th,
[data-gk-mode="dark"] .gk-table-celled td,
.gk-dark .gk-table-celled th,
.gk-dark .gk-table-celled td {
  border-color: rgba(255, 255, 255, 0.1);
}

/* Dark: Bordered */
[data-gk-mode="dark"] .gk-table-bordered th,
[data-gk-mode="dark"] .gk-table-bordered td,
.gk-dark .gk-table-bordered th,
.gk-dark .gk-table-bordered td {
  border-color: rgba(255, 255, 255, 0.1);
}

/* Dark: Minimal */

/* Dark: Flat */

/* Dark: Selectable */
[data-gk-mode="dark"] .gk-table-selectable tbody tr:hover,
.gk-dark .gk-table-selectable tbody tr:hover {
  background: rgba(99, 102, 241, 0.12);
}

/* Dark: Definition */
[data-gk-mode="dark"] .gk-table-definition td:first-child,
.gk-dark .gk-table-definition td:first-child {
  background: #0d1117;
  color: #8b949e;
}

/* Dark: Striped (explicit) */

/* Dark Mode: Table Mobile Card */
[data-gk-mode="dark"] .gk-table-mobile-card tr,
.gk-dark .gk-table-mobile-card tr {
  background: #161b22;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  border: 1px solid rgba(255, 255, 255, 0.08);
}
[data-gk-mode="dark"] .gk-table-mobile-card td,
.gk-dark .gk-table-mobile-card td {
  border-bottom-color: rgba(255, 255, 255, 0.06);
}

/* --- Inputs & Forms --- */
[data-gk-mode="dark"] .gk-input,
.gk-dark .gk-input {
  background: #0d1117;
  border-color: rgba(255, 255, 255, 0.15);
  color: var(--gk-on-surface);
}
[data-gk-mode="dark"] .gk-input::placeholder,
.gk-dark .gk-input::placeholder {
  color: #484f58;
}

/* --- Modal Header/Body --- */
[data-gk-mode="dark"] .gk-modal-header,
.gk-dark .gk-modal-header {
  background: #161b22;
  border-bottom-color: rgba(255, 255, 255, 0.08);
}
[data-gk-mode="dark"] .gk-modal-body,
.gk-dark .gk-modal-body {
  background: #161b22;
}
[data-gk-mode="dark"] .gk-modal-close:hover,
.gk-dark .gk-modal-close:hover {
  background: #21262d;
  color: var(--gk-on-surface);
}

[data-gk-mode="dark"] .gk-avatar,
.gk-dark .gk-avatar {
  background: rgba(99, 102, 241, 0.2);
  color: #a5b4fc;
}
[data-gk-mode="dark"] .gk-avatar-status,
.gk-dark .gk-avatar-status {
  border-color: #161b22;
}
[data-gk-mode="dark"] .gk-avatar-group .gk-avatar,
.gk-dark .gk-avatar-group .gk-avatar {
  border-color: #161b22;
}

/* ===================================================================
   TOOLTIP
   Usage: <span data-gk-tooltip="Tooltip text">Hover me</span>
   Position: data-gk-tooltip-pos="top|bottom|left|right" (default: top)
   Rich: <span data-gk-tooltip-rich="#tipId">Hover</span>
         <div id="tipId" class="gk-tooltip-content">HTML here</div>
   =================================================================== */

/* Base tooltip (CSS-only via ::after pseudo) */
[data-gk-tooltip] {
  position: relative;
  cursor: default;
}
[data-gk-tooltip]::after {
  font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  content: attr(data-gk-tooltip);
  position: absolute;
  z-index: 9999;
  padding: 6px 12px;
  font-size: var(--gk-text-caption);
  font-weight: 400;
  line-height: 1.4;
  white-space: nowrap;
  color: var(--gk-on-inverse-surface, #fff);
  background: var(--gk-inverse-surface, #1e293b);
  border-radius: 6px;
  box-shadow: var(--gk-elev-2);
  pointer-events: none;
  opacity: 0;
  transform: translateY(4px);
  transition:
    opacity 0.2s ease 0.3s,
    transform 0.2s ease 0.3s;
}
[data-gk-tooltip]:hover::after {
  opacity: 1;
  transform: translateY(0);
}


/* Positions */
[data-gk-tooltip]::after,
[data-gk-tooltip-pos="top"]::after {
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%) translateY(4px);
}
[data-gk-tooltip]:hover::after,
[data-gk-tooltip-pos="top"]:hover::after {
  transform: translateX(-50%) translateY(0);
}

[data-gk-tooltip-pos="bottom"]::after {
  top: calc(100% + 6px);
  bottom: auto;
  left: 50%;
  transform: translateX(-50%) translateY(-4px);
}
[data-gk-tooltip-pos="bottom"]:hover::after {
  transform: translateX(-50%) translateY(0);
}

[data-gk-tooltip-pos="left"]::after {
  right: calc(100% + 6px);
  left: auto;
  bottom: auto;
  top: 50%;
  transform: translateY(-50%) translateX(4px);
}
[data-gk-tooltip-pos="left"]:hover::after {
  transform: translateY(-50%) translateX(0);
}

[data-gk-tooltip-pos="right"]::after {
  left: calc(100% + 6px);
  right: auto;
  bottom: auto;
  top: 50%;
  transform: translateY(-50%) translateX(-4px);
}
[data-gk-tooltip-pos="right"]:hover::after {
  transform: translateY(-50%) translateX(0);
}

/* Multiline tooltip */
[data-gk-tooltip-wrap]::after {
  white-space: normal;
  max-width: 280px;
  text-align: left;
}

/* A CSS tooltip is position:absolute with white-space:nowrap and opacity:0 —
   so it is LAID OUT even while invisible, and a long one widens the page it
   sits on. Measured on the demo at 390px: the document scrolled 58px sideways
   with no visible element anywhere near the edge, which is why it survived
   several mobile passes. Capping the width on a narrow screen costs the
   desktop look nothing. */
@media (max-width: 640px) {
  [data-gk-tooltip]::after {
    max-width: min(70vw, 240px);
    white-space: normal;
    text-align: center;
  }
  /* left/right tooltips reach out sideways with left/right: 100%, which on a
     phone puts them past the screen edge — and, being laid out, widens the
     page. On a narrow screen every tooltip goes above its element instead,
     where it stays within the element's own horizontal span. */
  [data-gk-tooltip-pos="left"]::after,
  [data-gk-tooltip-pos="right"]::after {
    top: auto;
    bottom: calc(100% + 6px);
    left: 50%;
    right: auto;
    transform: translateX(-50%) translateY(4px);
  }
  [data-gk-tooltip-pos="left"]:hover::after,
  [data-gk-tooltip-pos="right"]:hover::after {
    transform: translateX(-50%) translateY(0);
  }
}


/* Rich Tooltip (HTML content from hidden element) */
.gk-tooltip-content {
  display: none;
  position: absolute;
  z-index: 600;
  padding: 12px 16px;
  min-width: 200px;
  max-width: 360px;
  font-size: var(--gk-text-label);
  line-height: 1.5;
  color: var(--gk-on-surface, #334155);
  background: var(--gk-surface-container-highest, #fff);
  border: 1px solid var(--gk-outline-variant, rgba(0, 0, 0, 0.1));
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  pointer-events: auto;
}
.gk-tooltip-content.visible {
  display: block;
  animation: gk-tooltip-in 0.2s ease;
}
.gk-tooltip-content a {
  color: var(--gk-primary);
  text-decoration: underline;
}
.gk-tooltip-content a:hover {
  text-decoration: none;
}

@keyframes gk-tooltip-in {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ── AJAX Navigation Progress ── */
/* AJAX navigation: no visual progress indicator — navigation is fast enough */


/* ════════════════════════════════════════════════════════════════════════
 * UTILITIES (v1.14.0) — helper classes for layout, spacing, typography, colors.
 *
 * Spacing scale: 0=0 · 1=4 · 2=8 · 3=12 · 4=16 · 5=20 · 6=24 (MD3 8-grid).
 * Goal: make inline styles in consumer projects (Panel etc.) eliminable.
 * All rules are additive — no breaking changes.
 * ════════════════════════════════════════════════════════════════════════ */

/* — Display — */
.gk-hidden        { display: none !important; }
.gk-block         { display: block; }
.gk-inline        { display: inline; }
.gk-inline-block  { display: inline-block; }

/* — Flex — */
.gk-flex          { display: flex; }
.gk-inline-flex   { display: inline-flex; }
.gk-flex-col      { display: flex; flex-direction: column; }
.gk-flex-wrap     { flex-wrap: wrap; }
.gk-flex-1        { flex: 1; }
.gk-items-start   { align-items: flex-start; }
.gk-items-center  { align-items: center; }
.gk-items-end     { align-items: flex-end; }
.gk-items-baseline{ align-items: baseline; }
.gk-justify-start { justify-content: flex-start; }
.gk-justify-center{ justify-content: center; }
.gk-justify-end   { justify-content: flex-end; }
.gk-justify-between{ justify-content: space-between; }

/* Composite shortcuts (most frequent combinations) */
.gk-flex-center   { display: flex; align-items: center; }
.gk-flex-between  { display: flex; align-items: center; justify-content: space-between; }

/* — Gap — */
.gk-gap-xs        { gap: 4px; }
.gk-gap-sm        { gap: 6px; }
.gk-gap-md        { gap: 8px; }
.gk-gap-lg        { gap: 12px; }
.gk-gap-xl        { gap: 16px; }
.gk-gap-2xl       { gap: 20px; }

/* — Margin (scale 0/1/2/3/4/5/6 = 0/4/8/12/16/20/24) — */
.gk-m-0  { margin: 0; }
.gk-m-1  { margin: 4px; }
.gk-m-2  { margin: 8px; }
.gk-m-3  { margin: 12px; }
.gk-m-4  { margin: 16px; }
.gk-m-5  { margin: 20px; }
.gk-m-6  { margin: 24px; }

.gk-mt-0 { margin-top: 0; }
.gk-mt-1 { margin-top: 4px; }
.gk-mt-2 { margin-top: 8px; }
.gk-mt-3 { margin-top: 12px; }
.gk-mt-4 { margin-top: 16px; }
.gk-mt-5 { margin-top: 20px; }
.gk-mt-6 { margin-top: 24px; }

.gk-mb-0 { margin-bottom: 0; }
.gk-mb-1 { margin-bottom: 4px; }
.gk-mb-2 { margin-bottom: 8px; }
.gk-mb-3 { margin-bottom: 12px; }
.gk-mb-4 { margin-bottom: 16px; }
.gk-mb-5 { margin-bottom: 20px; }
.gk-mb-6 { margin-bottom: 24px; }

.gk-ml-0 { margin-left: 0; }
.gk-ml-1 { margin-left: 4px; }
.gk-ml-2 { margin-left: 8px; }
.gk-ml-3 { margin-left: 12px; }
.gk-ml-4 { margin-left: 16px; }
.gk-ml-auto { margin-left: auto; }

.gk-mr-0 { margin-right: 0; }
.gk-mr-1 { margin-right: 4px; }
.gk-mr-2 { margin-right: 8px; }
.gk-mr-3 { margin-right: 12px; }
.gk-mr-4 { margin-right: 16px; }
.gk-mr-auto { margin-right: auto; }

.gk-mx-auto { margin-left: auto; margin-right: auto; }

/* — Padding (scale 0/1/2/3/4/5/6) — */
.gk-p-0  { padding: 0; }
.gk-p-1  { padding: 4px; }
.gk-p-2  { padding: 8px; }
.gk-p-3  { padding: 12px; }
.gk-p-4  { padding: 16px; }
.gk-p-5  { padding: 20px; }
.gk-p-6  { padding: 24px; }

.gk-px-0 { padding-left: 0; padding-right: 0; }
.gk-px-1 { padding-left: 4px; padding-right: 4px; }
.gk-px-2 { padding-left: 8px; padding-right: 8px; }
.gk-px-3 { padding-left: 12px; padding-right: 12px; }
.gk-px-4 { padding-left: 16px; padding-right: 16px; }
.gk-px-5 { padding-left: 20px; padding-right: 20px; }
.gk-px-6 { padding-left: 24px; padding-right: 24px; }

.gk-py-0 { padding-top: 0; padding-bottom: 0; }
.gk-py-1 { padding-top: 4px; padding-bottom: 4px; }
.gk-py-2 { padding-top: 8px; padding-bottom: 8px; }
.gk-py-3 { padding-top: 12px; padding-bottom: 12px; }
.gk-py-4 { padding-top: 16px; padding-bottom: 16px; }
.gk-py-5 { padding-top: 20px; padding-bottom: 20px; }
.gk-py-6 { padding-top: 24px; padding-bottom: 24px; }

/* — Font-Size — */
.gk-fs-xs   { font-size: 11px; }
.gk-fs-sm   { font-size: 12px; }
.gk-fs-md   { font-size: 13px; }
.gk-fs-base { font-size: 14px; }
.gk-fs-lg   { font-size: 16px; }
.gk-fs-xl   { font-size: 18px; }
.gk-fs-2xl  { font-size: 20px; }

/* — Font-Weight — */
.gk-fw-normal   { font-weight: 400; }
.gk-fw-medium   { font-weight: 500; }
.gk-fw-semibold { font-weight: 600; }
.gk-fw-bold     { font-weight: 700; }

/* — Text-Align — */
.gk-text-left   { text-align: left; }
.gk-text-center { text-align: center; }
/* .gk-text-right already exists further up — do not define it again */

/* — Text-Color (semantic) — */
.gk-text-primary { color: var(--gk-primary, #6366f1); }
.gk-text-success { color: var(--gk-success, #10b981); }
.gk-text-danger  { color: var(--gk-danger,  #ef4444); }
.gk-text-warning { color: var(--gk-warning, #f59e0b); }
.gk-text-on-surface { color: var(--gk-on-surface, #1e293b); }
/* .gk-text-muted already exists */

/* — Background (subtle container backgrounds) — */
.gk-bg-surface      { background: var(--gk-surface, #fff); }
.gk-bg-muted        { background: var(--gk-bg-muted, var(--gk-surface-container-low, #f8fafc)); }
.gk-bg-danger-soft  { background: rgba(239, 68, 68, 0.08); }
.gk-bg-success-soft { background: rgba(16, 185, 129, 0.08); }
.gk-bg-warning-soft { background: rgba(245, 158, 11, 0.10); }
.gk-bg-primary-soft { background: rgba(99, 102, 241, 0.08); }

/* — Border-Radius — */
.gk-rounded-none { border-radius: 0; }
.gk-rounded-sm   { border-radius: 6px; }
.gk-rounded-md   { border-radius: 8px; }
.gk-rounded-lg   { border-radius: 10px; }
.gk-rounded-xl   { border-radius: 14px; }
.gk-rounded-full { border-radius: 999px; }

/* — Width / Height — */
.gk-w-full { width: 100%; }
.gk-w-auto { width: auto; }
.gk-h-full { height: 100%; }
.gk-h-auto { height: auto; }

/* — Misc — */
.gk-clickable      { cursor: pointer; }
.gk-not-clickable  { cursor: default; }
.gk-overflow-x-auto{ overflow-x: auto; }
.gk-overflow-y-auto{ overflow-y: auto; }
.gk-font-mono      { font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; }
.gk-no-decoration  { text-decoration: none; }
.gk-truncate       { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gk-break-word     { overflow-wrap: anywhere; word-break: break-word; }


/* ════════════════════════════════════════════════════════════════════════
 * BelegModal (v1.15.0) — global PDF/receipt preview modal with an iframe.
 * Desktop: inline. Mobile: native viewer button.
 * ════════════════════════════════════════════════════════════════════════ */

.gk-beleg-modal-overlay {
    display: none;
    position: fixed; inset: 0;
    background: rgba(0,0,0,0.45);
    /* Above standard modals (.gk-modal-overlay = 9999), so that the PDF preview
       is visible even when it is opened FROM inside a modal
       (e.g. account detail in the year-end closing). Below .gk-confirm-overlay (10001). */
    z-index: 10000;
    align-items: stretch; justify-content: center;
}
.gk-beleg-modal-overlay.is-open { display: flex; }

.gk-beleg-modal-box {
    width: min(92vw, 960px);
    height: min(92vh, 1200px);
    display: flex; flex-direction: column; padding: 0;
    margin: auto;
}

.gk-beleg-modal-actions { display: flex; align-items: center; gap: 6px; }

.gk-beleg-modal-body {
    flex: 1; padding: 0; overflow: hidden; position: relative;
    background: var(--gk-surface-container);
}

.gk-beleg-modal-frame { width: 100%; height: 100%; border: 0; display: block; background: #fff; }

.gk-beleg-modal-mobile {
    display: none;
    flex-direction: column; align-items: center; justify-content: center;
    gap: 14px; padding: 40px 24px; text-align: center;
    position: absolute; inset: 0;
}
.gk-beleg-mobile-icon { font-size: 56px; color: var(--gk-text-muted); }
.gk-beleg-modal-mobile p {
    max-width: 280px;
    color: var(--gk-text-muted);
    margin: 0;
    font-size: var(--gk-text-body);
}

/* Mobile (≤ 768px): iframe gone, native viewer button to the front */
@media (max-width: 768px) {
    .gk-beleg-modal-frame { display: none; }
    .gk-beleg-modal-mobile { display: flex; }
    .gk-beleg-btn-label { display: none; }
    .gk-beleg-modal-box {
        width: 100vw; height: 100vh;
        max-width: 100vw; max-height: 100vh;
        border-radius: 0;
    }
}


/* ════════════════════════════════════════════════════════════════════════
 * ActionGroup (v1.16.0) — container for action buttons in table columns
 * + gk-btn-xs for mini buttons + gk-btn-pill for badge-shaped buttons
 * ════════════════════════════════════════════════════════════════════════ */

/* Action button container: compact flex row, no wrapping */
.gk-action-group {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    flex-wrap: nowrap;
}

/* Extra small button size (more compact than gk-btn-sm) */
.gk-btn-xs {
    padding: 3px 8px;
    font-size: var(--gk-text-overline);
    border-radius: 6px;
    gap: 3px;
}
.gk-btn-xs .material-icons { font-size: 14px; }
.gk-btn-icon-only.gk-btn-xs { padding: 4px; width: 26px; height: 26px; }
.gk-btn-icon-only.gk-btn-xs .material-icons { font-size: 16px; }

/* Pill-shaped (badge style) — round corners instead of rectangular */
.gk-btn-pill { border-radius: 999px; }
.gk-btn-pill.gk-btn-xs { padding: 2px 10px; }
.gk-btn-pill.gk-btn-sm { padding: 3px 12px; }

/* === SEARCH (GK.search) ==================================================
   System-wide quick search. It keeps using the existing .gk-search field and
   only adds the overlay and the result list. */
.gk-search-overlay {
  position: fixed;
  inset: 0;
  z-index: 9500;
  background: rgba(15, 23, 42, 0.45);
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding: 12vh 16px 16px;
  animation: gk-search-auf 0.12s ease-out;
}
@keyframes gk-search-auf {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.gk-search-box {
  width: 100%;
  max-width: 620px;
  background: var(--gk-surface);
  border: 1px solid var(--gk-border);
  border-radius: 14px;
  box-shadow: 0 20px 48px rgba(15, 23, 42, 0.22);
  overflow: hidden;
}
.gk-search-box .gk-search-feld {
  width: 100%;
  border: none;
  border-radius: 0;
  border-bottom: 1px solid var(--gk-border);
  padding: 16px 18px 16px 46px;
  font-size: var(--gk-text-subtitle);
  background-position: 18px center;
  background-color: var(--gk-surface);
  color: var(--gk-text);
}
.gk-search-box .gk-search-feld:focus-visible { box-shadow: none; border-color: var(--gk-border); }
.gk-search-liste { max-height: 58vh; overflow-y: auto; }
.gk-search-gruppe {
  padding: 10px 18px 4px;
  font-size: var(--gk-text-overline);
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--gk-text-muted);
}
.gk-search-treffer {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 18px;
  text-decoration: none;
  color: var(--gk-text);
  border-left: 3px solid transparent;
}
.gk-search-treffer.ist-aktiv {
  background: var(--gk-surface-container);
  border-left-color: var(--gk-primary);
}
.gk-search-icon { font-size: 20px; color: var(--gk-text-muted); flex: none; }
.gk-search-text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.gk-search-titel { font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gk-search-unter {
  font-size: var(--gk-text-caption);
  color: var(--gk-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.gk-search-betrag {
  font-size: var(--gk-text-body);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.gk-search-treffer mark { background: #fef08a; color: inherit; border-radius: 3px; padding: 0 1px; }
.gk-search-hinweis { padding: 22px 18px; text-align: center; color: var(--gk-text-muted); font-size: 13.5px; }
.gk-search-laedt {
  display: inline-block;
  width: 18px;
  height: 18px;
  border: 2px solid var(--gk-border);
  border-top-color: var(--gk-primary);
  border-radius: 50%;
  animation: gk-search-dreh 0.7s linear infinite;
}
@keyframes gk-search-dreh { to { transform: rotate(360deg); } }

/* Whoever asks for reduced motion gets it reduced everywhere — before, that
   applied to only two rules of the search. */
@media (prefers-reduced-motion: reduce) {
  .gk-root *,
  .gk-root *::before,
  .gk-root *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .gk-search-laedt { animation-duration: 2s !important; }
}
[data-theme="dark"] .gk-search-treffer mark { background: #854d0e; color: #fef9c3; }
[data-theme="dark"] .gk-search-overlay { background: rgba(0, 0, 0, 0.6); }

/* ===================================================================
   DERIVED STATE COLORS
   Deliberately at the end of the file: this block has to come after the
   fallback literals in the role block AND after every mode-dependent block,
   so that the derivation takes effect in every theme and in both modes.
   Older browsers without relative color syntax keep the literals.
   =================================================================== */
@supports (color: oklch(from red l c h)) {
  .gk-root,
  [data-gk-theme] {
    --gk-primary-hover: oklch(from var(--gk-primary) calc(l - 0.06) c h);
    --gk-tertiary-hover: oklch(from var(--gk-tertiary) calc(l - 0.06) c h);
    --gk-success-hover: oklch(from var(--gk-success) calc(l - 0.06) c h);
    --gk-error-hover: oklch(from var(--gk-error) calc(l - 0.06) c h);
    --gk-warning-hover: oklch(from var(--gk-warning) calc(l - 0.06) c h);
    /* Text roles: darkened further so the contrast holds on a light surface */
    /* -0.10 was not enough: it moved warning from 2.15:1 to 3.19:1, still under
       the 4.5:1 body text needs. */
    --gk-warning-text: oklch(from var(--gk-warning) calc(l - 0.22) c h);
    --gk-success-text: oklch(from var(--gk-success) calc(l - 0.22) c h);
    --gk-danger-text:  oklch(from var(--gk-error)   calc(l - 0.18) c h);
    --gk-primary-text: oklch(from var(--gk-primary) calc(l - 0.07) c h);
  }

    /* The text roles above are darkened for a LIGHT surface. In dark mode the
       role colours are already the light end of the scale and read at 7.6–8.8:1
       exactly as they are; darkening them by the same step landed them
       mid-range, the worst place against a dark ground — measured at 3.45:1
       for success, 3.92 for warning, 3.97 for danger. Later in source and at
       equal specificity, so this wins. */
    [data-gk-mode="dark"],
    [data-gk-mode="dark"] .gk-root,
    .gk-dark {
      --gk-warning-text: #fbbf24;
      --gk-success-text: #34d399;
      --gk-danger-text:  #fda4af;
    }
}

/* ===================================================================
   REFINEMENT — table, status, toolbar
   Deliberately at the end of the file: these rules refine existing components
   and therefore have to come after them in the cascade.
   =================================================================== */

/* ── Status pills carry meaning again ───────────────────────────────────
   The dot is not decoration: it tells the states apart even where color
   alone does not get through (color vision deficiency, greyscale print). */
.gk-label {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 9px 2px 7px;
}
.gk-label::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 9999px;
  background: currentColor;
  flex: none;
}
.gk-label-green::before { background: var(--gk-success); }
.gk-label-orange::before { background: var(--gk-warning); }
.gk-label-red::before { background: var(--gk-error); }
.gk-label-blue::before { background: var(--gk-info); }
.gk-label-gray::before { background: var(--gk-outline); }
/* For cases where the label is only a marker, not a state. */
.gk-label-plain::before { display: none; }

/* ── Row actions rest until the row is meant ────────────────────────────
   Delete is the rarest action and the only irreversible one — and it was the
   only one carrying a signal color on every row. Fifteen red waste baskets
   per screen are not a hint, they are noise.
   Nothing is hidden: the symbols stay visible, only colorless. */
/* Only where there is a mouse pointer. On touch devices :hover never fires —
   there the actions stayed permanently at 50 % opacity and desaturated, and
   were therefore indistinguishable from .gk-btn:disabled (0.45). */
@media (hover: hover) {
  .gk-table tbody td .gk-btn-icon-only,
  .gk-table tbody td.gk-actions .gk-btn {
    opacity: 0.5;
    filter: grayscale(1);
    transition:
      opacity var(--gk-dur-1) var(--gk-ease-out),
      filter var(--gk-dur-1) var(--gk-ease-out);
  }
}
.gk-table tbody tr:hover td .gk-btn-icon-only,
.gk-table tbody tr:hover td.gk-actions .gk-btn,
.gk-table tbody tr:focus-within td .gk-btn-icon-only,
.gk-table tbody tr:focus-within td.gk-actions .gk-btn,
.gk-table tbody td .gk-btn-icon-only:focus-visible,
.gk-table tbody td.gk-actions .gk-btn:focus-visible {
  opacity: 1;
  filter: none;
}

/* ── Numbers are not read, they are scanned ─────────────────────────────
   .gk-td-num already has tabular figures; what was missing is the weight that
   makes the column perceivable as a block. */
.gk-td-num {
  font-weight: 500;
}

/* ── The card carries itself ────────────────────────────────────────────
   Before, a hard border without elevation. Now the first elevation step, and
   the border retreats to a hairline. */
.gk-table-wrap {
  border-color: var(--gk-outline-variant);
  box-shadow: var(--gk-elev-1);
}
[data-gk-mode="dark"] .gk-table-wrap,
.gk-dark .gk-table-wrap {
  box-shadow: none;
}

/* ── The toolbar gets quieter ───────────────────────────────────────────
   The search field gets a surface of its own instead of a strong border, and
   steps forward onto the card surface on focus. */
.gk-toolbar .gk-search,
.gk-tableheader-toolbar .gk-search {
  background-color: var(--gk-surface-container-low);
  border-width: 1px;
}
.gk-toolbar .gk-search:focus-visible,
.gk-tableheader-toolbar .gk-search:focus-visible {
  background-color: var(--gk-surface);
}
/* Filters follow the pill shape of the other toolbar controls. */
.gk-toolbar .gk-filter,
.gk-tableheader-toolbar .gk-filter {
  border-radius: 9999px;
  padding-left: 14px;
}

/* ── Secondary columns step back ────────────────────────────────────────
   An article or document number is a reference, not content. In full text
   color it competes with the label beside it for the same glance.
   Column option: ['muted' => true] */
.gk-table td.gk-td-muted {
  color: var(--gk-on-surface-variant);
}

/* ===================================================================
   STATES
   Empty, disabled, loading. Between them these three had three CSS rules,
   while button and table have over a hundred each — even though these are
   exactly the states users see most often day to day.
   =================================================================== */

/* ── The empty state ────────────────────────────────────────────────────
   Before: one centered grey sentence. An empty table is not an error though,
   it is a situation — and that needs a statement, a way to place it and a
   way out of it. */
.gk-empty,
.gk-table td.gk-empty {
  text-align: center;
  padding: 56px 24px;
  color: var(--gk-on-surface-variant);
  font-size: var(--gk-text-body);
}
.gk-empty-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  max-width: 380px;
  margin: 0 auto;
}
/* Two classes deep, not one: the Material Icons stylesheet is usually included
   AFTER gridkit.css and sets .material-icons { font-size: 24px }. At equal
   specificity it then wins on source order. */
.gk-empty .gk-empty-icon {
  font-size: var(--gk-icon-3xl);
  color: var(--gk-outline);
  opacity: 0.5;
  margin-bottom: 4px;
}
.gk-empty-title {
  font-size: var(--gk-text-subtitle);
  font-weight: 600;
  line-height: var(--gk-leading-snug);
  color: var(--gk-on-surface);
}
.gk-empty-hint {
  font-size: var(--gk-text-body);
  line-height: var(--gk-leading-normal);
  color: var(--gk-on-surface-variant);
  text-wrap: pretty;
}
.gk-empty-action {
  margin-top: 10px;
}
/* The empty row carries no row highlight. */
.gk-table tbody tr.gk-empty-row:hover > td,
.gk-table tbody tr.gk-empty-row:hover > td:first-child {
  background: transparent;
  box-shadow: none;
}

/* ── Disabled states ────────────────────────────────────────────────────
   Until now there was exactly one rule for this (.gk-btn:disabled). A disabled
   input looked like an editable one — you only noticed on clicking it. With
   forms that carry permission logic that is a daily annoyance, and for screen
   reader users it is the only hint there is at all. */
.gk-input:disabled,
select.gk-input:disabled,
textarea.gk-input:disabled,
.gk-search:disabled,
.gk-filter:disabled {
  background-color: var(--gk-surface-container);
  border-color: var(--gk-outline-variant);
  color: var(--gk-on-surface-variant);
  cursor: not-allowed;
  box-shadow: none;
}
.gk-input:disabled::placeholder {
  color: var(--gk-outline);
}
/* Read-only is something other than disabled: the value still counts and the
   field stays focusable. Hence quieter, but without the not-allowed cursor. */
.gk-input[readonly],
textarea.gk-input[readonly] {
  background-color: var(--gk-surface-container-low);
  border-style: dashed;
}
/* The markup is <label class="gk-checkbox-wrap"><input type="checkbox">…;
   the input carries NO class of its own. Selectors on .gk-checkbox or on a
   .gk-label-wrap therefore hit nothing. */
.gk-checkbox-wrap:has(input:disabled),
.gk-radio-wrap:has(input:disabled) {
  cursor: not-allowed;
}
.gk-checkbox-wrap input:disabled ~ *,
.gk-radio-wrap input:disabled ~ * {
  opacity: 0.5;
  cursor: not-allowed;
}
.gk-field:has(.gk-input:disabled) .gk-label-text {
  color: var(--gk-outline);
}
/* Controls that are not a <button> must be disableable too. */
.gk-btn[aria-disabled="true"],
a.gk-btn[aria-disabled="true"],
.gk-disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

/* ── Loading state ──────────────────────────────────────────────────────
   GridKit advertises that tables search and filter without a reload — and so
   far gave no visible feedback for it. The content simply jumped. The existing
   rows now stay in place and step back; a bar shows that work is happening.
   No jumping, no dead time. */
/* Form.php puts `gk-spin` on a Material Icons `sync` glyph — for the AJAX
   select's loading line and the upload indicator. The keyframes below existed
   and nothing ever applied them to this class, so both "loading" icons sat
   perfectly still. The general prefers-reduced-motion block stops it. */
.gk-spin {
  display: inline-block;
  animation: gk-spin 0.9s linear infinite;
}

.gk-table-wrap[data-gk-loading],
.gk-live-loading {
  position: relative;
}
/* Track and bar live in ONE pseudo element as two background layers.
   A second, absolutely positioned element would be wrong here:
   .gk-table-wrap is deliberately set to overflow: visible so that dropdowns may
   stick out of the card — a traveling bar would then paint past the card edge
   and trigger horizontal scrolling. Backgrounds, by contrast, are always
   clipped to the box. */
/* GK.liveTable adds .gk-live-loading around its fetch and removes it after.
   Nothing styled it, so a live table gave no sign at all that it was working —
   the rows simply sat there until new ones appeared. */
.gk-table-wrap[data-gk-loading]::after,
.gk-live-loading::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 2px;
  z-index: 2;
  background-image:
    linear-gradient(90deg, transparent, var(--gk-primary), transparent),
    linear-gradient(
      color-mix(in oklab, var(--gk-primary) 18%, transparent),
      color-mix(in oklab, var(--gk-primary) 18%, transparent)
    );
  background-size: 40% 100%, 100% 100%;
  background-repeat: no-repeat;
  animation: gk-ladebalken 1.1s var(--gk-ease-in-out) infinite;
}
@keyframes gk-ladebalken {
  0% { background-position: -45% 0, 0 0; }
  100% { background-position: 145% 0, 0 0; }
}
/* The toolbar stays operable — only the content waits. */
.gk-table-wrap[data-gk-loading] .gk-table,
.gk-table-wrap[data-gk-loading] .gk-rowpager,
.gk-live-loading .gk-table,
.gk-live-loading .gk-rowpager {
  opacity: 0.45;
  pointer-events: none;
  transition: opacity var(--gk-dur-2) var(--gk-ease-out);
}

/* Placeholder rows for the first build-up, when nothing is there yet.
   Usage: <td><span class="gk-skeleton" style="width:60%"></span></td> */
.gk-skeleton {
  display: inline-block;
  height: 0.75em;
  min-width: 2em;
  border-radius: var(--gk-radius-sm);
  background: linear-gradient(
    90deg,
    var(--gk-surface-container) 0%,
    var(--gk-surface-container-high) 50%,
    var(--gk-surface-container) 100%
  );
  background-size: 200% 100%;
  animation: gk-skelett 1.4s var(--gk-ease-in-out) infinite;
  vertical-align: middle;
}
@keyframes gk-skelett {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* ── Field surfaces made uniform ────────────────────────────────────────
   The search field had been given a surface of its own, the form fields had
   not — two input fields, two appearances. Both now carry the same restrained
   surface AND their border: the surface makes them soft, the border keeps them
   visible even where the container happens to have the same color. */
.gk-input,
.gk-search,
.gk-filter {
  background-color: var(--gk-surface-container-low);
}
.gk-input:focus-visible,
.gk-search:focus-visible,
.gk-filter:focus-visible {
  background-color: var(--gk-surface);
}
/* A read-only field keeps its quiet surface on focus too — that is exactly
   when the hint "nothing can be entered here" is needed. */
.gk-input[readonly]:focus-visible,
textarea.gk-input[readonly]:focus-visible {
  background-color: var(--gk-surface-container-low);
}

/* ── Enforce icon sizes against the icon stylesheet ─────────────────────
   The Material Icons stylesheet is usually included AFTER gridkit.css and sets
   .material-icons { font-size: 24px }. At equal specificity source order
   decides — GridKit's own sizes have therefore been losing silently up to now
   (demonstrable on .gk-sidebar-icon and .gk-select-arrow: set to 20px and 18px
   respectively, rendered at 24px). Two classes deep they win again, without
   !important. */
.material-icons.gk-uq-icon,
.material-symbols-outlined.gk-uq-icon,
.material-symbols-rounded.gk-uq-icon {
  font-size: var(--gk-icon-md);
}
.material-icons.gk-modal-close,
.material-symbols-outlined.gk-modal-close,
.material-symbols-rounded.gk-modal-close {
  font-size: var(--gk-icon-lg);
}
.material-icons.gk-chip-icon,
.material-symbols-outlined.gk-chip-icon,
.material-symbols-rounded.gk-chip-icon {
  font-size: var(--gk-icon-xs);
}
.material-icons.gk-stat-icon,
.material-symbols-outlined.gk-stat-icon,
.material-symbols-rounded.gk-stat-icon {
  font-size: var(--gk-icon-2xl);
}
.material-icons.gk-sidebar-brand-icon,
.material-symbols-outlined.gk-sidebar-brand-icon,
.material-symbols-rounded.gk-sidebar-brand-icon {
  font-size: var(--gk-icon-2xl);
}
.material-icons.gk-sidebar-icon,
.material-symbols-outlined.gk-sidebar-icon,
.material-symbols-rounded.gk-sidebar-icon {
  font-size: var(--gk-icon-md);
}
.material-icons.gk-toast-icon,
.material-symbols-outlined.gk-toast-icon,
.material-symbols-rounded.gk-toast-icon {
  font-size: var(--gk-icon-lg);
}
.material-icons.gk-toast-close,
.material-symbols-outlined.gk-toast-close,
.material-symbols-rounded.gk-toast-close {
  font-size: var(--gk-icon-sm);
}
.material-icons.gk-lightbox-close,
.material-symbols-outlined.gk-lightbox-close,
.material-symbols-rounded.gk-lightbox-close {
  font-size: var(--gk-icon-md);
}
.material-icons.gk-select-arrow,
.material-symbols-outlined.gk-select-arrow,
.material-symbols-rounded.gk-select-arrow {
  font-size: var(--gk-icon-md);
}
.material-icons.gk-ajax-clear,
.material-symbols-outlined.gk-ajax-clear,
.material-symbols-rounded.gk-ajax-clear {
  font-size: var(--gk-icon-sm);
}
.material-icons.gk-select-icon,
.material-symbols-outlined.gk-select-icon,
.material-symbols-rounded.gk-select-icon {
  font-size: var(--gk-icon-md);
}

/* Motion sensitivity — exceptions for the loading feedback.
   Deliberately down here: the general prefers-reduced-motion block sits around
   400 lines further up, that is BEFORE the rules it is meant to override.
   At equal specificity source order decides — up there only the !important
   declarations would have won, and the bar would have stayed frozen at 40 %
   width instead of appearing as a full bar. */
@media (prefers-reduced-motion: reduce) {
  /* No traveling, but still visible: otherwise these very users would have no
     feedback at all any more. */
  .gk-table-wrap[data-gk-loading]::after {
    animation: none;
    background-size: 100% 100%, 100% 100%;
    background-position: 0 0, 0 0;
    opacity: 0.75;
  }
  .gk-skeleton {
    animation: none;
    background: var(--gk-surface-container-high);
  }
}
