/* ==========================================================================
   VEKMOT DESIGN SYSTEM — GENERATED BUNDLE
   --------------------------------------------------------------------------
   DO NOT EDIT. Generated by instance/build_css.py from vekmot.css.
   Edit the source layer files and re-run the script.

   Layer order:
      1. tokens/primitives.css
      2. tokens/semantic.css
      3. tokens/zones.css
      4. base/reset.css
      5. base/typography.css
      6. base/layout.css
      7. base/csp-utilities.css
      8. base/icons.css
      9. base/accessibility.css
     10. components/controls.css
     11. components/surfaces.css
     12. components/feedback.css
     13. components/overlays.css
     14. components/navigation.css
     15. components/domain.css
     16. layouts/shells.css
   ========================================================================== */

/* ==========================================================================
   VEKMOT DESIGN SYSTEM — LAYER 1: PRIMITIVES
   --------------------------------------------------------------------------
   Raw, context-free values. These are the only place literal colours,
   sizes and durations may be declared.

   Primitives must never be referenced directly by a component.
   Components consume the semantic layer (tokens/semantic.css) or the
   zone layer (tokens/zones.css), which alias these values.

   Colour space is OKLCH for perceptually uniform ramps: a fixed lightness
   step produces a matching perceived step across every hue, which is what
   keeps the zone accents feeling like one family.

   Naming: --vk-<family>-<step>. Step 500 is the base tone of every hue.
   ========================================================================== */

:root {
  /* ----------------------------------------------------------------------
     GRAPHITE — the Vekmot core neutral (hue 262, near-zero chroma)
     Carries a trace of blue so it reads as engineered graphite, not mud.
     ---------------------------------------------------------------------- */
  --vk-graphite-0: oklch(1 0 0);
  --vk-graphite-25: oklch(0.994 0.0015 262);
  --vk-graphite-50: oklch(0.982 0.002 262);
  --vk-graphite-100: oklch(0.968 0.003 262);
  --vk-graphite-150: oklch(0.952 0.0035 262);
  --vk-graphite-200: oklch(0.918 0.004 262);
  --vk-graphite-300: oklch(0.86 0.006 262);
  --vk-graphite-400: oklch(0.72 0.012 262);
  --vk-graphite-500: oklch(0.6 0.016 262);
  --vk-graphite-600: oklch(0.53 0.018 262);
  --vk-graphite-700: oklch(0.42 0.018 262);
  --vk-graphite-800: oklch(0.3 0.016 262);
  --vk-graphite-850: oklch(0.255 0.014 262);
  --vk-graphite-900: oklch(0.207 0.014 262);
  --vk-graphite-950: oklch(0.17 0.012 262);
  --vk-graphite-1000: oklch(0.12 0.01 262);

  /* ----------------------------------------------------------------------
     COBALT — Workforce zone (hue 255)
     ---------------------------------------------------------------------- */
  --vk-cobalt-50: oklch(0.972 0.016 255);
  --vk-cobalt-100: oklch(0.95 0.035 255);
  --vk-cobalt-200: oklch(0.9 0.06 255);
  --vk-cobalt-300: oklch(0.8 0.1 255);
  --vk-cobalt-400: oklch(0.65 0.145 255);
  --vk-cobalt-500: oklch(0.49 0.16 255);
  --vk-cobalt-600: oklch(0.43 0.155 255);
  --vk-cobalt-700: oklch(0.37 0.135 255);
  --vk-cobalt-800: oklch(0.3 0.1 255);
  --vk-cobalt-900: oklch(0.25 0.07 255);

  /* ----------------------------------------------------------------------
     INDIGO — Customer Payments zone (hue 275)
     ---------------------------------------------------------------------- */
  --vk-indigo-50: oklch(0.972 0.016 275);
  --vk-indigo-100: oklch(0.95 0.035 275);
  --vk-indigo-200: oklch(0.9 0.062 275);
  --vk-indigo-300: oklch(0.79 0.105 275);
  --vk-indigo-400: oklch(0.64 0.15 275);
  --vk-indigo-500: oklch(0.48 0.17 275);
  --vk-indigo-600: oklch(0.42 0.165 275);
  --vk-indigo-700: oklch(0.36 0.145 275);
  --vk-indigo-800: oklch(0.3 0.11 275);
  --vk-indigo-900: oklch(0.25 0.075 275);

  /* ----------------------------------------------------------------------
     CYAN — restrained secondary for Payments and VEKRYN (hue 215)
     Deliberately low chroma. Cyan is a supporting signal in Vekmot,
     never a primary surface or a decorative glow.
     ---------------------------------------------------------------------- */
  --vk-cyan-50: oklch(0.975 0.014 215);
  --vk-cyan-100: oklch(0.95 0.03 215);
  --vk-cyan-200: oklch(0.9 0.055 215);
  --vk-cyan-300: oklch(0.83 0.08 215);
  --vk-cyan-400: oklch(0.78 0.1 215);
  --vk-cyan-500: oklch(0.72 0.11 215);
  --vk-cyan-600: oklch(0.62 0.105 215);
  --vk-cyan-700: oklch(0.52 0.09 215);
  --vk-cyan-800: oklch(0.4 0.07 215);
  --vk-cyan-900: oklch(0.3 0.05 215);

  /* ----------------------------------------------------------------------
     AZURE — Analytics / Insights zone (hue 240)
     ---------------------------------------------------------------------- */
  --vk-azure-50: oklch(0.973 0.015 240);
  --vk-azure-100: oklch(0.95 0.035 240);
  --vk-azure-200: oklch(0.9 0.06 240);
  --vk-azure-300: oklch(0.81 0.1 240);
  --vk-azure-400: oklch(0.7 0.14 240);
  --vk-azure-500: oklch(0.58 0.16 240);
  --vk-azure-600: oklch(0.5 0.15 240);
  --vk-azure-700: oklch(0.42 0.13 240);
  --vk-azure-800: oklch(0.33 0.1 240);
  --vk-azure-900: oklch(0.26 0.07 240);

  /* ----------------------------------------------------------------------
     VIOLET — VEKRYN zone (hue 295)
     ---------------------------------------------------------------------- */
  --vk-violet-50: oklch(0.972 0.016 295);
  --vk-violet-100: oklch(0.95 0.035 295);
  --vk-violet-200: oklch(0.89 0.06 295);
  --vk-violet-300: oklch(0.77 0.1 295);
  --vk-violet-400: oklch(0.6 0.135 295);
  --vk-violet-500: oklch(0.42 0.15 295);
  --vk-violet-600: oklch(0.37 0.14 295);
  --vk-violet-700: oklch(0.32 0.12 295);
  --vk-violet-800: oklch(0.27 0.095 295);
  --vk-violet-900: oklch(0.23 0.065 295);

  /* ----------------------------------------------------------------------
     LUMINOUS GREEN — Super Admin zone (hue 145)
     Signals live telemetry and system health. Used as a signal accent on
     graphite, never as a large fill — that is what keeps it operational
     rather than cyberpunk.
     ---------------------------------------------------------------------- */
  --vk-green-50: oklch(0.97 0.02 145);
  --vk-green-100: oklch(0.94 0.045 145);
  --vk-green-200: oklch(0.89 0.08 145);
  --vk-green-300: oklch(0.82 0.13 145);
  --vk-green-400: oklch(0.75 0.16 145);
  --vk-green-500: oklch(0.67 0.18 145);
  --vk-green-600: oklch(0.58 0.16 145);
  --vk-green-700: oklch(0.47 0.13 145);
  --vk-green-800: oklch(0.36 0.1 145);
  --vk-green-900: oklch(0.28 0.07 145);

  /* ----------------------------------------------------------------------
     STATUS HUES — semantic feedback only, never zone identity
     ---------------------------------------------------------------------- */
  --vk-red-50: oklch(0.971 0.018 26);
  --vk-red-100: oklch(0.945 0.04 26);
  --vk-red-200: oklch(0.89 0.08 26);
  --vk-red-300: oklch(0.79 0.14 26);
  --vk-red-400: oklch(0.68 0.19 26);
  --vk-red-500: oklch(0.585 0.222 26);
  --vk-red-600: oklch(0.51 0.205 26);
  --vk-red-700: oklch(0.43 0.17 26);
  --vk-red-800: oklch(0.34 0.13 26);
  --vk-red-900: oklch(0.27 0.09 26);

  --vk-amber-50: oklch(0.978 0.022 72);
  --vk-amber-100: oklch(0.955 0.05 72);
  --vk-amber-200: oklch(0.91 0.09 72);
  --vk-amber-300: oklch(0.85 0.12 72);
  --vk-amber-400: oklch(0.79 0.14 72);
  --vk-amber-500: oklch(0.72 0.15 72);
  --vk-amber-600: oklch(0.62 0.14 72);
  --vk-amber-700: oklch(0.5 0.115 72);
  --vk-amber-800: oklch(0.39 0.09 72);
  --vk-amber-900: oklch(0.3 0.065 72);

  --vk-emerald-50: oklch(0.972 0.018 158);
  --vk-emerald-100: oklch(0.945 0.04 158);
  --vk-emerald-200: oklch(0.89 0.07 158);
  --vk-emerald-300: oklch(0.8 0.1 158);
  --vk-emerald-400: oklch(0.69 0.12 158);
  --vk-emerald-500: oklch(0.58 0.13 158);
  --vk-emerald-600: oklch(0.5 0.12 158);
  --vk-emerald-700: oklch(0.42 0.1 158);
  --vk-emerald-800: oklch(0.33 0.08 158);
  --vk-emerald-900: oklch(0.26 0.055 158);

  --vk-blue-50: oklch(0.973 0.016 244);
  --vk-blue-100: oklch(0.948 0.036 244);
  --vk-blue-200: oklch(0.9 0.06 244);
  --vk-blue-300: oklch(0.81 0.095 244);
  --vk-blue-400: oklch(0.7 0.12 244);
  --vk-blue-500: oklch(0.58 0.13 244);
  --vk-blue-600: oklch(0.5 0.125 244);
  --vk-blue-700: oklch(0.42 0.105 244);
  --vk-blue-800: oklch(0.33 0.085 244);
  --vk-blue-900: oklch(0.26 0.06 244);

  /* ----------------------------------------------------------------------
     TYPEFACE
     Inter is the Vekmot primary typeface. The stack degrades to the host
     system UI font so the product renders correctly with no network font.
     Noto Sans Arabic is included ahead of the generic fallback so Arabic
     copy is typographically correct from the first render, not retrofitted.
     ---------------------------------------------------------------------- */
  --vk-font-sans: "Inter", "Inter var", -apple-system, BlinkMacSystemFont,
    "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans",
    "Noto Sans Arabic", "Segoe UI Arabic", sans-serif;
  --vk-font-mono: "Geist Mono", ui-monospace, SFMono-Regular, "SF Mono",
    "JetBrains Mono", Menlo, Consolas, "Liberation Mono", monospace;

  /* TYPE SCALE — six sizes only. A constrained scale is what makes
     unrelated screens look like one product. */
  --vk-text-2xs: 0.6875rem; /* 11px — dense table meta, never body copy */
  --vk-text-xs: 0.75rem; /*  12px — labels, captions, table meta */
  --vk-text-sm: 0.875rem; /*  14px — dense UI, table cells, controls */
  --vk-text-base: 1rem; /*  16px — body copy, default */
  --vk-text-lg: 1.25rem; /*  20px — card and section titles */
  --vk-text-xl: 1.5rem; /*  24px — page titles */
  --vk-text-2xl: 2rem; /*  32px — display, key metrics */

  /* LINE HEIGHT — tight for headings, comfortable for prose */
  --vk-leading-none: 1;
  --vk-leading-tight: 1.25;
  --vk-leading-snug: 1.375;
  --vk-leading-normal: 1.5;
  --vk-leading-relaxed: 1.625;

  /* WEIGHT — three weights only */
  --vk-weight-regular: 400;
  --vk-weight-medium: 500;
  --vk-weight-semibold: 600;

  /* TRACKING — negative on large sizes keeps display text optically tight */
  --vk-tracking-tight: -0.02em;
  --vk-tracking-snug: -0.011em;
  --vk-tracking-normal: 0;
  --vk-tracking-wide: 0.02em;
  --vk-tracking-caps: 0.06em;

  /* ----------------------------------------------------------------------
     SPACING — 4px base. These ten values are the complete vocabulary.
     ---------------------------------------------------------------------- */
  --vk-space-0: 0;
  --vk-space-1: 4px;
  --vk-space-2: 8px;
  --vk-space-3: 12px;
  --vk-space-4: 16px;
  --vk-space-5: 20px;
  --vk-space-6: 24px;
  --vk-space-8: 32px;
  --vk-space-10: 40px;
  --vk-space-12: 48px;
  --vk-space-16: 64px;

  /* ----------------------------------------------------------------------
     RADIUS — restrained. Precise, not playful.
     ---------------------------------------------------------------------- */
  --vk-radius-sm: 6px; /* controls, badges, inputs */
  --vk-radius-md: 10px; /* cards, panels, menus */
  --vk-radius-lg: 14px; /* modals, drawers, large surfaces */
  --vk-radius-full: 999px; /* avatars, pills, status dots */

  /* ----------------------------------------------------------------------
     SHADOW — subtle depth. Layered rather than blurred, so surfaces read
     as lifted paper instead of glowing glass.
     ---------------------------------------------------------------------- */
  --vk-shadow-xs: 0 1px 2px oklch(0.17 0.012 262 / 0.05);
  --vk-shadow-sm: 0 1px 2px oklch(0.17 0.012 262 / 0.06),
    0 1px 3px oklch(0.17 0.012 262 / 0.04);
  --vk-shadow-md: 0 2px 4px oklch(0.17 0.012 262 / 0.05),
    0 4px 8px oklch(0.17 0.012 262 / 0.05);
  --vk-shadow-lg: 0 4px 8px oklch(0.17 0.012 262 / 0.05),
    0 12px 24px oklch(0.17 0.012 262 / 0.08);
  --vk-shadow-xl: 0 8px 16px oklch(0.17 0.012 262 / 0.06),
    0 24px 48px oklch(0.17 0.012 262 / 0.12);

  /* ----------------------------------------------------------------------
     MOTION — 120–200ms. Long enough to read, short enough to stay out of
     the way. Only opacity, transform and small positional transitions.
     ---------------------------------------------------------------------- */
  --vk-duration-instant: 80ms;
  --vk-duration-fast: 120ms;
  --vk-duration-base: 160ms;
  --vk-duration-slow: 200ms;

  --vk-ease-standard: cubic-bezier(0.2, 0, 0.2, 1);
  --vk-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --vk-ease-in: cubic-bezier(0.4, 0, 1, 1);

  --vk-transition-colors: color var(--vk-duration-fast) var(--vk-ease-standard),
    background-color var(--vk-duration-fast) var(--vk-ease-standard),
    border-color var(--vk-duration-fast) var(--vk-ease-standard),
    box-shadow var(--vk-duration-fast) var(--vk-ease-standard);

  /* ----------------------------------------------------------------------
     Z-INDEX — a fixed ladder. Never invent an arbitrary z-index.
     ---------------------------------------------------------------------- */
  --vk-z-base: 0;
  --vk-z-raised: 10;
  --vk-z-sticky: 100;
  --vk-z-shell: 200; /* sidebar, topbar */
  --vk-z-dropdown: 300;
  --vk-z-overlay: 400; /* modal / drawer scrim */
  --vk-z-modal: 500;
  --vk-z-command: 600; /* command palette sits above modals */
  --vk-z-toast: 700;
  --vk-z-tooltip: 800;

  /* ----------------------------------------------------------------------
     BREAKPOINTS — documented as tokens for reference.
     CSS cannot evaluate custom properties inside @media, so the literal
     values below are repeated in media queries. They are the ONLY
     breakpoints permitted anywhere in the system.

       --vk-bp-sm   640px   large phone
       --vk-bp-md   768px   tablet portrait
       --vk-bp-lg  1024px   tablet landscape / small laptop
       --vk-bp-xl  1280px   desktop
       --vk-bp-2xl 1536px   large desktop
     ---------------------------------------------------------------------- */
  --vk-bp-sm: 640px;
  --vk-bp-md: 768px;
  --vk-bp-lg: 1024px;
  --vk-bp-xl: 1280px;
  --vk-bp-2xl: 1536px;

  /* ----------------------------------------------------------------------
     SIZING — control heights and layout rails
     44px is the WCAG 2.2 AA minimum touch target and is the floor for any
     interactive control on touch viewports.
     ---------------------------------------------------------------------- */
  --vk-control-height-sm: 32px;
  --vk-control-height-md: 40px;
  --vk-control-height-lg: 48px;
  --vk-touch-target-min: 44px;

  --vk-icon-sm: 14px;
  --vk-icon-md: 16px;
  --vk-icon-lg: 20px;
  --vk-icon-xl: 24px;

  --vk-sidebar-width: 264px;
  --vk-sidebar-rail-width: 64px;
  --vk-topbar-height: 56px;
  --vk-mobile-nav-height: 56px;
  --vk-content-max-width: 1440px;
  --vk-prose-max-width: 68ch;

  --vk-border-width: 1px;
  --vk-focus-ring-width: 2px;
  --vk-focus-ring-offset: 2px;
}

/* ==========================================================================
   VEKMOT DESIGN SYSTEM — LAYER 2: SEMANTIC ROLES
   --------------------------------------------------------------------------
   Maps primitives onto roles that describe PURPOSE, not appearance.
   A component asks for "the muted text colour", never "graphite 600".

   This is the layer that themes. Light is the default; dark is applied by
   [data-theme="dark"] on <html>, and also honoured automatically when the
   user's OS prefers dark and no explicit theme has been chosen.

   Rule: if a component needs a colour that is not expressed here or in
   tokens/zones.css, the token layer is incomplete — extend it here rather
   than hard-coding a value in the component.
   ========================================================================== */

:root {
  color-scheme: light;

  /* ---------------------------------------------------------------- SURFACE
     page      the application background
     raised    cards, panels, table surfaces — sits above page
     overlay   modals, popovers, dropdowns — sits above everything
     sunken    wells, code blocks, inset regions
     hover/active are interaction states for any raised surface           */
  --vk-surface-page: var(--vk-graphite-25);
  --vk-surface-raised: var(--vk-graphite-0);
  --vk-surface-overlay: var(--vk-graphite-0);
  --vk-surface-sunken: var(--vk-graphite-100);
  --vk-surface-hover: var(--vk-graphite-100);
  --vk-surface-active: var(--vk-graphite-150);
  --vk-surface-selected: var(--vk-graphite-100);
  --vk-surface-disabled: var(--vk-graphite-100);
  --vk-surface-inverse: var(--vk-graphite-950);
  --vk-surface-scrim: oklch(0.17 0.012 262 / 0.45);

  /* ------------------------------------------------------------------- TEXT
     primary    body and headings
     secondary  supporting copy
     muted      labels, captions, table headers, meta
     disabled   non-interactive text — never used for meaning
     inverse    text on --vk-surface-inverse
     on-accent  text on a filled accent surface                            */
  --vk-text-primary: var(--vk-graphite-950);
  --vk-text-secondary: var(--vk-graphite-700);
  --vk-text-muted: var(--vk-graphite-600);
  --vk-text-disabled: var(--vk-graphite-400);
  --vk-text-inverse: var(--vk-graphite-50);
  --vk-text-on-accent: var(--vk-graphite-0);
  --vk-text-link: var(--vk-accent-strong);

  /* ----------------------------------------------------------------- BORDER */
  --vk-border-subtle: var(--vk-graphite-150);
  --vk-border-default: var(--vk-graphite-200);
  --vk-border-strong: var(--vk-graphite-300);
  --vk-border-inverse: oklch(1 0 0 / 0.14);
  --vk-border-focus: var(--vk-accent-strong);

  /* ------------------------------------------------------------------ ACCENT
     The accent role is what a zone overrides. Unscoped UI resolves to the
     Vekmot core identity: graphite. Setting [data-zone] on any ancestor
     re-points these four tokens and every descendant component follows.   */
  --vk-accent-subtle: var(--vk-graphite-100);
  --vk-accent-muted: var(--vk-graphite-300);
  --vk-accent-strong: var(--vk-graphite-900);
  --vk-accent-stronger: var(--vk-graphite-950);
  --vk-accent-on: var(--vk-graphite-0);
  --vk-accent-ring: oklch(0.17 0.012 262 / 0.28);

  /* ------------------------------------------------------------------ STATUS
     Each status exposes four roles so state can be shown structurally
     (icon + label + surface), never by colour alone — a WCAG 2.2
     requirement and the reason every status has a paired icon convention. */
  --vk-success-surface: var(--vk-emerald-50);
  --vk-success-border: var(--vk-emerald-200);
  --vk-success-text: var(--vk-emerald-700);
  --vk-success-solid: var(--vk-emerald-500);
  --vk-success-on-solid: var(--vk-graphite-0);

  --vk-warning-surface: var(--vk-amber-50);
  --vk-warning-border: var(--vk-amber-200);
  --vk-warning-text: var(--vk-amber-800);
  --vk-warning-solid: var(--vk-amber-500);
  --vk-warning-on-solid: var(--vk-graphite-950);

  --vk-danger-surface: var(--vk-red-50);
  --vk-danger-border: var(--vk-red-200);
  --vk-danger-text: var(--vk-red-700);
  --vk-danger-solid: var(--vk-red-500);
  --vk-danger-on-solid: var(--vk-graphite-0);

  --vk-info-surface: var(--vk-blue-50);
  --vk-info-border: var(--vk-blue-200);
  --vk-info-text: var(--vk-blue-700);
  --vk-info-solid: var(--vk-blue-500);
  --vk-info-on-solid: var(--vk-graphite-0);

  /* Neutral status — pending, draft, archived, cancelled.
     Deliberately colourless: an inert state must not compete with a
     live one for attention. */
  --vk-neutral-surface: var(--vk-graphite-100);
  --vk-neutral-border: var(--vk-graphite-200);
  --vk-neutral-text: var(--vk-graphite-700);
  --vk-neutral-solid: var(--vk-graphite-500);
  --vk-neutral-on-solid: var(--vk-graphite-0);

  /* ------------------------------------------------------------------- CHART
     Data visualisation ramp. Ordered for categorical series; the first
     three are distinguishable under the common forms of colour blindness. */
  --vk-chart-1: var(--vk-azure-500);
  --vk-chart-2: var(--vk-emerald-500);
  --vk-chart-3: var(--vk-amber-500);
  --vk-chart-4: var(--vk-violet-400);
  --vk-chart-5: var(--vk-cyan-600);
  --vk-chart-6: var(--vk-graphite-500);
  --vk-chart-grid: var(--vk-graphite-150);
  --vk-chart-axis: var(--vk-graphite-400);

  /* -------------------------------------------------------------- ELEVATION */
  --vk-elevation-raised: var(--vk-shadow-sm);
  --vk-elevation-dropdown: var(--vk-shadow-md);
  --vk-elevation-modal: var(--vk-shadow-xl);
  --vk-elevation-toast: var(--vk-shadow-lg);
}

/* ==========================================================================
   DARK THEME
   --------------------------------------------------------------------------
   Not an inversion. Surfaces step UP in lightness as they come forward,
   which is how depth reads correctly on a dark background, and borders
   become translucent white so they sit on any surface in the stack.
   ========================================================================== */

[data-theme="dark"] {
  color-scheme: dark;

  --vk-surface-page: var(--vk-graphite-950);
  --vk-surface-raised: var(--vk-graphite-900);
  --vk-surface-overlay: var(--vk-graphite-850);
  --vk-surface-sunken: var(--vk-graphite-1000);
  --vk-surface-hover: oklch(1 0 0 / 0.05);
  --vk-surface-active: oklch(1 0 0 / 0.08);
  --vk-surface-selected: oklch(1 0 0 / 0.07);
  --vk-surface-disabled: oklch(1 0 0 / 0.04);
  --vk-surface-inverse: var(--vk-graphite-50);
  --vk-surface-scrim: oklch(0.12 0.01 262 / 0.65);

  --vk-text-primary: var(--vk-graphite-50);
  --vk-text-secondary: var(--vk-graphite-300);
  --vk-text-muted: var(--vk-graphite-400);
  --vk-text-disabled: var(--vk-graphite-600);
  --vk-text-inverse: var(--vk-graphite-950);
  --vk-text-on-accent: var(--vk-graphite-950);

  --vk-border-subtle: oklch(1 0 0 / 0.07);
  --vk-border-default: oklch(1 0 0 / 0.11);
  --vk-border-strong: oklch(1 0 0 / 0.18);
  --vk-border-inverse: oklch(0.17 0.012 262 / 0.14);

  --vk-accent-subtle: oklch(1 0 0 / 0.08);
  --vk-accent-muted: var(--vk-graphite-600);
  --vk-accent-strong: var(--vk-graphite-100);
  --vk-accent-stronger: var(--vk-graphite-0);
  --vk-accent-on: var(--vk-graphite-950);
  --vk-accent-ring: oklch(1 0 0 / 0.32);

  /* Status surfaces become deep tints rather than pale washes so they
     remain legible without glowing. */
  --vk-success-surface: oklch(0.26 0.055 158);
  --vk-success-border: oklch(0.42 0.1 158);
  --vk-success-text: var(--vk-emerald-300);
  --vk-success-solid: var(--vk-emerald-400);
  --vk-success-on-solid: var(--vk-graphite-950);

  --vk-warning-surface: oklch(0.3 0.065 72);
  --vk-warning-border: oklch(0.5 0.115 72);
  --vk-warning-text: var(--vk-amber-300);
  --vk-warning-solid: var(--vk-amber-400);
  --vk-warning-on-solid: var(--vk-graphite-950);

  --vk-danger-surface: oklch(0.27 0.09 26);
  --vk-danger-border: oklch(0.43 0.17 26);
  --vk-danger-text: var(--vk-red-300);
  --vk-danger-solid: var(--vk-red-400);
  --vk-danger-on-solid: var(--vk-graphite-950);

  --vk-info-surface: oklch(0.26 0.06 244);
  --vk-info-border: oklch(0.42 0.105 244);
  --vk-info-text: var(--vk-blue-300);
  --vk-info-solid: var(--vk-blue-400);
  --vk-info-on-solid: var(--vk-graphite-950);

  --vk-neutral-surface: oklch(1 0 0 / 0.06);
  --vk-neutral-border: oklch(1 0 0 / 0.12);
  --vk-neutral-text: var(--vk-graphite-300);
  --vk-neutral-solid: var(--vk-graphite-500);
  --vk-neutral-on-solid: var(--vk-graphite-950);

  --vk-chart-1: var(--vk-azure-400);
  --vk-chart-2: var(--vk-emerald-400);
  --vk-chart-3: var(--vk-amber-400);
  --vk-chart-4: var(--vk-violet-300);
  --vk-chart-5: var(--vk-cyan-400);
  --vk-chart-6: var(--vk-graphite-400);
  --vk-chart-grid: oklch(1 0 0 / 0.08);
  --vk-chart-axis: var(--vk-graphite-500);

  /* Shadows carry almost no weight on dark surfaces; depth comes from
     the surface ramp instead. */
  --vk-shadow-xs: 0 1px 2px oklch(0 0 0 / 0.3);
  --vk-shadow-sm: 0 1px 2px oklch(0 0 0 / 0.35), 0 1px 3px oklch(0 0 0 / 0.25);
  --vk-shadow-md: 0 2px 4px oklch(0 0 0 / 0.35), 0 4px 8px oklch(0 0 0 / 0.3);
  --vk-shadow-lg: 0 4px 8px oklch(0 0 0 / 0.35), 0 12px 24px oklch(0 0 0 / 0.4);
  --vk-shadow-xl: 0 8px 16px oklch(0 0 0 / 0.4), 0 24px 48px oklch(0 0 0 / 0.5);
}

/* Honour the OS preference only when the product has not been explicitly
   themed. An explicit [data-theme="light"] always wins. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not([data-theme="dark"]) {
    color-scheme: dark;

    --vk-surface-page: var(--vk-graphite-950);
    --vk-surface-raised: var(--vk-graphite-900);
    --vk-surface-overlay: var(--vk-graphite-850);
    --vk-surface-sunken: var(--vk-graphite-1000);
    --vk-surface-hover: oklch(1 0 0 / 0.05);
    --vk-surface-active: oklch(1 0 0 / 0.08);
    --vk-surface-selected: oklch(1 0 0 / 0.07);
    --vk-surface-disabled: oklch(1 0 0 / 0.04);
    --vk-surface-inverse: var(--vk-graphite-50);
    --vk-surface-scrim: oklch(0.12 0.01 262 / 0.65);

    --vk-text-primary: var(--vk-graphite-50);
    --vk-text-secondary: var(--vk-graphite-300);
    --vk-text-muted: var(--vk-graphite-400);
    --vk-text-disabled: var(--vk-graphite-600);
    --vk-text-inverse: var(--vk-graphite-950);
    --vk-text-on-accent: var(--vk-graphite-950);

    --vk-border-subtle: oklch(1 0 0 / 0.07);
    --vk-border-default: oklch(1 0 0 / 0.11);
    --vk-border-strong: oklch(1 0 0 / 0.18);

    --vk-accent-subtle: oklch(1 0 0 / 0.08);
    --vk-accent-muted: var(--vk-graphite-600);
    --vk-accent-strong: var(--vk-graphite-100);
    --vk-accent-stronger: var(--vk-graphite-0);
    --vk-accent-on: var(--vk-graphite-950);
    --vk-accent-ring: oklch(1 0 0 / 0.32);

    --vk-success-surface: oklch(0.26 0.055 158);
    --vk-success-border: oklch(0.42 0.1 158);
    --vk-success-text: var(--vk-emerald-300);
    --vk-success-solid: var(--vk-emerald-400);
    --vk-success-on-solid: var(--vk-graphite-950);

    --vk-warning-surface: oklch(0.3 0.065 72);
    --vk-warning-border: oklch(0.5 0.115 72);
    --vk-warning-text: var(--vk-amber-300);
    --vk-warning-solid: var(--vk-amber-400);
    --vk-warning-on-solid: var(--vk-graphite-950);

    --vk-danger-surface: oklch(0.27 0.09 26);
    --vk-danger-border: oklch(0.43 0.17 26);
    --vk-danger-text: var(--vk-red-300);
    --vk-danger-solid: var(--vk-red-400);
    --vk-danger-on-solid: var(--vk-graphite-950);

    --vk-info-surface: oklch(0.26 0.06 244);
    --vk-info-border: oklch(0.42 0.105 244);
    --vk-info-text: var(--vk-blue-300);
    --vk-info-solid: var(--vk-blue-400);
    --vk-info-on-solid: var(--vk-graphite-950);

    --vk-neutral-surface: oklch(1 0 0 / 0.06);
    --vk-neutral-border: oklch(1 0 0 / 0.12);
    --vk-neutral-text: var(--vk-graphite-300);

    --vk-chart-grid: oklch(1 0 0 / 0.08);
    --vk-chart-axis: var(--vk-graphite-500);
  }
}

/* ==========================================================================
   VEKMOT DESIGN SYSTEM — LAYER 3: ZONE ACCENTS
   --------------------------------------------------------------------------
   Vekmot is ONE product with controlled colour zones, not ten brands.

   A zone re-points the accent role only. Typography, spacing, radius,
   shadow, motion, component anatomy and interaction behaviour are
   identical everywhere. That single constraint is what makes Owner,
   Workforce, Payments and Super Admin read as the same platform.

   USAGE
     <body data-zone="workforce">          whole shell
     <section data-zone="payments">        a region inside another zone

   Zones nest. A payments panel inside an owner page inherits owner
   typography and spacing while resolving payments accents.

   ZONE MAP
     owner / core   graphite   default, needs no attribute
     workforce      cobalt     Manager, Receptionist, Staff — one colour
     payments       indigo     Customer Payments: CUSTOMER -> SHOP
     billing        graphite   Platform Billing: SHOP -> VEKMOT
     analytics      azure      Insights
     vekryn         violet     analysis workspace
     chat           violet     VEKRYN family, calmer
     partner        graphite   ecosystem workspace
     superadmin     green      command centre telemetry

   --vk-zone-secondary is a RESTRAINED support signal. It is permitted on
   thin indicators, small icons and chart series. It is never a fill for a
   button, a card or a page region.
   ========================================================================== */

/* ------------------------------------------------------------------- OWNER
   Core Vekmot. Declared explicitly so a nested region can return to core
   identity from inside another zone. */
[data-zone="owner"],
[data-zone="core"] {
  --vk-zone-name: "owner";
  --vk-accent-subtle: var(--vk-graphite-100);
  --vk-accent-muted: var(--vk-graphite-300);
  --vk-accent-strong: var(--vk-graphite-900);
  --vk-accent-stronger: var(--vk-graphite-950);
  --vk-accent-on: var(--vk-graphite-0);
  --vk-accent-ring: oklch(0.17 0.012 262 / 0.28);
  --vk-zone-secondary: var(--vk-graphite-500);
}

/* --------------------------------------------------------------- WORKFORCE
   Manager, Receptionist and Staff all resolve to this one accent.
   Role differences are expressed through permissions, navigation,
   available actions and information density — never through colour. */
[data-zone="workforce"] {
  --vk-zone-name: "workforce";
  --vk-accent-subtle: var(--vk-cobalt-50);
  --vk-accent-muted: var(--vk-cobalt-200);
  --vk-accent-strong: var(--vk-cobalt-500);
  --vk-accent-stronger: var(--vk-cobalt-600);
  --vk-accent-on: var(--vk-graphite-0);
  --vk-accent-ring: oklch(0.49 0.16 255 / 0.32);
  --vk-zone-secondary: var(--vk-cobalt-400);
}

/* ---------------------------------------------------------------- PAYMENTS
   Customer Payments — CUSTOMER -> SHOP.
   Indigo with restrained cyan. Must never resemble Platform Billing. */
[data-zone="payments"] {
  --vk-zone-name: "payments";
  --vk-accent-subtle: var(--vk-indigo-50);
  --vk-accent-muted: var(--vk-indigo-200);
  --vk-accent-strong: var(--vk-indigo-500);
  --vk-accent-stronger: var(--vk-indigo-600);
  --vk-accent-on: var(--vk-graphite-0);
  --vk-accent-ring: oklch(0.48 0.17 275 / 0.32);
  --vk-zone-secondary: var(--vk-cyan-600);
}

/* ----------------------------------------------------------------- BILLING
   Platform Billing — SHOP -> VEKMOT.
   Deliberately core graphite. Billing is Vekmot invoicing the shop, so it
   wears the Vekmot identity rather than the customer-facing payments one.
   Keeping these two visually distinct is a product-correctness
   requirement, not a stylistic preference. */
[data-zone="billing"] {
  --vk-zone-name: "billing";
  --vk-accent-subtle: var(--vk-graphite-100);
  --vk-accent-muted: var(--vk-graphite-300);
  --vk-accent-strong: var(--vk-graphite-900);
  --vk-accent-stronger: var(--vk-graphite-950);
  --vk-accent-on: var(--vk-graphite-0);
  --vk-accent-ring: oklch(0.17 0.012 262 / 0.28);
  --vk-zone-secondary: var(--vk-graphite-500);
}

/* --------------------------------------------------------------- ANALYTICS */
[data-zone="analytics"],
[data-zone="insights"] {
  --vk-zone-name: "analytics";
  --vk-accent-subtle: var(--vk-azure-50);
  --vk-accent-muted: var(--vk-azure-200);
  --vk-accent-strong: var(--vk-azure-500);
  --vk-accent-stronger: var(--vk-azure-600);
  --vk-accent-on: var(--vk-graphite-0);
  --vk-accent-ring: oklch(0.58 0.16 240 / 0.32);
  --vk-zone-secondary: var(--vk-azure-400);
}

/* ------------------------------------------------------------------ VEKRYN
   Analytical and evidence-based. Deep violet with restrained cyan used
   only for evidence and source indicators. */
[data-zone="vekryn"] {
  --vk-zone-name: "vekryn";
  --vk-accent-subtle: var(--vk-violet-50);
  --vk-accent-muted: var(--vk-violet-200);
  --vk-accent-strong: var(--vk-violet-500);
  --vk-accent-stronger: var(--vk-violet-600);
  --vk-accent-on: var(--vk-graphite-0);
  --vk-accent-ring: oklch(0.42 0.15 295 / 0.32);
  --vk-zone-secondary: var(--vk-cyan-600);
}

/* -------------------------------------------------------------------- CHAT
   Same family as VEKRYN, one step calmer, because chat is ambient and
   persistent while an analysis result is a deliberate destination. */
[data-zone="chat"] {
  --vk-zone-name: "chat";
  --vk-accent-subtle: var(--vk-violet-50);
  --vk-accent-muted: var(--vk-violet-200);
  --vk-accent-strong: var(--vk-violet-600);
  --vk-accent-stronger: var(--vk-violet-700);
  --vk-accent-on: var(--vk-graphite-0);
  --vk-accent-ring: oklch(0.37 0.14 295 / 0.28);
  --vk-zone-secondary: var(--vk-cyan-700);
}

/* ----------------------------------------------------------------- PARTNER
   Vekmot ecosystem styling: core graphite identity, distinguished by
   layout and navigation rather than a competing accent hue. */
[data-zone="partner"] {
  --vk-zone-name: "partner";
  --vk-accent-subtle: var(--vk-graphite-100);
  --vk-accent-muted: var(--vk-graphite-300);
  --vk-accent-strong: var(--vk-graphite-800);
  --vk-accent-stronger: var(--vk-graphite-900);
  --vk-accent-on: var(--vk-graphite-0);
  --vk-accent-ring: oklch(0.3 0.016 262 / 0.28);
  --vk-zone-secondary: var(--vk-graphite-500);
}

/* -------------------------------------------------------------- SUPER ADMIN
   Graphite with luminous green. Green is a telemetry signal — live state,
   health, real-time operations — so it appears on dots, thin bars, small
   icons and metric deltas. It is never a page fill or a large button. */
[data-zone="superadmin"] {
  --vk-zone-name: "superadmin";
  --vk-accent-subtle: var(--vk-green-50);
  --vk-accent-muted: var(--vk-green-200);
  --vk-accent-strong: var(--vk-green-600);
  --vk-accent-stronger: var(--vk-green-700);
  --vk-accent-on: var(--vk-graphite-0);
  --vk-accent-ring: oklch(0.58 0.16 145 / 0.32);
  --vk-zone-secondary: var(--vk-green-500);
}

/* ==========================================================================
   DARK-THEME ZONE ADJUSTMENTS
   --------------------------------------------------------------------------
   On dark surfaces the mid-tone accents lose contrast, so each zone shifts
   to a lighter step and its "on" colour flips to deep graphite. Subtle
   surfaces become low-alpha tints of the accent hue rather than pale
   washes, which keeps them readable without glowing.
   ========================================================================== */

[data-theme="dark"] [data-zone="owner"],
[data-theme="dark"] [data-zone="core"],
[data-theme="dark"] [data-zone="billing"],
[data-theme="dark"] [data-zone="partner"] {
  --vk-accent-subtle: oklch(1 0 0 / 0.08);
  --vk-accent-muted: var(--vk-graphite-600);
  --vk-accent-strong: var(--vk-graphite-100);
  --vk-accent-stronger: var(--vk-graphite-0);
  --vk-accent-on: var(--vk-graphite-950);
  --vk-accent-ring: oklch(1 0 0 / 0.32);
  --vk-zone-secondary: var(--vk-graphite-400);
}

[data-theme="dark"] [data-zone="workforce"] {
  --vk-accent-subtle: oklch(0.49 0.16 255 / 0.16);
  --vk-accent-muted: oklch(0.49 0.16 255 / 0.4);
  --vk-accent-strong: oklch(0.72 0.14 255);
  --vk-accent-stronger: oklch(0.8 0.12 255);
  --vk-accent-on: var(--vk-graphite-950);
  --vk-accent-ring: oklch(0.72 0.14 255 / 0.4);
  --vk-zone-secondary: var(--vk-cobalt-300);
}

[data-theme="dark"] [data-zone="payments"] {
  --vk-accent-subtle: oklch(0.48 0.17 275 / 0.16);
  --vk-accent-muted: oklch(0.48 0.17 275 / 0.4);
  --vk-accent-strong: oklch(0.74 0.14 275);
  --vk-accent-stronger: oklch(0.82 0.11 275);
  --vk-accent-on: var(--vk-graphite-950);
  --vk-accent-ring: oklch(0.74 0.14 275 / 0.4);
  --vk-zone-secondary: var(--vk-cyan-400);
}

[data-theme="dark"] [data-zone="analytics"],
[data-theme="dark"] [data-zone="insights"] {
  --vk-accent-subtle: oklch(0.58 0.16 240 / 0.16);
  --vk-accent-muted: oklch(0.58 0.16 240 / 0.4);
  --vk-accent-strong: oklch(0.75 0.13 240);
  --vk-accent-stronger: oklch(0.83 0.1 240);
  --vk-accent-on: var(--vk-graphite-950);
  --vk-accent-ring: oklch(0.75 0.13 240 / 0.4);
  --vk-zone-secondary: var(--vk-azure-300);
}

[data-theme="dark"] [data-zone="vekryn"] {
  --vk-accent-subtle: oklch(0.42 0.15 295 / 0.18);
  --vk-accent-muted: oklch(0.42 0.15 295 / 0.42);
  --vk-accent-strong: oklch(0.76 0.13 295);
  --vk-accent-stronger: oklch(0.84 0.1 295);
  --vk-accent-on: var(--vk-graphite-950);
  --vk-accent-ring: oklch(0.76 0.13 295 / 0.4);
  --vk-zone-secondary: var(--vk-cyan-400);
}

[data-theme="dark"] [data-zone="chat"] {
  --vk-accent-subtle: oklch(0.42 0.15 295 / 0.14);
  --vk-accent-muted: oklch(0.42 0.15 295 / 0.36);
  --vk-accent-strong: oklch(0.7 0.12 295);
  --vk-accent-stronger: oklch(0.78 0.1 295);
  --vk-accent-on: var(--vk-graphite-950);
  --vk-accent-ring: oklch(0.7 0.12 295 / 0.36);
  --vk-zone-secondary: var(--vk-cyan-500);
}

[data-theme="dark"] [data-zone="superadmin"] {
  --vk-accent-subtle: oklch(0.67 0.18 145 / 0.14);
  --vk-accent-muted: oklch(0.67 0.18 145 / 0.36);
  --vk-accent-strong: oklch(0.78 0.18 145);
  --vk-accent-stronger: oklch(0.85 0.15 145);
  --vk-accent-on: var(--vk-graphite-950);
  --vk-accent-ring: oklch(0.78 0.18 145 / 0.4);
  --vk-zone-secondary: var(--vk-green-400);
}

/* ==========================================================================
   VEKMOT DESIGN SYSTEM — BASE: RESET
   --------------------------------------------------------------------------
   A minimal, opinionated normalisation. It removes browser defaults that
   fight the design system and sets sensible inheritance, and does nothing
   decorative — all appearance lives in the component layer.
   ========================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

html {
  /* Never disable user zoom: WCAG 2.2 requires text to scale to 200%. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  tab-size: 4;
}

body {
  min-height: 100dvh;
  background-color: var(--vk-surface-page);
  color: var(--vk-text-primary);
  font-family: var(--vk-font-sans);
  font-size: var(--vk-text-base);
  line-height: var(--vk-leading-normal);
  font-weight: var(--vk-weight-regular);
  letter-spacing: var(--vk-tracking-normal);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* Media defaults to block so images never sit on a mystery text baseline. */
img,
picture,
video,
canvas,
svg {
  display: block;
  max-width: 100%;
}

svg {
  /* Icons inherit their colour from the surrounding text by default. */
  fill: none;
  stroke: currentColor;
  flex-shrink: 0;
}

/* Form controls do not inherit typography in any browser. Force it. */
input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
}

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

button:disabled {
  cursor: not-allowed;
}

textarea {
  resize: vertical;
}

/* Long unbroken strings — reference IDs, e-mail addresses, tokens — must
   wrap rather than force a horizontal scrollbar on mobile. */
p,
h1,
h2,
h3,
h4,
h5,
h6,
li,
dd,
dt,
figcaption {
  overflow-wrap: break-word;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  font-size: inherit;
  font-weight: inherit;
  line-height: var(--vk-leading-tight);
  text-wrap: balance;
}

a {
  color: inherit;
  text-decoration: none;
}

ul[role="list"],
ol[role="list"] {
  list-style: none;
  padding: 0;
}

table {
  border-collapse: collapse;
  border-spacing: 0;
}

th {
  text-align: start;
  font-weight: var(--vk-weight-semibold);
}

fieldset {
  border: none;
  padding: 0;
  min-inline-size: 0;
}

legend {
  padding: 0;
}

hr {
  border: none;
  border-top: var(--vk-border-width) solid var(--vk-border-default);
}

[hidden] {
  display: none !important;
}

::placeholder {
  color: var(--vk-text-disabled);
  opacity: 1;
}

/* Selection uses the active zone accent, so highlighting text in the
   Payments zone tints indigo and in Workforce tints cobalt. */
::selection {
  background-color: var(--vk-accent-subtle);
  color: var(--vk-text-primary);
}

:root {
  scrollbar-color: var(--vk-border-strong) transparent;
}

::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

::-webkit-scrollbar-track {
  background: transparent;
}

::-webkit-scrollbar-thumb {
  background-color: var(--vk-border-strong);
  border-radius: var(--vk-radius-full);
  border: 2px solid transparent;
  background-clip: content-box;
}

::-webkit-scrollbar-thumb:hover {
  background-color: var(--vk-text-disabled);
  background-clip: content-box;
}

/* ==========================================================================
   VEKMOT DESIGN SYSTEM — BASE: TYPOGRAPHY
   --------------------------------------------------------------------------
   Six sizes, three weights, one typeface. The constraint is the point:
   a small scale applied consistently is what separates a mature product
   from a template.

   Class names describe ROLE, not size, so a display metric can be retuned
   globally without editing every screen.
   ========================================================================== */

/* ------------------------------------------------------------------ DISPLAY
   Reserved for a single primary metric on a page — collected today,
   outstanding balance, active sessions. Never for decoration. */
.vk-display {
  font-size: var(--vk-text-2xl);
  line-height: var(--vk-leading-tight);
  font-weight: var(--vk-weight-semibold);
  letter-spacing: var(--vk-tracking-tight);
}

/* ----------------------------------------------------------------- HEADINGS */
.vk-title-page {
  font-size: var(--vk-text-xl);
  line-height: var(--vk-leading-tight);
  font-weight: var(--vk-weight-semibold);
  letter-spacing: var(--vk-tracking-snug);
}

.vk-title-section {
  font-size: var(--vk-text-lg);
  line-height: var(--vk-leading-snug);
  font-weight: var(--vk-weight-semibold);
  letter-spacing: var(--vk-tracking-snug);
}

.vk-title-card {
  font-size: var(--vk-text-base);
  line-height: var(--vk-leading-snug);
  font-weight: var(--vk-weight-semibold);
}

/* --------------------------------------------------------------------- BODY */
.vk-body {
  font-size: var(--vk-text-base);
  line-height: var(--vk-leading-normal);
  font-weight: var(--vk-weight-regular);
}

/* The default for dense operational UI: tables, forms, list rows, controls. */
.vk-body-sm {
  font-size: var(--vk-text-sm);
  line-height: var(--vk-leading-normal);
  font-weight: var(--vk-weight-regular);
}

.vk-prose {
  max-width: var(--vk-prose-max-width);
  line-height: var(--vk-leading-relaxed);
}

/* ------------------------------------------------------------ SUPPORTING */
.vk-label {
  font-size: var(--vk-text-sm);
  line-height: var(--vk-leading-snug);
  font-weight: var(--vk-weight-medium);
  color: var(--vk-text-primary);
}

.vk-caption {
  font-size: var(--vk-text-xs);
  line-height: var(--vk-leading-snug);
  font-weight: var(--vk-weight-regular);
  color: var(--vk-text-muted);
}

/* Section eyebrow. Uppercase + tracking, used sparingly for grouping. */
.vk-overline {
  font-size: var(--vk-text-xs);
  line-height: var(--vk-leading-snug);
  font-weight: var(--vk-weight-semibold);
  letter-spacing: var(--vk-tracking-caps);
  text-transform: uppercase;
  color: var(--vk-text-muted);
}

.vk-meta {
  font-size: var(--vk-text-2xs);
  line-height: var(--vk-leading-snug);
  color: var(--vk-text-muted);
}

/* --------------------------------------------------------------- NUMERALS
   Tabular figures for anything that must align in a column or must not
   reflow as it updates: money, balances, counts, durations, IDs, metrics.

   .vk-numeric is mandatory on every monetary value in the product.
   Proportional digits cause amounts to jitter as they change and make
   columns impossible to scan, which is unacceptable in a payments UI. */
.vk-numeric {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
}

/* Money is always LTR, even in an RTL document. An amount reversed by
   bidi reordering is a correctness bug, not a styling preference. */
.vk-amount {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
  direction: ltr;
  unicode-bidi: isolate;
  white-space: nowrap;
}

.vk-amount-lg {
  font-size: var(--vk-text-2xl);
  line-height: var(--vk-leading-tight);
  font-weight: var(--vk-weight-semibold);
  letter-spacing: var(--vk-tracking-tight);
}

/* The currency code beside an amount is supporting information and should
   never compete with the figure itself. */
.vk-amount-currency {
  font-size: 0.75em;
  font-weight: var(--vk-weight-medium);
  color: var(--vk-text-muted);
}

.vk-mono {
  font-family: var(--vk-font-mono);
  font-size: 0.9375em;
  font-variant-ligatures: none;
}

/* ------------------------------------------------------------------ COLOUR */
.vk-text-primary {
  color: var(--vk-text-primary);
}
.vk-text-secondary {
  color: var(--vk-text-secondary);
}
.vk-text-muted {
  color: var(--vk-text-muted);
}
.vk-text-disabled {
  color: var(--vk-text-disabled);
}
.vk-text-accent {
  color: var(--vk-accent-strong);
}
.vk-text-success {
  color: var(--vk-success-text);
}
.vk-text-warning {
  color: var(--vk-warning-text);
}
.vk-text-danger {
  color: var(--vk-danger-text);
}
.vk-text-info {
  color: var(--vk-info-text);
}

/* ------------------------------------------------------------------ WEIGHT */
.vk-weight-regular {
  font-weight: var(--vk-weight-regular);
}
.vk-weight-medium {
  font-weight: var(--vk-weight-medium);
}
.vk-weight-semibold {
  font-weight: var(--vk-weight-semibold);
}

/* ----------------------------------------------------------------- LINKS */
.vk-link {
  color: var(--vk-text-link);
  font-weight: var(--vk-weight-medium);
  text-decoration: underline;
  text-underline-offset: 0.2em;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--vk-accent-muted);
  border-radius: var(--vk-radius-sm);
  transition: var(--vk-transition-colors);
}

.vk-link:hover {
  text-decoration-color: currentColor;
}

/* --------------------------------------------------------------- TRUNCATION
   Truncation always needs the full value available to assistive tech and
   on hover — pair these with a title attribute or a tooltip. */
.vk-truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.vk-clamp-2 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.vk-clamp-3 {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ==========================================================================
   VEKMOT DESIGN SYSTEM — BASE: LAYOUT PRIMITIVES
   --------------------------------------------------------------------------
   Composable layout objects. Every screen in the product is assembled from
   these rather than from bespoke per-page CSS — that is what keeps Owner,
   Workforce and Super Admin structurally identical.

   All primitives use LOGICAL properties (inline/block, start/end) so the
   entire product mirrors correctly under dir="rtl" with no overrides.

   Spacing arguments accept only the ten values from the 4px scale.
   ========================================================================== */

/* -------------------------------------------------------------- CONTAINER */
.vk-container {
  inline-size: 100%;
  max-inline-size: var(--vk-content-max-width);
  margin-inline: auto;
  padding-inline: var(--vk-space-4);
}

@media (min-width: 768px) {
  .vk-container {
    padding-inline: var(--vk-space-6);
  }
}

@media (min-width: 1280px) {
  .vk-container {
    padding-inline: var(--vk-space-8);
  }
}

.vk-container-narrow {
  max-inline-size: 720px;
}

.vk-container-prose {
  max-inline-size: var(--vk-prose-max-width);
}

/* ------------------------------------------------------------------ STACK
   Vertical rhythm. The single most-used primitive in the system. */
.vk-stack {
  display: flex;
  flex-direction: column;
  gap: var(--vk-stack-gap, var(--vk-space-4));
}

.vk-stack-1 {
  --vk-stack-gap: var(--vk-space-1);
}
.vk-stack-2 {
  --vk-stack-gap: var(--vk-space-2);
}
.vk-stack-3 {
  --vk-stack-gap: var(--vk-space-3);
}
.vk-stack-4 {
  --vk-stack-gap: var(--vk-space-4);
}
.vk-stack-5 {
  --vk-stack-gap: var(--vk-space-5);
}
.vk-stack-6 {
  --vk-stack-gap: var(--vk-space-6);
}
.vk-stack-8 {
  --vk-stack-gap: var(--vk-space-8);
}
.vk-stack-10 {
  --vk-stack-gap: var(--vk-space-10);
}
.vk-stack-12 {
  --vk-stack-gap: var(--vk-space-12);
}

/* ---------------------------------------------------------------- CLUSTER
   Horizontal group that wraps. Button rows, filter bars, tag lists,
   metadata lines. Wrapping is the default because a toolbar that
   overflows on mobile is a defect. */
.vk-cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--vk-cluster-gap, var(--vk-space-2));
}

.vk-cluster-1 {
  --vk-cluster-gap: var(--vk-space-1);
}
.vk-cluster-2 {
  --vk-cluster-gap: var(--vk-space-2);
}
.vk-cluster-3 {
  --vk-cluster-gap: var(--vk-space-3);
}
.vk-cluster-4 {
  --vk-cluster-gap: var(--vk-space-4);
}
.vk-cluster-6 {
  --vk-cluster-gap: var(--vk-space-6);
}

.vk-cluster-nowrap {
  flex-wrap: nowrap;
}
.vk-cluster-start {
  align-items: flex-start;
}
.vk-cluster-end {
  align-items: flex-end;
}
.vk-cluster-baseline {
  align-items: baseline;
}

/* ------------------------------------------------------------------ SPLIT
   Two groups pushed to opposite ends: page headers, card headers,
   list rows with a trailing action. Collapses to a stack on mobile. */
.vk-split {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--vk-space-4);
}

.vk-split-top {
  align-items: flex-start;
}

@media (max-width: 639px) {
  .vk-split-responsive {
    flex-direction: column;
    align-items: stretch;
  }
}

/* Pushes a child to the far end of a flex container. */
.vk-push-end {
  margin-inline-start: auto;
}

/* ------------------------------------------------------------------- GRID
   Auto-fitting card grid. Columns are derived from available width rather
   than declared per breakpoint, so a grid behaves correctly inside a
   collapsed sidebar, a drawer or a full-width page without extra rules. */
.vk-grid {
  display: grid;
  gap: var(--vk-grid-gap, var(--vk-space-4));
  grid-template-columns: repeat(
    auto-fit,
    minmax(min(var(--vk-grid-min, 260px), 100%), 1fr)
  );
}

.vk-grid-sm {
  --vk-grid-min: 180px;
}
.vk-grid-md {
  --vk-grid-min: 260px;
}
.vk-grid-lg {
  --vk-grid-min: 340px;
}
.vk-grid-gap-2 {
  --vk-grid-gap: var(--vk-space-2);
}
.vk-grid-gap-6 {
  --vk-grid-gap: var(--vk-space-6);
}

/* Fixed-column grids for deliberate layouts. */
.vk-grid-2 {
  display: grid;
  gap: var(--vk-grid-gap, var(--vk-space-4));
  grid-template-columns: 1fr;
}

.vk-grid-3 {
  display: grid;
  gap: var(--vk-grid-gap, var(--vk-space-4));
  grid-template-columns: 1fr;
}

.vk-grid-4 {
  display: grid;
  gap: var(--vk-grid-gap, var(--vk-space-4));
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 768px) {
  .vk-grid-2,
  .vk-grid-3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .vk-grid-3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .vk-grid-4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* ------------------------------------------------------------------ CENTRE */
.vk-center {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* --------------------------------------------------------------- DIVIDERS */
.vk-divider {
  border: none;
  border-block-start: var(--vk-border-width) solid var(--vk-border-subtle);
  margin-block: var(--vk-space-4);
}

.vk-divider-tight {
  margin-block: var(--vk-space-2);
}

.vk-divider-vertical {
  inline-size: var(--vk-border-width);
  align-self: stretch;
  background-color: var(--vk-border-subtle);
  border: none;
  margin-inline: var(--vk-space-2);
}

/* ------------------------------------------------------------- VISIBILITY
   Responsive visibility helpers. Used sparingly: mobile should get its own
   information architecture rather than a desktop layout with pieces
   switched off. These exist for genuinely equivalent alternatives, such as
   a table on desktop and the same records as cards on mobile. */
@media (max-width: 767px) {
  .vk-hide-mobile {
    display: none !important;
  }
}

@media (min-width: 768px) and (max-width: 1023px) {
  .vk-hide-tablet {
    display: none !important;
  }
}

@media (min-width: 1024px) {
  .vk-hide-desktop {
    display: none !important;
  }
}

@media (max-width: 1023px) {
  .vk-desktop-only {
    display: none !important;
  }
}

@media (min-width: 768px) {
  .vk-mobile-only {
    display: none !important;
  }
}

/* --------------------------------------------------------------- SCROLLERS */
.vk-scroll-x {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
}

.vk-scroll-y {
  overflow-y: auto;
  overscroll-behavior-y: contain;
}

/* Full-bleed horizontal scroller that escapes container padding on mobile,
   so a table or chip row can run edge to edge without breaking the grid. */
@media (max-width: 767px) {
  .vk-bleed-mobile {
    margin-inline: calc(var(--vk-space-4) * -1);
    padding-inline: var(--vk-space-4);
  }
}

/* CSP-safe layout utilities. Replaces HTML style attributes so style-src-attr
   does not need unsafe-inline. Dynamic percentages use discrete vk-pct-* classes. */

.vk-mt-2 { margin-block-start: var(--vk-space-2); }
.vk-mt-3 { margin-block-start: var(--vk-space-3); }
.vk-mt-4 { margin-block-start: var(--vk-space-4); }
.vk-mt-5 { margin-block-start: var(--vk-space-5); }
.vk-mt-6 { margin-block-start: var(--vk-space-6); }
.vk-mt-8 { margin-block-start: var(--vk-space-8); }
.vk-mt-10 { margin-block-start: var(--vk-space-10); }
.vk-mt-12 { margin-block-start: var(--vk-space-12); }
.vk-mt-16 { margin-block-start: var(--vk-space-16); }
.vk-mb-2 { margin-block-end: var(--vk-space-2); }
.vk-mb-3 { margin-block-end: var(--vk-space-3); }
.vk-mb-4 { margin-block-end: var(--vk-space-4); }
.vk-mb-5 { margin-block-end: var(--vk-space-5); }
.vk-mb-6 { margin-block-end: var(--vk-space-6); }
.vk-my-3 { margin-block: var(--vk-space-3); }
.vk-my-6 { margin-block: var(--vk-space-6); }
.vk-pad-3 { padding: var(--vk-space-3); }
.vk-pad-b-6 { padding-block-end: var(--vk-space-6); }
.vk-row-tight { padding-block: var(--vk-space-1); }
.vk-text-center { text-align: center; }
.vk-mx-auto { margin-inline: auto; }
.vk-flex-1 { flex: 1; min-inline-size: 0; }
.vk-justify-center { justify-content: center; }
.vk-min-w-12 { min-inline-size: 12rem; }
.vk-max-w-14 { max-inline-size: 14rem; }
.vk-measure { max-inline-size: 68ch; }
.vk-measure-lg { max-inline-size: 62ch; }
.vk-measure-md { max-inline-size: 60ch; }
.vk-measure-sm { max-inline-size: 56ch; }
.vk-measure-xs { max-inline-size: 52ch; }
.vk-color-inherit { color: inherit; }
.vk-label-soft { color: inherit; opacity: 0.75; }
.vk-td-flush { padding: 0; }
.vk-link-xs { font-size: var(--vk-text-xs); }
.vk-chat-pane { min-block-size: min(70dvh, 720px); }
.vk-auth-card-wide { --vk-auth-width: 480px; }
.vk-otp-input { font-size: var(--vk-text-lg); letter-spacing: 0.4em; text-align: center; }

textarea[data-vk-chat-input] {
  field-sizing: content;
  max-block-size: 160px;
  overflow-y: auto;
}

.g-wrap { padding: var(--vk-space-6) var(--vk-space-4) var(--vk-space-16); }
.g-section { padding-block: var(--vk-space-8); border-block-start: var(--vk-border-width) solid var(--vk-border-subtle); }
.g-section:first-of-type { border-block-start: 0; }
.g-row { display: flex; flex-wrap: wrap; gap: var(--vk-space-3); align-items: center; }
.g-grid { display: grid; gap: var(--vk-space-4); grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.g-zone { padding: var(--vk-space-4); border-radius: var(--vk-radius-md); border: var(--vk-border-width) solid var(--vk-border-subtle); }
.g-swatch { block-size: 44px; border-radius: var(--vk-radius-sm); border: var(--vk-border-width) solid var(--vk-border-subtle); }
.g-swatch-subtle { background: var(--vk-accent-subtle); }
.g-swatch-muted { background: var(--vk-accent-muted); }
.g-swatch-strong { background: var(--vk-accent-strong); }
.g-swatch-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--vk-space-1); margin-block-start: var(--vk-space-3); }
.g-demo { max-inline-size: 360px; }

.vk-pct-x-0 { inline-size: 0%; }
.vk-pct-y-0 { block-size: 0%; }
.vk-pct-x-1 { inline-size: 1%; }
.vk-pct-y-1 { block-size: 1%; }
.vk-pct-x-2 { inline-size: 2%; }
.vk-pct-y-2 { block-size: 2%; }
.vk-pct-x-3 { inline-size: 3%; }
.vk-pct-y-3 { block-size: 3%; }
.vk-pct-x-4 { inline-size: 4%; }
.vk-pct-y-4 { block-size: 4%; }
.vk-pct-x-5 { inline-size: 5%; }
.vk-pct-y-5 { block-size: 5%; }
.vk-pct-x-6 { inline-size: 6%; }
.vk-pct-y-6 { block-size: 6%; }
.vk-pct-x-7 { inline-size: 7%; }
.vk-pct-y-7 { block-size: 7%; }
.vk-pct-x-8 { inline-size: 8%; }
.vk-pct-y-8 { block-size: 8%; }
.vk-pct-x-9 { inline-size: 9%; }
.vk-pct-y-9 { block-size: 9%; }
.vk-pct-x-10 { inline-size: 10%; }
.vk-pct-y-10 { block-size: 10%; }
.vk-pct-x-11 { inline-size: 11%; }
.vk-pct-y-11 { block-size: 11%; }
.vk-pct-x-12 { inline-size: 12%; }
.vk-pct-y-12 { block-size: 12%; }
.vk-pct-x-13 { inline-size: 13%; }
.vk-pct-y-13 { block-size: 13%; }
.vk-pct-x-14 { inline-size: 14%; }
.vk-pct-y-14 { block-size: 14%; }
.vk-pct-x-15 { inline-size: 15%; }
.vk-pct-y-15 { block-size: 15%; }
.vk-pct-x-16 { inline-size: 16%; }
.vk-pct-y-16 { block-size: 16%; }
.vk-pct-x-17 { inline-size: 17%; }
.vk-pct-y-17 { block-size: 17%; }
.vk-pct-x-18 { inline-size: 18%; }
.vk-pct-y-18 { block-size: 18%; }
.vk-pct-x-19 { inline-size: 19%; }
.vk-pct-y-19 { block-size: 19%; }
.vk-pct-x-20 { inline-size: 20%; }
.vk-pct-y-20 { block-size: 20%; }
.vk-pct-x-21 { inline-size: 21%; }
.vk-pct-y-21 { block-size: 21%; }
.vk-pct-x-22 { inline-size: 22%; }
.vk-pct-y-22 { block-size: 22%; }
.vk-pct-x-23 { inline-size: 23%; }
.vk-pct-y-23 { block-size: 23%; }
.vk-pct-x-24 { inline-size: 24%; }
.vk-pct-y-24 { block-size: 24%; }
.vk-pct-x-25 { inline-size: 25%; }
.vk-pct-y-25 { block-size: 25%; }
.vk-pct-x-26 { inline-size: 26%; }
.vk-pct-y-26 { block-size: 26%; }
.vk-pct-x-27 { inline-size: 27%; }
.vk-pct-y-27 { block-size: 27%; }
.vk-pct-x-28 { inline-size: 28%; }
.vk-pct-y-28 { block-size: 28%; }
.vk-pct-x-29 { inline-size: 29%; }
.vk-pct-y-29 { block-size: 29%; }
.vk-pct-x-30 { inline-size: 30%; }
.vk-pct-y-30 { block-size: 30%; }
.vk-pct-x-31 { inline-size: 31%; }
.vk-pct-y-31 { block-size: 31%; }
.vk-pct-x-32 { inline-size: 32%; }
.vk-pct-y-32 { block-size: 32%; }
.vk-pct-x-33 { inline-size: 33%; }
.vk-pct-y-33 { block-size: 33%; }
.vk-pct-x-34 { inline-size: 34%; }
.vk-pct-y-34 { block-size: 34%; }
.vk-pct-x-35 { inline-size: 35%; }
.vk-pct-y-35 { block-size: 35%; }
.vk-pct-x-36 { inline-size: 36%; }
.vk-pct-y-36 { block-size: 36%; }
.vk-pct-x-37 { inline-size: 37%; }
.vk-pct-y-37 { block-size: 37%; }
.vk-pct-x-38 { inline-size: 38%; }
.vk-pct-y-38 { block-size: 38%; }
.vk-pct-x-39 { inline-size: 39%; }
.vk-pct-y-39 { block-size: 39%; }
.vk-pct-x-40 { inline-size: 40%; }
.vk-pct-y-40 { block-size: 40%; }
.vk-pct-x-41 { inline-size: 41%; }
.vk-pct-y-41 { block-size: 41%; }
.vk-pct-x-42 { inline-size: 42%; }
.vk-pct-y-42 { block-size: 42%; }
.vk-pct-x-43 { inline-size: 43%; }
.vk-pct-y-43 { block-size: 43%; }
.vk-pct-x-44 { inline-size: 44%; }
.vk-pct-y-44 { block-size: 44%; }
.vk-pct-x-45 { inline-size: 45%; }
.vk-pct-y-45 { block-size: 45%; }
.vk-pct-x-46 { inline-size: 46%; }
.vk-pct-y-46 { block-size: 46%; }
.vk-pct-x-47 { inline-size: 47%; }
.vk-pct-y-47 { block-size: 47%; }
.vk-pct-x-48 { inline-size: 48%; }
.vk-pct-y-48 { block-size: 48%; }
.vk-pct-x-49 { inline-size: 49%; }
.vk-pct-y-49 { block-size: 49%; }
.vk-pct-x-50 { inline-size: 50%; }
.vk-pct-y-50 { block-size: 50%; }
.vk-pct-x-51 { inline-size: 51%; }
.vk-pct-y-51 { block-size: 51%; }
.vk-pct-x-52 { inline-size: 52%; }
.vk-pct-y-52 { block-size: 52%; }
.vk-pct-x-53 { inline-size: 53%; }
.vk-pct-y-53 { block-size: 53%; }
.vk-pct-x-54 { inline-size: 54%; }
.vk-pct-y-54 { block-size: 54%; }
.vk-pct-x-55 { inline-size: 55%; }
.vk-pct-y-55 { block-size: 55%; }
.vk-pct-x-56 { inline-size: 56%; }
.vk-pct-y-56 { block-size: 56%; }
.vk-pct-x-57 { inline-size: 57%; }
.vk-pct-y-57 { block-size: 57%; }
.vk-pct-x-58 { inline-size: 58%; }
.vk-pct-y-58 { block-size: 58%; }
.vk-pct-x-59 { inline-size: 59%; }
.vk-pct-y-59 { block-size: 59%; }
.vk-pct-x-60 { inline-size: 60%; }
.vk-pct-y-60 { block-size: 60%; }
.vk-pct-x-61 { inline-size: 61%; }
.vk-pct-y-61 { block-size: 61%; }
.vk-pct-x-62 { inline-size: 62%; }
.vk-pct-y-62 { block-size: 62%; }
.vk-pct-x-63 { inline-size: 63%; }
.vk-pct-y-63 { block-size: 63%; }
.vk-pct-x-64 { inline-size: 64%; }
.vk-pct-y-64 { block-size: 64%; }
.vk-pct-x-65 { inline-size: 65%; }
.vk-pct-y-65 { block-size: 65%; }
.vk-pct-x-66 { inline-size: 66%; }
.vk-pct-y-66 { block-size: 66%; }
.vk-pct-x-67 { inline-size: 67%; }
.vk-pct-y-67 { block-size: 67%; }
.vk-pct-x-68 { inline-size: 68%; }
.vk-pct-y-68 { block-size: 68%; }
.vk-pct-x-69 { inline-size: 69%; }
.vk-pct-y-69 { block-size: 69%; }
.vk-pct-x-70 { inline-size: 70%; }
.vk-pct-y-70 { block-size: 70%; }
.vk-pct-x-71 { inline-size: 71%; }
.vk-pct-y-71 { block-size: 71%; }
.vk-pct-x-72 { inline-size: 72%; }
.vk-pct-y-72 { block-size: 72%; }
.vk-pct-x-73 { inline-size: 73%; }
.vk-pct-y-73 { block-size: 73%; }
.vk-pct-x-74 { inline-size: 74%; }
.vk-pct-y-74 { block-size: 74%; }
.vk-pct-x-75 { inline-size: 75%; }
.vk-pct-y-75 { block-size: 75%; }
.vk-pct-x-76 { inline-size: 76%; }
.vk-pct-y-76 { block-size: 76%; }
.vk-pct-x-77 { inline-size: 77%; }
.vk-pct-y-77 { block-size: 77%; }
.vk-pct-x-78 { inline-size: 78%; }
.vk-pct-y-78 { block-size: 78%; }
.vk-pct-x-79 { inline-size: 79%; }
.vk-pct-y-79 { block-size: 79%; }
.vk-pct-x-80 { inline-size: 80%; }
.vk-pct-y-80 { block-size: 80%; }
.vk-pct-x-81 { inline-size: 81%; }
.vk-pct-y-81 { block-size: 81%; }
.vk-pct-x-82 { inline-size: 82%; }
.vk-pct-y-82 { block-size: 82%; }
.vk-pct-x-83 { inline-size: 83%; }
.vk-pct-y-83 { block-size: 83%; }
.vk-pct-x-84 { inline-size: 84%; }
.vk-pct-y-84 { block-size: 84%; }
.vk-pct-x-85 { inline-size: 85%; }
.vk-pct-y-85 { block-size: 85%; }
.vk-pct-x-86 { inline-size: 86%; }
.vk-pct-y-86 { block-size: 86%; }
.vk-pct-x-87 { inline-size: 87%; }
.vk-pct-y-87 { block-size: 87%; }
.vk-pct-x-88 { inline-size: 88%; }
.vk-pct-y-88 { block-size: 88%; }
.vk-pct-x-89 { inline-size: 89%; }
.vk-pct-y-89 { block-size: 89%; }
.vk-pct-x-90 { inline-size: 90%; }
.vk-pct-y-90 { block-size: 90%; }
.vk-pct-x-91 { inline-size: 91%; }
.vk-pct-y-91 { block-size: 91%; }
.vk-pct-x-92 { inline-size: 92%; }
.vk-pct-y-92 { block-size: 92%; }
.vk-pct-x-93 { inline-size: 93%; }
.vk-pct-y-93 { block-size: 93%; }
.vk-pct-x-94 { inline-size: 94%; }
.vk-pct-y-94 { block-size: 94%; }
.vk-pct-x-95 { inline-size: 95%; }
.vk-pct-y-95 { block-size: 95%; }
.vk-pct-x-96 { inline-size: 96%; }
.vk-pct-y-96 { block-size: 96%; }
.vk-pct-x-97 { inline-size: 97%; }
.vk-pct-y-97 { block-size: 97%; }
.vk-pct-x-98 { inline-size: 98%; }
.vk-pct-y-98 { block-size: 98%; }
.vk-pct-x-99 { inline-size: 99%; }
.vk-pct-y-99 { block-size: 99%; }
.vk-pct-x-100 { inline-size: 100%; }
.vk-pct-y-100 { block-size: 100%; }

/* ==========================================================================
   VEKMOT DESIGN SYSTEM — BASE: ICON CONVENTIONS
   --------------------------------------------------------------------------
   One icon family across the entire product: Lucide-style outlined
   geometry, 24x24 grid, 1.5 stroke, currentColor.

   Rules
     1. Icons are decorative by default and carry aria-hidden="true".
     2. An icon-only control MUST have its own accessible name.
     3. Icons never carry a hard-coded colour — they inherit currentColor.
     4. Only chevrons, arrows and other directional glyphs may mirror in
        RTL, via .vk-icon-directional.
     5. No emoji. Anywhere. Emoji are not an icon system: they render
        differently per platform, cannot inherit colour, and read as
        informal in an operational product.

   Sizes map to the type scale so an icon optically matches its label:
     sm 14px  beside 12px text
     md 16px  beside 14px text  (the product default)
     lg 20px  beside 16px text
     xl 24px  standalone, empty states, feature headers
   ========================================================================== */

.vk-icon-sprite {
  display: none;
}
.vk-icon-sprite symbol {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.vk-icon {
  display: inline-block;
  inline-size: var(--vk-icon-md);
  block-size: var(--vk-icon-md);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: middle;
  flex-shrink: 0;
  /* Optical centring: an outlined glyph sits marginally high against a
     text baseline at these sizes. */
  transform: translateY(-0.5px);
}

.vk-icon-sm {
  inline-size: var(--vk-icon-sm);
  block-size: var(--vk-icon-sm);
  stroke-width: 1.75;
}

.vk-icon-md {
  inline-size: var(--vk-icon-md);
  block-size: var(--vk-icon-md);
  stroke-width: 1.5;
}

.vk-icon-lg {
  inline-size: var(--vk-icon-lg);
  block-size: var(--vk-icon-lg);
  stroke-width: 1.5;
}

.vk-icon-xl {
  inline-size: var(--vk-icon-xl);
  block-size: var(--vk-icon-xl);
  stroke-width: 1.5;
}

/* Colour roles — applied to the icon, or inherited from the parent. */
.vk-icon-muted {
  color: var(--vk-text-muted);
}
.vk-icon-accent {
  color: var(--vk-accent-strong);
}
.vk-icon-success {
  color: var(--vk-success-text);
}
.vk-icon-warning {
  color: var(--vk-warning-text);
}
.vk-icon-danger {
  color: var(--vk-danger-text);
}
.vk-icon-info {
  color: var(--vk-info-text);
}

/* --------------------------------------------------------------- SPINNER
   The only continuous animation permitted in the system, and only to
   indicate that a request is genuinely in flight.

   In a payments context a spinner means "we are waiting for the provider".
   It must never be shown in a way that suggests a result has been reached. */
.vk-icon-spin {
  animation: vk-spin 900ms linear infinite;
  transform-origin: center;
}

@keyframes vk-spin {
  to {
    rotate: 360deg;
  }
}

@media (prefers-reduced-motion: reduce) {
  .vk-icon-spin {
    /* Motion removed, but the element keeps its role and live-region text
       so the state remains announced. */
    animation: none;
    opacity: 0.7;
  }
}

/* ------------------------------------------------------------- ICON FRAME
   A sized, tinted container used for empty states, feature headers and
   list-row leading icons. Uses the active zone accent by default. */
.vk-icon-frame {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--vk-space-10);
  block-size: var(--vk-space-10);
  border-radius: var(--vk-radius-md);
  background-color: var(--vk-accent-subtle);
  color: var(--vk-accent-strong);
}

.vk-icon-frame-sm {
  inline-size: var(--vk-space-8);
  block-size: var(--vk-space-8);
  border-radius: var(--vk-radius-sm);
}

.vk-icon-frame-lg {
  inline-size: var(--vk-space-12);
  block-size: var(--vk-space-12);
  border-radius: var(--vk-radius-md);
}

.vk-icon-frame-neutral {
  background-color: var(--vk-surface-sunken);
  color: var(--vk-text-muted);
}

.vk-icon-frame-success {
  background-color: var(--vk-success-surface);
  color: var(--vk-success-text);
}

.vk-icon-frame-warning {
  background-color: var(--vk-warning-surface);
  color: var(--vk-warning-text);
}

.vk-icon-frame-danger {
  background-color: var(--vk-danger-surface);
  color: var(--vk-danger-text);
}

.vk-icon-frame-info {
  background-color: var(--vk-info-surface);
  color: var(--vk-info-text);
}

/* ==========================================================================
   VEKMOT DESIGN SYSTEM — BASE: ACCESSIBILITY
   --------------------------------------------------------------------------
   Target: WCAG 2.2 AA.

   Accessibility lives in the foundation rather than in individual
   components so that a screen cannot accidentally opt out of it. Anything
   defined here applies to every zone and every shell.
   ========================================================================== */

/* ------------------------------------------------------------------- FOCUS
   :focus-visible only — a visible ring appears for keyboard and
   assistive-tech users without punishing pointer users. The ring uses the
   active zone accent, so focus is always visible against its own context.

   WCAG 2.2 (2.4.11 Focus Not Obscured / 2.4.13 Focus Appearance): the ring
   is 2px with a 2px offset, giving a continuous high-contrast outline on
   both light and dark surfaces. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible,
.vk-focusable:focus-visible {
  outline: var(--vk-focus-ring-width) solid var(--vk-accent-strong);
  outline-offset: var(--vk-focus-ring-offset);
  border-radius: var(--vk-radius-sm);
}

/* Remove the default ring only where a replacement is guaranteed above. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus:not(
    :focus-visible
  ) {
  outline: none;
}

/* A focused element inside a scroll container must never be scrolled
   under a sticky header. */
:root {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--vk-topbar-height) + var(--vk-space-4));
}

/* --------------------------------------------------------------- SKIP LINK
   First focusable element in every shell. Hidden until focused. */
.vk-skip-link {
  position: absolute;
  inset-inline-start: var(--vk-space-4);
  inset-block-start: var(--vk-space-4);
  z-index: var(--vk-z-tooltip);
  padding: var(--vk-space-3) var(--vk-space-4);
  background-color: var(--vk-surface-overlay);
  color: var(--vk-text-primary);
  border: var(--vk-border-width) solid var(--vk-border-strong);
  border-radius: var(--vk-radius-sm);
  box-shadow: var(--vk-elevation-modal);
  font-size: var(--vk-text-sm);
  font-weight: var(--vk-weight-medium);
  transform: translateY(calc(-100% - var(--vk-space-4) * 2));
  transition: transform var(--vk-duration-fast) var(--vk-ease-out);
}

.vk-skip-link:focus-visible {
  transform: translateY(0);
}

/* ------------------------------------------------------- SCREEN READER ONLY
   .vk-sr-only hides content visually while keeping it in the accessibility
   tree. Used for icon-only button labels, table captions, live-region
   status text and form group descriptions. */
.vk-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Visible once focused — for skip targets and hidden shortcuts. */
.vk-sr-only-focusable:not(:focus):not(:focus-within) {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------------------------------------------------------- TOUCH TARGETS
   WCAG 2.2 AA (2.5.8 Target Size Minimum) requires 24px, and Vekmot
   targets 44px on touch pointers because the Workforce shell is used
   one-handed on a phone at a front desk.

   The pseudo-element expands the hit area without changing layout, so a
   32px control still presents a 44px target on touch. */
@media (pointer: coarse) {
  .vk-touch-target {
    position: relative;
  }

  .vk-touch-target::after {
    content: "";
    position: absolute;
    inset: 50% auto auto 50%;
    translate: -50% -50%;
    min-width: var(--vk-touch-target-min);
    min-height: var(--vk-touch-target-min);
    width: 100%;
    height: 100%;
  }
}

/* ------------------------------------------------------------ REDUCED MOTION
   Motion is removed rather than shortened. Transitions are collapsed to a
   near-zero duration instead of `none` so that transitionend listeners
   still fire and no interaction logic stalls waiting for an event. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  :root {
    --vk-duration-instant: 0.01ms;
    --vk-duration-fast: 0.01ms;
    --vk-duration-base: 0.01ms;
    --vk-duration-slow: 0.01ms;
  }
}

/* ------------------------------------------------------------ HIGH CONTRAST
   Windows High Contrast / forced-colors. Borders must be preserved because
   the system palette flattens backgrounds, and a component whose boundary
   is expressed only by a background colour would disappear. */
@media (forced-colors: active) {
  :where(button, input, select, textarea, [role="button"]) {
    border: 1px solid ButtonBorder;
  }

  :where(a, button, input, select, textarea, [tabindex]):focus-visible {
    outline: 2px solid Highlight;
    outline-offset: 2px;
  }
}

/* ------------------------------------------------------------- TRANSPARENCY */
@media (prefers-reduced-transparency: reduce) {
  :root {
    --vk-surface-scrim: var(--vk-graphite-950);
  }
}

/* ================================================================== RTL
   Arabic is a first-class language in Vekmot, not a retrofit.

   The system is built on CSS logical properties throughout —
   margin-inline, padding-inline, inset-inline, border-inline, text-align
   start/end — so the entire layout mirrors from `dir="rtl"` on <html>
   with no per-component overrides.

   Only three things need explicit handling, and they are handled here:

     1. Directional icons (chevrons, arrows, back/forward) must mirror.
     2. Numbers, money and identifiers must stay LTR (see .vk-amount).
     3. Assets that encode direction must be flipped explicitly.
   ================================================================== */

/* Directional glyphs mirror automatically in an RTL context. Opt in with
   .vk-icon-directional so that non-directional icons — a clock, a user,
   a checkmark — are never flipped. */
[dir="rtl"] .vk-icon-directional {
  scale: -1 1;
}

/* Progress and timeline fills read from the start edge in both directions. */
[dir="rtl"] .vk-flip-none {
  scale: 1 1;
}

/* Latin identifiers inside Arabic copy — booking references, e-mails,
   plan codes — must not be reordered by the bidi algorithm. */
.vk-ltr {
  direction: ltr;
  unicode-bidi: isolate;
}

.vk-rtl {
  direction: rtl;
  unicode-bidi: isolate;
}

/* Backend-formatted dates and times. Direction is taken from the string's own
   first strong character rather than forced, because "27 Aug 2026, 14:36" must
   read left-to-right while "٢٧ أغسطس ٢٠٢٦" must read right-to-left, and both
   arrive through the same macro argument. Equivalent to dir="auto". */
.vk-ts {
  unicode-bidi: plaintext;
}

/* Isolates any user-supplied string so untrusted content cannot leak its
   direction into the surrounding layout. */
.vk-bidi-isolate {
  unicode-bidi: isolate;
}

/* -------------------------------------------------------------- LIVE REGIONS
   Status containers announced by assistive tech. Payment state changes,
   terminal progress and toast notifications all render into one of these.

   aria-live must be present in the DOM BEFORE the content changes, so
   these containers are rendered empty rather than injected on demand. */
.vk-live-region {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --------------------------------------------------------------- UTILITIES */
.vk-no-select {
  user-select: none;
}

/* Applied to <body> while a modal, drawer or command palette is open. */
.vk-scroll-lock {
  overflow: hidden;
  touch-action: none;
}

/* ==========================================================================
   VEKMOT COMPONENTS — CONTROLS
   --------------------------------------------------------------------------
   Buttons, inputs, selects, checkboxes, radios, switches, textareas and the
   field wrapper that binds a label, a control, a hint and an error together.

   Every control consumes semantic or zone tokens only. None reference a
   primitive. That is what allows [data-zone] to restyle an entire screen
   without a single component being aware a zone exists.

   Sizing: the 44px WCAG 2.2 AA touch floor is applied on coarse pointers
   rather than universally, so desktop stays dense and touch stays reachable.
   ========================================================================== */

/* ---------------------------------------------------------------- BUTTON */

.vk-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--vk-space-2);

  block-size: var(--vk-control-height-md);
  padding-inline: var(--vk-space-4);

  border: var(--vk-border-width) solid transparent;
  border-radius: var(--vk-radius-sm);

  font-family: inherit;
  font-size: var(--vk-text-sm);
  font-weight: var(--vk-weight-medium);
  line-height: var(--vk-leading-none);
  letter-spacing: var(--vk-tracking-snug);
  white-space: nowrap;
  text-decoration: none;

  cursor: pointer;
  user-select: none;
  transition: var(--vk-transition-colors);
}

.vk-btn:disabled,
.vk-btn[aria-disabled="true"],
.vk-btn.is-disabled {
  cursor: not-allowed;
  opacity: 0.55;
}

/* Primary — the single most important action on a surface. One per view. */
.vk-btn-primary {
  background: var(--vk-accent-strong);
  border-color: var(--vk-accent-strong);
  color: var(--vk-accent-on);
}
.vk-btn-primary:hover:not(:disabled):not(.is-loading) {
  background: var(--vk-accent-stronger);
  border-color: var(--vk-accent-stronger);
}
.vk-btn-primary:active:not(:disabled) {
  transform: translateY(0.5px);
}

/* Secondary — the default for most actions. */
.vk-btn-secondary {
  background: var(--vk-surface-raised);
  border-color: var(--vk-border-default);
  color: var(--vk-text-primary);
}
.vk-btn-secondary:hover:not(:disabled):not(.is-loading) {
  background: var(--vk-surface-hover);
  border-color: var(--vk-border-strong);
}
.vk-btn-secondary:active:not(:disabled) {
  background: var(--vk-surface-active);
}

/* Ghost — inline and toolbar actions that must not compete. */
.vk-btn-ghost {
  background: transparent;
  border-color: transparent;
  color: var(--vk-text-secondary);
}
.vk-btn-ghost:hover:not(:disabled):not(.is-loading) {
  background: var(--vk-surface-hover);
  color: var(--vk-text-primary);
}
.vk-btn-ghost:active:not(:disabled) {
  background: var(--vk-surface-active);
}

/* Danger — destructive only. Never used for emphasis. */
.vk-btn-danger {
  background: var(--vk-danger-solid);
  border-color: var(--vk-danger-solid);
  color: var(--vk-danger-on-solid);
}
.vk-btn-danger:hover:not(:disabled):not(.is-loading) {
  filter: brightness(0.94);
}

.vk-btn-danger-quiet {
  background: transparent;
  border-color: var(--vk-danger-border);
  color: var(--vk-danger-text);
}
.vk-btn-danger-quiet:hover:not(:disabled):not(.is-loading) {
  background: var(--vk-danger-surface);
}

/* Sizes */
.vk-btn-sm {
  block-size: var(--vk-control-height-sm);
  padding-inline: var(--vk-space-3);
  font-size: var(--vk-text-xs);
}
.vk-btn-lg {
  block-size: var(--vk-control-height-lg);
  padding-inline: var(--vk-space-6);
  font-size: var(--vk-text-base);
}

.vk-btn-block {
  inline-size: 100%;
}

/* Icon-only. An accessible name is mandatory — the macro enforces it. */
.vk-btn-icon {
  inline-size: var(--vk-control-height-md);
  padding-inline: 0;
}
.vk-btn-icon.vk-btn-sm {
  inline-size: var(--vk-control-height-sm);
}
.vk-btn-icon.vk-btn-lg {
  inline-size: var(--vk-control-height-lg);
}

/* Loading. The label stays in the DOM for screen readers and is hidden
   visually, so the button never changes width mid-request. */
.vk-btn.is-loading {
  position: relative;
  cursor: progress;
  pointer-events: none;
}
.vk-btn.is-loading > * {
  visibility: hidden;
}
.vk-btn.is-loading::after {
  content: "";
  position: absolute;
  inline-size: 15px;
  block-size: 15px;
  border: 2px solid currentColor;
  border-block-start-color: transparent;
  border-radius: var(--vk-radius-full);
  animation: vk-spin 620ms linear infinite;
}

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

@media (prefers-reduced-motion: reduce) {
  .vk-btn.is-loading::after {
    animation-duration: 1600ms;
  }
}

/* A group of buttons that reads as one control. */
.vk-btn-group {
  display: inline-flex;
  isolation: isolate;
}
.vk-btn-group > .vk-btn {
  border-radius: 0;
  margin-inline-start: calc(var(--vk-border-width) * -1);
}
.vk-btn-group > .vk-btn:first-child {
  border-start-start-radius: var(--vk-radius-sm);
  border-end-start-radius: var(--vk-radius-sm);
  margin-inline-start: 0;
}
.vk-btn-group > .vk-btn:last-child {
  border-start-end-radius: var(--vk-radius-sm);
  border-end-end-radius: var(--vk-radius-sm);
}
.vk-btn-group > .vk-btn:hover,
.vk-btn-group > .vk-btn:focus-visible {
  z-index: var(--vk-z-raised);
}

/* ----------------------------------------------------------------- FIELD */

.vk-field {
  display: flex;
  flex-direction: column;
  gap: var(--vk-space-2);
  min-inline-size: 0;
}

.vk-field-label {
  display: flex;
  align-items: center;
  gap: var(--vk-space-2);
  font-size: var(--vk-text-xs);
  font-weight: var(--vk-weight-medium);
  color: var(--vk-text-secondary);
}

.vk-field-required {
  color: var(--vk-danger-text);
}

.vk-field-optional {
  margin-inline-start: auto;
  font-weight: var(--vk-weight-regular);
  color: var(--vk-text-muted);
}

.vk-field-hint {
  font-size: var(--vk-text-xs);
  line-height: var(--vk-leading-snug);
  color: var(--vk-text-muted);
}

/* Errors pair an icon with the text so the state is never colour-only. */
.vk-field-error {
  display: flex;
  align-items: flex-start;
  gap: var(--vk-space-1);
  font-size: var(--vk-text-xs);
  line-height: var(--vk-leading-snug);
  color: var(--vk-danger-text);
}
.vk-field-error .vk-icon {
  flex: none;
  margin-block-start: 1px;
}

/* ----------------------------------------------------- INPUT / TEXTAREA */

.vk-input,
.vk-textarea,
.vk-select {
  inline-size: 100%;
  min-inline-size: 0;

  background: var(--vk-surface-raised);
  border: var(--vk-border-width) solid var(--vk-border-default);
  border-radius: var(--vk-radius-sm);

  color: var(--vk-text-primary);
  font-family: inherit;
  font-size: var(--vk-text-sm);
  line-height: var(--vk-leading-normal);

  transition: var(--vk-transition-colors);
}

.vk-input,
.vk-select {
  block-size: var(--vk-control-height-md);
  padding-inline: var(--vk-space-3);
}

.vk-textarea {
  padding: var(--vk-space-3);
  min-block-size: 88px;
  resize: vertical;
}

.vk-input::placeholder,
.vk-textarea::placeholder {
  color: var(--vk-text-disabled);
}

.vk-input:hover:not(:disabled),
.vk-textarea:hover:not(:disabled),
.vk-select:hover:not(:disabled) {
  border-color: var(--vk-border-strong);
}

.vk-input:disabled,
.vk-textarea:disabled,
.vk-select:disabled {
  background: var(--vk-surface-disabled);
  color: var(--vk-text-disabled);
  cursor: not-allowed;
}

.vk-input[readonly],
.vk-textarea[readonly] {
  background: var(--vk-surface-sunken);
}

/* Invalid state is driven by aria-invalid so the visual and the
   accessibility tree can never disagree. */
.vk-input[aria-invalid="true"],
.vk-textarea[aria-invalid="true"],
.vk-select[aria-invalid="true"] {
  border-color: var(--vk-danger-solid);
}

.vk-input-sm {
  block-size: var(--vk-control-height-sm);
  font-size: var(--vk-text-xs);
}

/* Money and identifier inputs stay LTR and tabular even in Arabic. */
.vk-input-numeric {
  font-variant-numeric: tabular-nums;
  direction: ltr;
  text-align: start;
}

/* Input with a leading or trailing adornment (icon, currency, unit). */
.vk-input-group {
  position: relative;
  display: flex;
  align-items: center;
  inline-size: 100%;
}
.vk-input-group > .vk-input {
  flex: 1;
}
.vk-input-group-icon {
  position: absolute;
  inset-inline-start: var(--vk-space-3);
  display: flex;
  color: var(--vk-text-muted);
  pointer-events: none;
}
.vk-input-group-icon ~ .vk-input {
  padding-inline-start: var(--vk-space-10);
}
.vk-input-group-suffix {
  position: absolute;
  inset-inline-end: var(--vk-space-3);
  font-size: var(--vk-text-xs);
  color: var(--vk-text-muted);
  pointer-events: none;
  /* Isolated so a currency code never reorders against the amount when the
     surrounding paragraph is right-to-left. */
  unicode-bidi: isolate;
}

/* The suffix is absolutely positioned over the field, so the field has to
   reserve room for it. It cannot be done with a sibling combinator because
   the suffix follows the input in the DOM. */
.vk-input-group:has(.vk-input-group-suffix) .vk-input {
  padding-inline-end: var(--vk-space-12);
}

/* An amount field is a single left-to-right unit even on an Arabic page: the
   digits run LTR, so the currency suffix has to be placed by the same
   direction or it lands on top of the value. Turning the whole group LTR keeps
   the input and its adornment in agreement, and isolate stops that decision
   leaking back out into the surrounding RTL form. */
.vk-input-group:has(.vk-input-numeric) {
  direction: ltr;
  unicode-bidi: isolate;
}

/* ---------------------------------------------------------------- SELECT */

.vk-select {
  appearance: none;
  padding-inline-end: var(--vk-space-8);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--vk-space-3) center;
  background-size: 16px;
  cursor: pointer;
}

[dir="rtl"] .vk-select {
  background-position: left var(--vk-space-3) center;
}

/* -------------------------------------------------------------- CHECKBOX */

.vk-checkbox,
.vk-radio {
  display: flex;
  align-items: flex-start;
  gap: var(--vk-space-2);
  cursor: pointer;
  font-size: var(--vk-text-sm);
  color: var(--vk-text-primary);
}

.vk-checkbox input[type="checkbox"],
.vk-radio input[type="radio"] {
  flex: none;
  inline-size: 16px;
  block-size: 16px;
  margin: 2px 0 0;
  accent-color: var(--vk-accent-strong);
  cursor: pointer;
}

.vk-checkbox input:disabled,
.vk-radio input:disabled {
  cursor: not-allowed;
}
.vk-checkbox:has(input:disabled),
.vk-radio:has(input:disabled) {
  color: var(--vk-text-disabled);
  cursor: not-allowed;
}

.vk-checkbox-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  line-height: var(--vk-leading-snug);
}
.vk-checkbox-description {
  font-size: var(--vk-text-xs);
  color: var(--vk-text-muted);
}

/* A radio or checkbox rendered as a selectable card. Used for payment
   method choice, plan choice and worker choice. */
.vk-choice {
  display: flex;
  align-items: flex-start;
  gap: var(--vk-space-3);
  padding: var(--vk-space-4);
  background: var(--vk-surface-raised);
  border: var(--vk-border-width) solid var(--vk-border-default);
  border-radius: var(--vk-radius-md);
  cursor: pointer;
  transition: var(--vk-transition-colors);
}
.vk-choice:hover {
  border-color: var(--vk-border-strong);
  background: var(--vk-surface-hover);
}
.vk-choice:has(input:checked) {
  border-color: var(--vk-accent-strong);
  background: var(--vk-accent-subtle);
}
.vk-choice:has(input:disabled) {
  opacity: 0.55;
  cursor: not-allowed;
}
.vk-choice-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-inline-size: 0;
}
.vk-choice-title {
  font-size: var(--vk-text-sm);
  font-weight: var(--vk-weight-medium);
}
.vk-choice-description {
  font-size: var(--vk-text-xs);
  color: var(--vk-text-muted);
}

/* ---------------------------------------------------------------- SWITCH */

.vk-switch {
  display: flex;
  align-items: center;
  gap: var(--vk-space-3);
  cursor: pointer;
}

.vk-switch input {
  position: absolute;
  opacity: 0;
  inline-size: 0;
  block-size: 0;
}

.vk-switch-track {
  position: relative;
  flex: none;
  inline-size: 36px;
  block-size: 20px;
  background: var(--vk-graphite-300);
  border-radius: var(--vk-radius-full);
  transition: background-color var(--vk-duration-fast) var(--vk-ease-standard);
}

.vk-switch-track::after {
  content: "";
  position: absolute;
  inset-block-start: 2px;
  inset-inline-start: 2px;
  inline-size: 16px;
  block-size: 16px;
  background: var(--vk-graphite-0);
  border-radius: var(--vk-radius-full);
  box-shadow: var(--vk-shadow-xs);
  transition: transform var(--vk-duration-fast) var(--vk-ease-standard);
}

.vk-switch input:checked + .vk-switch-track {
  background: var(--vk-accent-strong);
}
.vk-switch input:checked + .vk-switch-track::after {
  transform: translateX(16px);
}
[dir="rtl"] .vk-switch input:checked + .vk-switch-track::after {
  transform: translateX(-16px);
}
.vk-switch input:disabled + .vk-switch-track {
  opacity: 0.5;
  cursor: not-allowed;
}

.vk-switch-label {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: var(--vk-text-sm);
}

/* ------------------------------------------------------------- FIELDSET */

.vk-fieldset {
  border: 0;
  padding: 0;
  margin: 0;
  min-inline-size: 0;
}
.vk-legend {
  padding: 0;
  margin-block-end: var(--vk-space-3);
  font-size: var(--vk-text-sm);
  font-weight: var(--vk-weight-semibold);
  color: var(--vk-text-primary);
}

/* Two-column form rows collapse to one column below tablet. */
.vk-form-row {
  display: grid;
  gap: var(--vk-space-4);
}
@media (min-width: 768px) {
  .vk-form-row-2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .vk-form-row-3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* ------------------------------------------------- INTERNATIONAL PHONE */

.vk-phone-intl {
  display: grid;
  grid-template-columns: minmax(7.5rem, auto) minmax(0, 1fr);
  gap: var(--vk-space-2);
  align-items: stretch;
}
.vk-phone-country {
  position: relative;
  min-inline-size: 0;
}
.vk-phone-country-trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--vk-space-2);
  inline-size: 100%;
  min-block-size: var(--vk-control-height, 2.75rem);
  padding-inline: var(--vk-space-3);
  border: var(--vk-border-width) solid var(--vk-border-strong);
  border-radius: var(--vk-radius-md);
  background: var(--vk-bg-elevated);
  color: var(--vk-text-primary);
  font: inherit;
  cursor: pointer;
}
.vk-phone-country-trigger:hover {
  border-color: var(--vk-border-focus, var(--vk-accent));
}
.vk-phone-flag {
  font-size: 1.15rem;
  line-height: 1;
}
.vk-phone-code {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.vk-phone-caret {
  margin-inline-start: auto;
  opacity: 0.7;
  font-size: 0.75rem;
}
.vk-phone-country-panel {
  position: absolute;
  inset-block-start: calc(100% + var(--vk-space-1));
  inset-inline-start: 0;
  z-index: 40;
  inline-size: min(22rem, 80vw);
  max-block-size: 16rem;
  display: flex;
  flex-direction: column;
  gap: var(--vk-space-2);
  padding: var(--vk-space-2);
  border: var(--vk-border-width) solid var(--vk-border-subtle);
  border-radius: var(--vk-radius-md);
  background: var(--vk-bg-elevated);
  box-shadow: var(--vk-shadow-md, 0 8px 24px rgba(0, 0, 0, 0.12));
}
.vk-phone-country-panel[hidden] {
  display: none !important;
}
.vk-phone-country-list {
  list-style: none;
  margin: 0;
  padding: 0;
  overflow: auto;
  max-block-size: 12rem;
}
.vk-phone-country-option {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: var(--vk-space-2);
  align-items: center;
  inline-size: 100%;
  padding: var(--vk-space-2) var(--vk-space-3);
  border: 0;
  border-radius: var(--vk-radius-sm);
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: start;
  cursor: pointer;
}
.vk-phone-country-option:hover,
.vk-phone-country-option.is-selected {
  background: var(--vk-bg-muted, rgba(0, 0, 0, 0.06));
}
.vk-phone-option-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vk-phone-option-code {
  color: var(--vk-text-muted);
  font-variant-numeric: tabular-nums;
}
.vk-phone-national {
  min-inline-size: 0;
}
[dir="rtl"] .vk-phone-caret {
  margin-inline-start: 0;
  margin-inline-end: auto;
}
@media (max-width: 480px) {
  .vk-phone-intl {
    grid-template-columns: 1fr;
  }
  .vk-phone-country-panel {
    inline-size: 100%;
  }
}

/* Sticky action bar for long forms. */
.vk-form-actions {
  display: flex;
  align-items: center;
  gap: var(--vk-space-3);
  padding-block-start: var(--vk-space-5);
  border-block-start: var(--vk-border-width) solid var(--vk-border-subtle);
}
.vk-form-actions-end {
  justify-content: flex-end;
}

/* ------------------------------------------------- TOUCH TARGET FLOOR */

@media (pointer: coarse) {
  .vk-btn,
  .vk-input,
  .vk-select {
    min-block-size: var(--vk-touch-target-min);
  }
  .vk-btn-sm,
  .vk-input-sm {
    min-block-size: 38px;
  }
  .vk-btn-icon {
    min-inline-size: var(--vk-touch-target-min);
  }
  .vk-checkbox input[type="checkbox"],
  .vk-radio input[type="radio"] {
    inline-size: 20px;
    block-size: 20px;
  }
}

/* ==========================================================================
   VEKMOT COMPONENTS — SURFACES
   --------------------------------------------------------------------------
   Cards, panels, tables, badges, avatars, metrics, lists and timelines.

   Tables are the load-bearing component of this product: bookings, staff,
   invoices, payments, referrals, commissions, audit. They therefore get a
   responsive strategy rather than a horizontal scrollbar — below tablet a
   table collapses into stacked records using the header text supplied via
   data-label, which keeps every cell labelled for both sighted and
   screen-reader users.
   ========================================================================== */

/* ------------------------------------------------------------------ CARD */

.vk-card {
  display: flex;
  flex-direction: column;
  min-inline-size: 0;
  background: var(--vk-surface-raised);
  border: var(--vk-border-width) solid var(--vk-border-subtle);
  border-radius: var(--vk-radius-md);
}

.vk-card-raised {
  box-shadow: var(--vk-elevation-raised);
}

.vk-card-quiet {
  background: transparent;
  border-color: var(--vk-border-subtle);
}

.vk-card-sunken {
  background: var(--vk-surface-sunken);
  border-color: transparent;
}

/* An interactive card — a booking, a shop, a staff member. */
.vk-card-link {
  cursor: pointer;
  text-decoration: none;
  color: inherit;
  transition: var(--vk-transition-colors);
}
.vk-card-link:hover {
  border-color: var(--vk-border-strong);
  background: var(--vk-surface-hover);
}

.vk-card-header {
  display: flex;
  align-items: center;
  gap: var(--vk-space-3);
  padding: var(--vk-space-4) var(--vk-space-5);
  border-block-end: var(--vk-border-width) solid var(--vk-border-subtle);
}

.vk-card-title {
  font-size: var(--vk-text-sm);
  font-weight: var(--vk-weight-semibold);
  letter-spacing: var(--vk-tracking-snug);
  color: var(--vk-text-primary);
}

.vk-card-subtitle {
  font-size: var(--vk-text-xs);
  color: var(--vk-text-muted);
}

.vk-card-actions {
  margin-inline-start: auto;
  display: flex;
  align-items: center;
  gap: var(--vk-space-2);
}

.vk-card-body {
  padding: var(--vk-space-5);
  min-inline-size: 0;
}

.vk-card-body-flush {
  padding: 0;
}

.vk-card-footer {
  display: flex;
  align-items: center;
  gap: var(--vk-space-3);
  padding: var(--vk-space-4) var(--vk-space-5);
  border-block-start: var(--vk-border-width) solid var(--vk-border-subtle);
  background: var(--vk-surface-sunken);
  border-end-start-radius: var(--vk-radius-md);
  border-end-end-radius: var(--vk-radius-md);
}

/* ------------------------------------------------------------ PAGE HEADER */

.vk-page-header {
  display: flex;
  align-items: flex-start;
  gap: var(--vk-space-4);
  flex-wrap: wrap;
  padding-block-end: var(--vk-space-5);
}

.vk-page-header-text {
  display: flex;
  flex-direction: column;
  gap: var(--vk-space-1);
  min-inline-size: 0;
  flex: 1;
}

.vk-page-header-actions {
  display: flex;
  align-items: center;
  gap: var(--vk-space-2);
  flex-wrap: wrap;
}

/* ----------------------------------------------------------- BREADCRUMB */

.vk-breadcrumb {
  display: flex;
  align-items: center;
  gap: var(--vk-space-1);
  flex-wrap: wrap;
  font-size: var(--vk-text-xs);
  color: var(--vk-text-muted);
}
.vk-breadcrumb a {
  color: var(--vk-text-muted);
  text-decoration: none;
}
.vk-breadcrumb a:hover {
  color: var(--vk-text-primary);
  text-decoration: underline;
}
.vk-breadcrumb-separator {
  color: var(--vk-text-disabled);
  display: flex;
}
.vk-breadcrumb [aria-current="page"] {
  color: var(--vk-text-primary);
  font-weight: var(--vk-weight-medium);
}

/* ----------------------------------------------------------------- BADGE */

.vk-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--vk-space-1);
  padding: 2px var(--vk-space-2);
  border: var(--vk-border-width) solid transparent;
  border-radius: var(--vk-radius-sm);
  font-size: var(--vk-text-2xs);
  font-weight: var(--vk-weight-medium);
  line-height: 1.5;
  white-space: nowrap;
}

.vk-badge-neutral {
  background: var(--vk-neutral-surface);
  border-color: var(--vk-neutral-border);
  color: var(--vk-neutral-text);
}
.vk-badge-success {
  background: var(--vk-success-surface);
  border-color: var(--vk-success-border);
  color: var(--vk-success-text);
}
.vk-badge-warning {
  background: var(--vk-warning-surface);
  border-color: var(--vk-warning-border);
  color: var(--vk-warning-text);
}
.vk-badge-danger {
  background: var(--vk-danger-surface);
  border-color: var(--vk-danger-border);
  color: var(--vk-danger-text);
}
.vk-badge-info {
  background: var(--vk-info-surface);
  border-color: var(--vk-info-border);
  color: var(--vk-info-text);
}
.vk-badge-accent {
  background: var(--vk-accent-subtle);
  border-color: var(--vk-accent-muted);
  color: var(--vk-accent-strong);
}

.vk-badge-solid {
  border-color: transparent;
}
.vk-badge-solid.vk-badge-success {
  background: var(--vk-success-solid);
  color: var(--vk-success-on-solid);
}
.vk-badge-solid.vk-badge-danger {
  background: var(--vk-danger-solid);
  color: var(--vk-danger-on-solid);
}

/* A count badge on a nav item or tab. */
.vk-badge-count {
  min-inline-size: 18px;
  block-size: 18px;
  padding-inline: 5px;
  justify-content: center;
  border-radius: var(--vk-radius-full);
  font-variant-numeric: tabular-nums;
}

/* -------------------------------------------------------- STATUS INDICATOR
   A dot plus a label. The dot alone is never the whole signal — the label
   carries the meaning so status is legible without colour perception. */

.vk-status {
  display: inline-flex;
  align-items: center;
  gap: var(--vk-space-2);
  font-size: var(--vk-text-xs);
  font-weight: var(--vk-weight-medium);
  white-space: nowrap;
}

.vk-status-dot {
  flex: none;
  inline-size: 7px;
  block-size: 7px;
  border-radius: var(--vk-radius-full);
  background: var(--vk-neutral-solid);
}
.vk-status-success .vk-status-dot {
  background: var(--vk-success-solid);
}
.vk-status-warning .vk-status-dot {
  background: var(--vk-warning-solid);
}
.vk-status-danger .vk-status-dot {
  background: var(--vk-danger-solid);
}
.vk-status-info .vk-status-dot {
  background: var(--vk-info-solid);
}
.vk-status-accent .vk-status-dot {
  background: var(--vk-accent-strong);
}

/* A live/pulsing dot for genuinely real-time state only. */
.vk-status-live .vk-status-dot {
  animation: vk-pulse 2s var(--vk-ease-standard) infinite;
}
@keyframes vk-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.35;
  }
}
@media (prefers-reduced-motion: reduce) {
  .vk-status-live .vk-status-dot {
    animation: none;
  }
}

/* ---------------------------------------------------------------- AVATAR */

.vk-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  inline-size: 32px;
  block-size: 32px;
  border-radius: var(--vk-radius-full);
  background: var(--vk-accent-subtle);
  color: var(--vk-accent-strong);
  font-size: var(--vk-text-xs);
  font-weight: var(--vk-weight-semibold);
  text-transform: uppercase;
  overflow: hidden;
  user-select: none;
}
.vk-avatar img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}
.vk-avatar-sm {
  inline-size: 24px;
  block-size: 24px;
  font-size: var(--vk-text-2xs);
}
.vk-avatar-lg {
  inline-size: 40px;
  block-size: 40px;
  font-size: var(--vk-text-sm);
}
.vk-avatar-xl {
  inline-size: 56px;
  block-size: 56px;
  font-size: var(--vk-text-lg);
}

/* ------------------------------------------------------------- METRIC */

.vk-metric {
  display: flex;
  flex-direction: column;
  gap: var(--vk-space-1);
  min-inline-size: 0;
}

.vk-metric-label {
  font-size: var(--vk-text-xs);
  font-weight: var(--vk-weight-medium);
  color: var(--vk-text-muted);
}

.vk-metric-value {
  font-size: var(--vk-text-2xl);
  font-weight: var(--vk-weight-semibold);
  line-height: var(--vk-leading-tight);
  letter-spacing: var(--vk-tracking-tight);
  font-variant-numeric: tabular-nums;
  color: var(--vk-text-primary);
}
.vk-metric-value-sm {
  font-size: var(--vk-text-xl);
}

.vk-metric-meta {
  display: flex;
  align-items: center;
  gap: var(--vk-space-1);
  font-size: var(--vk-text-xs);
  color: var(--vk-text-muted);
}

.vk-metric-delta {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-weight: var(--vk-weight-medium);
  font-variant-numeric: tabular-nums;
}
.vk-metric-delta-up {
  color: var(--vk-success-text);
}
.vk-metric-delta-down {
  color: var(--vk-danger-text);
}
.vk-metric-delta-flat {
  color: var(--vk-text-muted);
}

/* ------------------------------------------------------------------ TABLE */

.vk-table-wrap {
  inline-size: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.vk-table {
  inline-size: 100%;
  border-collapse: collapse;
  font-size: var(--vk-text-sm);
}

.vk-table th,
.vk-table td {
  padding: var(--vk-space-3) var(--vk-space-4);
  text-align: start;
  vertical-align: middle;
}

.vk-table thead th {
  position: relative;
  font-size: var(--vk-text-xs);
  font-weight: var(--vk-weight-medium);
  color: var(--vk-text-muted);
  white-space: nowrap;
  border-block-end: var(--vk-border-width) solid var(--vk-border-default);
  background: var(--vk-surface-raised);
}

.vk-table tbody tr {
  border-block-end: var(--vk-border-width) solid var(--vk-border-subtle);
}
.vk-table tbody tr:last-child {
  border-block-end: 0;
}

.vk-table-hover tbody tr:hover {
  background: var(--vk-surface-hover);
}

.vk-table-row-link {
  cursor: pointer;
}

.vk-table td.vk-table-numeric,
.vk-table th.vk-table-numeric {
  text-align: end;
  font-variant-numeric: tabular-nums;
}

.vk-table-actions {
  display: flex;
  align-items: center;
  gap: var(--vk-space-1);
  justify-content: flex-end;
}

.vk-table-sticky thead th {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--vk-z-sticky);
}

/* Sortable header. */
.vk-table-sort {
  display: inline-flex;
  align-items: center;
  gap: var(--vk-space-1);
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
}
.vk-table-sort:hover {
  color: var(--vk-text-primary);
}

/* Primary cell — the identifying value in a row. */
.vk-table-primary {
  font-weight: var(--vk-weight-medium);
  color: var(--vk-text-primary);
}

/* ------------------------------------------------- RESPONSIVE TABLE CARDS
   Below tablet the table becomes a list of records. Each cell prints its
   column name from data-label, so no information is lost and nothing needs
   to be scrolled horizontally on a phone. */

@media (max-width: 767px) {
  .vk-table-responsive thead {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .vk-table-responsive,
  .vk-table-responsive tbody,
  .vk-table-responsive tr,
  .vk-table-responsive td {
    display: block;
    inline-size: 100%;
  }

  .vk-table-responsive tbody tr {
    padding: var(--vk-space-3) var(--vk-space-4);
    border: var(--vk-border-width) solid var(--vk-border-subtle);
    border-radius: var(--vk-radius-md);
    margin-block-end: var(--vk-space-3);
    background: var(--vk-surface-raised);
  }

  .vk-table-responsive td {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--vk-space-4);
    padding: var(--vk-space-2) 0;
    text-align: end;
  }

  .vk-table-responsive td::before {
    content: attr(data-label);
    flex: none;
    font-size: var(--vk-text-xs);
    font-weight: var(--vk-weight-medium);
    color: var(--vk-text-muted);
    text-align: start;
  }

  .vk-table-responsive td:empty {
    display: none;
  }

  .vk-table-responsive .vk-table-actions {
    justify-content: flex-end;
  }
}

/* -------------------------------------------------------------- DATA LIST
   Label/value pairs — booking detail, payment detail, invoice summary. */

.vk-datalist {
  display: grid;
  gap: var(--vk-space-3);
  margin: 0;
}
@media (min-width: 640px) {
  .vk-datalist-2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.vk-datalist-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-inline-size: 0;
}
.vk-datalist-term {
  font-size: var(--vk-text-xs);
  color: var(--vk-text-muted);
}
.vk-datalist-value {
  font-size: var(--vk-text-sm);
  color: var(--vk-text-primary);
  word-break: break-word;
}

/* Inline row variant for dense summaries (checkout totals). */
.vk-datarow {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--vk-space-4);
  padding-block: var(--vk-space-2);
}
.vk-datarow-total {
  padding-block-start: var(--vk-space-3);
  margin-block-start: var(--vk-space-2);
  border-block-start: var(--vk-border-width) solid var(--vk-border-default);
  font-weight: var(--vk-weight-semibold);
  font-size: var(--vk-text-base);
}

/* --------------------------------------------------------------- TIMELINE
   Audit trails, payment event history, booking history. */

.vk-timeline {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  list-style: none;
}

.vk-timeline-item {
  position: relative;
  display: flex;
  gap: var(--vk-space-3);
  padding-block-end: var(--vk-space-5);
}
.vk-timeline-item:last-child {
  padding-block-end: 0;
}

/* The connecting rail. Uses inset-inline so it mirrors in RTL. */
.vk-timeline-item:not(:last-child)::before {
  content: "";
  position: absolute;
  inset-block: 22px 0;
  inset-inline-start: 11px;
  inline-size: var(--vk-border-width);
  background: var(--vk-border-default);
}

.vk-timeline-marker {
  position: relative;
  z-index: var(--vk-z-raised);
  flex: none;
  inline-size: 24px;
  block-size: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--vk-radius-full);
  background: var(--vk-surface-raised);
  border: var(--vk-border-width) solid var(--vk-border-default);
  color: var(--vk-text-muted);
}
.vk-timeline-marker-success {
  background: var(--vk-success-surface);
  border-color: var(--vk-success-border);
  color: var(--vk-success-text);
}
.vk-timeline-marker-danger {
  background: var(--vk-danger-surface);
  border-color: var(--vk-danger-border);
  color: var(--vk-danger-text);
}
.vk-timeline-marker-warning {
  background: var(--vk-warning-surface);
  border-color: var(--vk-warning-border);
  color: var(--vk-warning-text);
}

.vk-timeline-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-inline-size: 0;
  padding-block-start: 2px;
}
.vk-timeline-title {
  font-size: var(--vk-text-sm);
  font-weight: var(--vk-weight-medium);
}
.vk-timeline-meta {
  font-size: var(--vk-text-xs);
  color: var(--vk-text-muted);
}

/* ----------------------------------------------------------- DESCRIPTION
   A titled panel section used inside long settings pages. */

.vk-section {
  display: flex;
  flex-direction: column;
  gap: var(--vk-space-4);
}
.vk-section-head {
  display: flex;
  flex-direction: column;
  gap: var(--vk-space-1);
}
.vk-section-title {
  font-size: var(--vk-text-base);
  font-weight: var(--vk-weight-semibold);
  letter-spacing: var(--vk-tracking-snug);
}
.vk-section-description {
  font-size: var(--vk-text-sm);
  color: var(--vk-text-muted);
  max-inline-size: var(--vk-prose-max-width);
}

/* ==========================================================================
   VEKMOT COMPONENTS — FEEDBACK
   --------------------------------------------------------------------------
   Alerts, toasts, empty states, error states, skeletons, progress and
   tooltips.

   Every state component pairs an icon with its text. WCAG 2.2 AA forbids
   colour as the sole carrier of meaning, and this product shows money and
   payment outcomes, where a misread state is a real-world error.
   ========================================================================== */

/* ----------------------------------------------------------------- ALERT */

.vk-alert {
  display: flex;
  align-items: flex-start;
  gap: var(--vk-space-3);
  padding: var(--vk-space-4);
  border: var(--vk-border-width) solid;
  border-radius: var(--vk-radius-md);
  font-size: var(--vk-text-sm);
  line-height: var(--vk-leading-snug);
}

.vk-alert-icon {
  flex: none;
  margin-block-start: 1px;
}

.vk-alert-body {
  display: flex;
  flex-direction: column;
  gap: var(--vk-space-1);
  min-inline-size: 0;
  flex: 1;
}

.vk-alert-title {
  font-weight: var(--vk-weight-semibold);
}

.vk-alert-actions {
  display: flex;
  gap: var(--vk-space-2);
  margin-block-start: var(--vk-space-2);
}

.vk-alert-dismiss {
  flex: none;
  margin-inline-start: auto;
  background: none;
  border: 0;
  padding: var(--vk-space-1);
  border-radius: var(--vk-radius-sm);
  color: inherit;
  opacity: 0.65;
  cursor: pointer;
}
.vk-alert-dismiss:hover {
  opacity: 1;
}

.vk-alert-info {
  background: var(--vk-info-surface);
  border-color: var(--vk-info-border);
  color: var(--vk-info-text);
}
.vk-alert-success {
  background: var(--vk-success-surface);
  border-color: var(--vk-success-border);
  color: var(--vk-success-text);
}
.vk-alert-warning {
  background: var(--vk-warning-surface);
  border-color: var(--vk-warning-border);
  color: var(--vk-warning-text);
}
.vk-alert-danger {
  background: var(--vk-danger-surface);
  border-color: var(--vk-danger-border);
  color: var(--vk-danger-text);
}
.vk-alert-neutral {
  background: var(--vk-neutral-surface);
  border-color: var(--vk-neutral-border);
  color: var(--vk-text-secondary);
}

/* ----------------------------------------------------------------- TOAST
   Transient confirmation of a completed action. Toasts are announced by
   the live region in the shell, never by themselves. */

.vk-toast-region {
  position: fixed;
  inset-block-end: var(--vk-space-4);
  inset-inline-end: var(--vk-space-4);
  z-index: var(--vk-z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--vk-space-2);
  inline-size: min(380px, calc(100vw - var(--vk-space-8)));
  pointer-events: none;
}

@media (max-width: 639px) {
  .vk-toast-region {
    inset-block-end: calc(var(--vk-mobile-nav-height) + var(--vk-space-4));
    inset-inline: var(--vk-space-3);
    inline-size: auto;
  }
}

.vk-toast {
  display: flex;
  align-items: flex-start;
  gap: var(--vk-space-3);
  padding: var(--vk-space-3) var(--vk-space-4);
  background: var(--vk-surface-overlay);
  border: var(--vk-border-width) solid var(--vk-border-default);
  border-radius: var(--vk-radius-md);
  box-shadow: var(--vk-elevation-toast);
  font-size: var(--vk-text-sm);
  pointer-events: auto;
  animation: vk-toast-in var(--vk-duration-base) var(--vk-ease-out);
}

.vk-toast.is-leaving {
  animation: vk-toast-out var(--vk-duration-fast) var(--vk-ease-in) forwards;
}

@keyframes vk-toast-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}
@keyframes vk-toast-out {
  to {
    opacity: 0;
    transform: translateY(4px);
  }
}
@media (prefers-reduced-motion: reduce) {
  .vk-toast,
  .vk-toast.is-leaving {
    animation: none;
  }
}

.vk-toast-body {
  flex: 1;
  min-inline-size: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.vk-toast-title {
  font-weight: var(--vk-weight-medium);
  color: var(--vk-text-primary);
}
.vk-toast-message {
  font-size: var(--vk-text-xs);
  color: var(--vk-text-muted);
}

.vk-toast-success .vk-toast-icon {
  color: var(--vk-success-text);
}
.vk-toast-danger .vk-toast-icon {
  color: var(--vk-danger-text);
}
.vk-toast-warning .vk-toast-icon {
  color: var(--vk-warning-text);
}
.vk-toast-info .vk-toast-icon {
  color: var(--vk-info-text);
}

.vk-toast-close {
  flex: none;
  background: none;
  border: 0;
  padding: 2px;
  border-radius: var(--vk-radius-sm);
  color: var(--vk-text-muted);
  cursor: pointer;
}
.vk-toast-close:hover {
  color: var(--vk-text-primary);
}

/* ------------------------------------------------------------ EMPTY STATE
   An empty state must say what is missing and offer the action that
   resolves it. A blank panel is a defect, not a state. */

.vk-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--vk-space-3);
  padding: var(--vk-space-12) var(--vk-space-6);
  text-align: center;
}

.vk-empty-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  inline-size: 48px;
  block-size: 48px;
  border-radius: var(--vk-radius-full);
  background: var(--vk-surface-sunken);
  color: var(--vk-text-muted);
  margin-block-end: var(--vk-space-1);
}

.vk-empty-title {
  font-size: var(--vk-text-base);
  font-weight: var(--vk-weight-semibold);
  color: var(--vk-text-primary);
}

.vk-empty-description {
  font-size: var(--vk-text-sm);
  color: var(--vk-text-muted);
  max-inline-size: 42ch;
  line-height: var(--vk-leading-normal);
}

.vk-empty-actions {
  display: flex;
  gap: var(--vk-space-2);
  margin-block-start: var(--vk-space-2);
  flex-wrap: wrap;
  justify-content: center;
}

.vk-empty-compact {
  padding: var(--vk-space-8) var(--vk-space-4);
}

/* Error state — an empty state whose cause is a failure, with a retry. */
.vk-empty-error .vk-empty-icon {
  background: var(--vk-danger-surface);
  color: var(--vk-danger-text);
}

/* --------------------------------------------------------------- SKELETON
   Shape-preserving placeholder. Marked aria-hidden by the macro so it is
   never announced; the surrounding region carries aria-busy instead. */

.vk-skeleton {
  display: block;
  background: var(--vk-surface-sunken);
  border-radius: var(--vk-radius-sm);
  position: relative;
  overflow: hidden;
}

.vk-skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    transparent,
    var(--vk-surface-hover),
    transparent
  );
  animation: vk-shimmer 1.4s infinite;
}

@keyframes vk-shimmer {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(100%);
  }
}

[dir="rtl"] .vk-skeleton::after {
  animation-name: vk-shimmer-rtl;
}
@keyframes vk-shimmer-rtl {
  from {
    transform: translateX(100%);
  }
  to {
    transform: translateX(-100%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .vk-skeleton::after {
    animation: none;
  }
}

.vk-skeleton-text {
  block-size: 12px;
  margin-block: 4px;
}
.vk-skeleton-title {
  block-size: 20px;
  inline-size: 40%;
}
.vk-skeleton-line-short {
  inline-size: 60%;
}
.vk-skeleton-avatar {
  inline-size: 32px;
  block-size: 32px;
  border-radius: var(--vk-radius-full);
}
.vk-skeleton-block {
  block-size: 96px;
  border-radius: var(--vk-radius-md);
}
.vk-skeleton-row {
  block-size: 44px;
  margin-block-end: var(--vk-space-2);
  border-radius: var(--vk-radius-sm);
}

/* -------------------------------------------------------------- SPINNER */

.vk-spinner {
  display: inline-block;
  inline-size: 16px;
  block-size: 16px;
  border: 2px solid var(--vk-border-default);
  border-block-start-color: var(--vk-accent-strong);
  border-radius: var(--vk-radius-full);
  animation: vk-spin 620ms linear infinite;
}
.vk-spinner-lg {
  inline-size: 28px;
  block-size: 28px;
  border-width: 3px;
}
@media (prefers-reduced-motion: reduce) {
  .vk-spinner {
    animation-duration: 1600ms;
  }
}

/* A centred loading panel used while a region fetches. */
.vk-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--vk-space-3);
  padding: var(--vk-space-10);
  color: var(--vk-text-muted);
  font-size: var(--vk-text-sm);
}

/* -------------------------------------------------------------- PROGRESS */

.vk-progress {
  inline-size: 100%;
  block-size: 6px;
  background: var(--vk-surface-sunken);
  border-radius: var(--vk-radius-full);
  overflow: hidden;
}
.vk-progress-bar {
  block-size: 100%;
  background: var(--vk-accent-strong);
  border-radius: var(--vk-radius-full);
  transition: inline-size var(--vk-duration-slow) var(--vk-ease-out);
}
.vk-progress-success .vk-progress-bar {
  background: var(--vk-success-solid);
}
.vk-progress-danger .vk-progress-bar {
  background: var(--vk-danger-solid);
}

/* Indeterminate — used for terminal polling, where no percentage exists. */
.vk-progress-indeterminate .vk-progress-bar {
  inline-size: 35%;
  animation: vk-indeterminate 1.4s var(--vk-ease-standard) infinite;
}
@keyframes vk-indeterminate {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(340%);
  }
}
@media (prefers-reduced-motion: reduce) {
  .vk-progress-indeterminate .vk-progress-bar {
    animation: none;
    inline-size: 100%;
    opacity: 0.4;
  }
}

/* Stepper progress for the booking flow. */
.vk-steps {
  display: flex;
  align-items: center;
  gap: var(--vk-space-2);
  list-style: none;
  margin: 0;
  padding: 0;
}
.vk-step {
  display: flex;
  align-items: center;
  gap: var(--vk-space-2);
  font-size: var(--vk-text-xs);
  color: var(--vk-text-muted);
  min-inline-size: 0;
}
.vk-step-marker {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  inline-size: 22px;
  block-size: 22px;
  border-radius: var(--vk-radius-full);
  border: var(--vk-border-width) solid var(--vk-border-default);
  font-size: var(--vk-text-2xs);
  font-weight: var(--vk-weight-semibold);
  font-variant-numeric: tabular-nums;
}
.vk-step-current .vk-step-marker {
  background: var(--vk-accent-strong);
  border-color: var(--vk-accent-strong);
  color: var(--vk-accent-on);
}
.vk-step-current {
  color: var(--vk-text-primary);
  font-weight: var(--vk-weight-medium);
}
.vk-step-done .vk-step-marker {
  background: var(--vk-success-surface);
  border-color: var(--vk-success-border);
  color: var(--vk-success-text);
}
.vk-step-connector {
  flex: 1;
  min-inline-size: var(--vk-space-4);
  block-size: var(--vk-border-width);
  background: var(--vk-border-default);
}
.vk-step-label {
  white-space: nowrap;
}
@media (max-width: 639px) {
  .vk-step:not(.vk-step-current) .vk-step-label {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }
}

/* --------------------------------------------------------------- TOOLTIP
   CSS-only, driven by hover and focus-within so it is keyboard reachable.
   The tooltip text is also the control's accessible description. */

.vk-tooltip {
  position: relative;
  display: inline-flex;
}

.vk-tooltip-content {
  position: absolute;
  inset-block-end: calc(100% + var(--vk-space-2));
  inset-inline-start: 50%;
  transform: translateX(-50%);
  z-index: var(--vk-z-tooltip);

  padding: var(--vk-space-1) var(--vk-space-2);
  background: var(--vk-surface-inverse);
  color: var(--vk-text-inverse);
  border-radius: var(--vk-radius-sm);
  font-size: var(--vk-text-xs);
  white-space: nowrap;

  opacity: 0;
  visibility: hidden;
  transition: opacity var(--vk-duration-fast) var(--vk-ease-standard),
    visibility var(--vk-duration-fast);
}

.vk-tooltip:hover .vk-tooltip-content,
.vk-tooltip:focus-within .vk-tooltip-content {
  opacity: 1;
  visibility: visible;
}

/* ------------------------------------------------------------- CALLOUT
   A quiet inline note. Lower weight than an alert; used for guidance
   rather than state. */

.vk-callout {
  display: flex;
  gap: var(--vk-space-3);
  padding: var(--vk-space-3) var(--vk-space-4);
  background: var(--vk-surface-sunken);
  border-inline-start: 3px solid var(--vk-accent-muted);
  border-radius: var(--vk-radius-sm);
  font-size: var(--vk-text-xs);
  color: var(--vk-text-secondary);
  line-height: var(--vk-leading-snug);
}

/* ==========================================================================
   VEKMOT COMPONENTS — OVERLAYS
   --------------------------------------------------------------------------
   Dialogs, drawers, dropdowns, popovers and the command palette.

   Dialogs and drawers are built on the native <dialog> element. showModal()
   gives focus trapping, inert background, Escape-to-close and the top layer
   for free — all behaviour that hand-rolled overlays routinely get wrong,
   and all of it required for WCAG 2.2 AA.
   ========================================================================== */

/* ---------------------------------------------------------------- DIALOG */

.vk-dialog {
  padding: 0;
  border: var(--vk-border-width) solid var(--vk-border-default);
  border-radius: var(--vk-radius-lg);
  background: var(--vk-surface-overlay);
  color: var(--vk-text-primary);
  box-shadow: var(--vk-elevation-modal);

  inline-size: min(520px, calc(100vw - var(--vk-space-8)));
  max-block-size: min(85vh, 720px);
  overflow: visible;
}

.vk-dialog::backdrop {
  background: var(--vk-surface-scrim);
  backdrop-filter: blur(2px);
}

.vk-dialog[open] {
  animation: vk-dialog-in var(--vk-duration-base) var(--vk-ease-out);
}
@keyframes vk-dialog-in {
  from {
    opacity: 0;
    transform: translateY(8px) scale(0.985);
  }
}
@media (prefers-reduced-motion: reduce) {
  .vk-dialog[open] {
    animation: none;
  }
}

.vk-dialog-sm {
  inline-size: min(400px, calc(100vw - var(--vk-space-8)));
}
.vk-dialog-lg {
  inline-size: min(760px, calc(100vw - var(--vk-space-8)));
}

.vk-dialog-inner {
  display: flex;
  flex-direction: column;
  max-block-size: inherit;
  overflow: hidden;
  border-radius: inherit;
}

.vk-dialog-header {
  display: flex;
  align-items: flex-start;
  gap: var(--vk-space-3);
  padding: var(--vk-space-5) var(--vk-space-5) var(--vk-space-4);
}

.vk-dialog-title {
  font-size: var(--vk-text-lg);
  font-weight: var(--vk-weight-semibold);
  letter-spacing: var(--vk-tracking-snug);
  line-height: var(--vk-leading-tight);
}

.vk-dialog-description {
  font-size: var(--vk-text-sm);
  color: var(--vk-text-muted);
  line-height: var(--vk-leading-normal);
  margin-block-start: var(--vk-space-1);
}

.vk-dialog-close {
  flex: none;
  margin-inline-start: auto;
}

.vk-dialog-body {
  padding: 0 var(--vk-space-5) var(--vk-space-5);
  overflow-y: auto;
  flex: 1;
}

.vk-dialog-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--vk-space-2);
  padding: var(--vk-space-4) var(--vk-space-5);
  border-block-start: var(--vk-border-width) solid var(--vk-border-subtle);
  background: var(--vk-surface-sunken);
}

/* On a phone a dialog becomes a bottom sheet: reachable with a thumb,
   and it does not float in the middle of a small viewport. */
@media (max-width: 639px) {
  .vk-dialog {
    inline-size: 100vw;
    max-inline-size: 100vw;
    margin: 0;
    margin-block-start: auto;
    border-radius: var(--vk-radius-lg) var(--vk-radius-lg) 0 0;
    border-inline: 0;
    border-block-end: 0;
    max-block-size: 92vh;
  }
  .vk-dialog[open] {
    animation: vk-sheet-in var(--vk-duration-base) var(--vk-ease-out);
  }
  @keyframes vk-sheet-in {
    from {
      transform: translateY(100%);
    }
  }
  .vk-dialog-footer {
    flex-direction: column-reverse;
    align-items: stretch;
    padding-block-end: calc(var(--vk-space-4) + env(safe-area-inset-bottom, 0px));
  }
  .vk-dialog-footer .vk-btn {
    inline-size: 100%;
  }
}

/* Confirmation dialog — icon carries the severity. */
.vk-confirm-icon {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  inline-size: 40px;
  block-size: 40px;
  border-radius: var(--vk-radius-full);
  background: var(--vk-danger-surface);
  color: var(--vk-danger-text);
}
.vk-confirm-icon-warning {
  background: var(--vk-warning-surface);
  color: var(--vk-warning-text);
}
.vk-confirm-icon-info {
  background: var(--vk-info-surface);
  color: var(--vk-info-text);
}

/* ---------------------------------------------------------------- DRAWER
   A side panel for detail without losing list context: booking detail,
   payment detail, audit record, customer record. */

.vk-drawer {
  padding: 0;
  border: 0;
  border-inline-start: var(--vk-border-width) solid var(--vk-border-default);
  background: var(--vk-surface-overlay);
  color: var(--vk-text-primary);
  box-shadow: var(--vk-elevation-modal);

  inline-size: min(480px, 100vw);
  max-inline-size: 100vw;
  block-size: 100vh;
  max-block-size: 100vh;

  margin: 0;
  margin-inline-start: auto;
  inset-block: 0;
  inset-inline-end: 0;
}

.vk-drawer::backdrop {
  background: var(--vk-surface-scrim);
}

.vk-drawer-lg {
  inline-size: min(680px, 100vw);
}

.vk-drawer[open] {
  animation: vk-drawer-in var(--vk-duration-base) var(--vk-ease-out);
}
@keyframes vk-drawer-in {
  from {
    transform: translateX(100%);
  }
}
[dir="rtl"] .vk-drawer[open] {
  animation-name: vk-drawer-in-rtl;
}
@keyframes vk-drawer-in-rtl {
  from {
    transform: translateX(-100%);
  }
}
@media (prefers-reduced-motion: reduce) {
  .vk-drawer[open] {
    animation: none;
  }
}

.vk-drawer-inner {
  display: flex;
  flex-direction: column;
  block-size: 100%;
  overflow: hidden;
}

.vk-drawer-header {
  display: flex;
  align-items: flex-start;
  gap: var(--vk-space-3);
  padding: var(--vk-space-5);
  border-block-end: var(--vk-border-width) solid var(--vk-border-subtle);
}

.vk-drawer-title {
  font-size: var(--vk-text-base);
  font-weight: var(--vk-weight-semibold);
  letter-spacing: var(--vk-tracking-snug);
}

.vk-drawer-body {
  flex: 1;
  overflow-y: auto;
  padding: var(--vk-space-5);
}

.vk-drawer-footer {
  display: flex;
  align-items: center;
  gap: var(--vk-space-2);
  padding: var(--vk-space-4) var(--vk-space-5);
  border-block-start: var(--vk-border-width) solid var(--vk-border-subtle);
  background: var(--vk-surface-sunken);
  padding-block-end: calc(var(--vk-space-4) + env(safe-area-inset-bottom, 0px));
}

/* Below tablet a drawer becomes a full-height bottom sheet. */
@media (max-width: 767px) {
  .vk-drawer {
    inline-size: 100vw;
    block-size: 92vh;
    margin-block-start: auto;
    border-inline-start: 0;
    border-radius: var(--vk-radius-lg) var(--vk-radius-lg) 0 0;
  }
  .vk-drawer[open],
  [dir="rtl"] .vk-drawer[open] {
    animation-name: vk-sheet-in;
  }
}

/* -------------------------------------------------------------- DROPDOWN
   Uses the popover attribute where supported and degrades to a plain
   absolutely-positioned menu. */

.vk-dropdown {
  position: relative;
  display: inline-flex;
}

.vk-menu {
  position: absolute;
  inset-block-start: calc(100% + var(--vk-space-1));
  inset-inline-end: 0;
  z-index: var(--vk-z-dropdown);

  min-inline-size: 200px;
  max-block-size: 340px;
  overflow-y: auto;
  padding: var(--vk-space-1);
  margin: 0;
  list-style: none;

  background: var(--vk-surface-overlay);
  border: var(--vk-border-width) solid var(--vk-border-default);
  border-radius: var(--vk-radius-md);
  box-shadow: var(--vk-elevation-dropdown);
}

.vk-menu[hidden] {
  display: none;
}

.vk-menu-start {
  inset-inline-start: 0;
  inset-inline-end: auto;
}

.vk-menu-item {
  display: flex;
  align-items: center;
  gap: var(--vk-space-2);
  inline-size: 100%;
  padding: var(--vk-space-2) var(--vk-space-3);
  border: 0;
  border-radius: var(--vk-radius-sm);
  background: none;
  color: var(--vk-text-primary);
  font: inherit;
  font-size: var(--vk-text-sm);
  text-align: start;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
}
.vk-menu-item:hover,
.vk-menu-item:focus-visible {
  background: var(--vk-surface-hover);
}
.vk-menu-item[aria-disabled="true"],
.vk-menu-item:disabled {
  color: var(--vk-text-disabled);
  cursor: not-allowed;
  pointer-events: none;
}
.vk-menu-item-danger {
  color: var(--vk-danger-text);
}
.vk-menu-item-danger:hover {
  background: var(--vk-danger-surface);
}
.vk-menu-item-icon {
  flex: none;
  color: var(--vk-text-muted);
}
.vk-menu-item-danger .vk-menu-item-icon {
  color: inherit;
}
.vk-menu-item-shortcut {
  margin-inline-start: auto;
  font-size: var(--vk-text-2xs);
  color: var(--vk-text-muted);
  font-family: var(--vk-font-mono);
}

.vk-menu-separator {
  block-size: var(--vk-border-width);
  background: var(--vk-border-subtle);
  margin: var(--vk-space-1) 0;
  border: 0;
}

.vk-menu-label {
  padding: var(--vk-space-2) var(--vk-space-3) var(--vk-space-1);
  font-size: var(--vk-text-2xs);
  font-weight: var(--vk-weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--vk-tracking-caps);
  color: var(--vk-text-muted);
}

/* On a phone a dropdown becomes a bottom sheet so it never opens off
   screen and every item clears the touch floor. */
@media (max-width: 639px) {
  .vk-menu-sheet {
    position: fixed;
    inset: auto 0 0 0;
    inline-size: 100vw;
    max-block-size: 70vh;
    border-radius: var(--vk-radius-lg) var(--vk-radius-lg) 0 0;
    border-inline: 0;
    border-block-end: 0;
    padding: var(--vk-space-2);
    padding-block-end: calc(var(--vk-space-2) + env(safe-area-inset-bottom, 0px));
    box-shadow: var(--vk-elevation-modal);
  }
  .vk-menu-sheet .vk-menu-item {
    min-block-size: var(--vk-touch-target-min);
  }
}

/* -------------------------------------------------------- COMMAND PALETTE
   Global navigation and search. Primary navigation on Super Admin mobile
   and a power-user accelerator everywhere else. */

.vk-command {
  padding: 0;
  border: var(--vk-border-width) solid var(--vk-border-default);
  border-radius: var(--vk-radius-lg);
  background: var(--vk-surface-overlay);
  box-shadow: var(--vk-elevation-modal);
  inline-size: min(620px, calc(100vw - var(--vk-space-6)));
  max-block-size: 70vh;
  margin-block-start: 12vh;
  overflow: hidden;
}
.vk-command::backdrop {
  background: var(--vk-surface-scrim);
  backdrop-filter: blur(2px);
}

.vk-command-inner {
  display: flex;
  flex-direction: column;
  max-block-size: inherit;
}

.vk-command-search {
  display: flex;
  align-items: center;
  gap: var(--vk-space-3);
  padding: var(--vk-space-4) var(--vk-space-5);
  border-block-end: var(--vk-border-width) solid var(--vk-border-subtle);
}

.vk-command-input {
  flex: 1;
  border: 0;
  background: none;
  font-family: inherit;
  font-size: var(--vk-text-base);
  color: var(--vk-text-primary);
  min-inline-size: 0;
}
.vk-command-input:focus {
  outline: none;
}
.vk-command-input::placeholder {
  color: var(--vk-text-disabled);
}

.vk-command-list {
  overflow-y: auto;
  padding: var(--vk-space-2);
  margin: 0;
  list-style: none;
  flex: 1;
}

.vk-command-item {
  display: flex;
  align-items: center;
  gap: var(--vk-space-3);
  inline-size: 100%;
  padding: var(--vk-space-3);
  border: 0;
  border-radius: var(--vk-radius-sm);
  background: none;
  color: var(--vk-text-primary);
  font: inherit;
  font-size: var(--vk-text-sm);
  text-align: start;
  text-decoration: none;
  cursor: pointer;
}
.vk-command-item:hover,
.vk-command-item.is-active {
  background: var(--vk-surface-hover);
}
.vk-command-item-icon {
  flex: none;
  color: var(--vk-text-muted);
}
.vk-command-item-group {
  margin-inline-start: auto;
  font-size: var(--vk-text-xs);
  color: var(--vk-text-muted);
}

.vk-command-footer {
  display: flex;
  align-items: center;
  gap: var(--vk-space-4);
  padding: var(--vk-space-2) var(--vk-space-5);
  border-block-start: var(--vk-border-width) solid var(--vk-border-subtle);
  background: var(--vk-surface-sunken);
  font-size: var(--vk-text-2xs);
  color: var(--vk-text-muted);
}

.vk-kbd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-inline-size: 18px;
  padding: 1px 5px;
  border: var(--vk-border-width) solid var(--vk-border-default);
  border-block-end-width: 2px;
  border-radius: 4px;
  background: var(--vk-surface-raised);
  font-family: var(--vk-font-mono);
  font-size: 10px;
  color: var(--vk-text-secondary);
}

@media (max-width: 639px) {
  .vk-command {
    inline-size: 100vw;
    max-inline-size: 100vw;
    block-size: 100vh;
    max-block-size: 100vh;
    margin: 0;
    border-radius: 0;
    border: 0;
  }
  .vk-command-footer {
    display: none;
  }
}

/* --------------------------------------------------------------- POPOVER
   A small anchored surface for filters and date pickers. */

.vk-popover {
  position: absolute;
  inset-block-start: calc(100% + var(--vk-space-1));
  inset-inline-start: 0;
  z-index: var(--vk-z-dropdown);
  min-inline-size: 260px;
  padding: var(--vk-space-4);
  background: var(--vk-surface-overlay);
  border: var(--vk-border-width) solid var(--vk-border-default);
  border-radius: var(--vk-radius-md);
  box-shadow: var(--vk-elevation-dropdown);
}
.vk-popover[hidden] {
  display: none;
}

/* ==========================================================================
   VEKMOT COMPONENTS — NAVIGATION & SHELL
   --------------------------------------------------------------------------
   The application shell and everything that moves a user through it:
   sidebar, collapsible rail, topbar, mobile bottom navigation, tabs,
   segmented controls, filter bars, search and pagination.

   The shell is a CSS grid with named areas. At each breakpoint the areas
   are re-declared rather than the elements being repositioned, so the DOM
   order stays correct for keyboard and screen-reader users at every size.

   Mobile is not a shrunken desktop. Below tablet the sidebar is removed
   from the layout entirely and navigation moves to a bottom bar carrying
   the four destinations that matter on a phone, with the remainder behind
   "More".
   ========================================================================== */

/* ------------------------------------------------------------------ SHELL */

.vk-shell {
  display: grid;
  min-block-size: 100vh;
  min-block-size: 100dvh;
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr;
  grid-template-areas:
    "topbar"
    "main";
  background: var(--vk-surface-page);
}

@media (min-width: 1024px) {
  .vk-shell {
    grid-template-columns: var(--vk-sidebar-width) 1fr;
    grid-template-areas:
      "sidebar topbar"
      "sidebar main";
  }

  /* Collapsed rail for tablet landscape and for users who choose it. */
  .vk-shell[data-nav="rail"] {
    grid-template-columns: var(--vk-sidebar-rail-width) 1fr;
  }
}

.vk-shell-sidebar {
  grid-area: sidebar;
  display: none;
}
@media (min-width: 1024px) {
  .vk-shell-sidebar {
    display: flex;
  }
}

.vk-shell-topbar {
  grid-area: topbar;
}

.vk-shell-main {
  grid-area: main;
  min-inline-size: 0;
  display: flex;
  flex-direction: column;
}

/* Bottom nav is fixed, so the content needs matching bottom padding to
   avoid the last row being permanently covered. */
.vk-shell-content {
  flex: 1;
  min-inline-size: 0;
  padding: var(--vk-space-5) var(--vk-space-4);
  padding-block-end: calc(
    var(--vk-mobile-nav-height) + var(--vk-space-6) +
      env(safe-area-inset-bottom, 0px)
  );
}

@media (min-width: 768px) {
  .vk-shell-content {
    padding: var(--vk-space-6);
    padding-block-end: var(--vk-space-10);
  }
}

@media (min-width: 1536px) {
  .vk-shell-content {
    padding-inline: var(--vk-space-8);
  }
}

.vk-shell-content-inner {
  inline-size: 100%;
  max-inline-size: var(--vk-content-max-width);
  margin-inline: auto;
}

.vk-shell-content-narrow .vk-shell-content-inner {
  max-inline-size: 880px;
}

/* ---------------------------------------------------------------- SIDEBAR */

.vk-sidebar {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--vk-z-shell);
  flex-direction: column;
  block-size: 100vh;
  block-size: 100dvh;
  inline-size: 100%;
  background: var(--vk-surface-raised);
  border-inline-end: var(--vk-border-width) solid var(--vk-border-subtle);
  overflow: hidden;
}

.vk-sidebar-brand {
  display: flex;
  align-items: center;
  gap: var(--vk-space-3);
  block-size: var(--vk-topbar-height);
  padding-inline: var(--vk-space-4);
  flex: none;
  border-block-end: var(--vk-border-width) solid var(--vk-border-subtle);
  text-decoration: none;
  color: var(--vk-text-primary);
}

.vk-sidebar-brand-mark {
  flex: none;
  inline-size: 26px;
  block-size: 26px;
  object-fit: contain;
}

.vk-sidebar-brand-text {
  display: flex;
  flex-direction: column;
  min-inline-size: 0;
  line-height: var(--vk-leading-tight);
}
.vk-sidebar-brand-name {
  font-size: var(--vk-text-sm);
  font-weight: var(--vk-weight-semibold);
  letter-spacing: var(--vk-tracking-snug);
}
.vk-sidebar-brand-context {
  font-size: var(--vk-text-2xs);
  color: var(--vk-text-muted);
}

.vk-sidebar-scroll {
  flex: 1;
  overflow-y: auto;
  padding: var(--vk-space-3) var(--vk-space-2);
}

.vk-sidebar-footer {
  flex: none;
  padding: var(--vk-space-2);
  border-block-start: var(--vk-border-width) solid var(--vk-border-subtle);
}

.vk-nav-group {
  display: flex;
  flex-direction: column;
  gap: 1px;
  margin-block-end: var(--vk-space-4);
}
.vk-nav-group:last-child {
  margin-block-end: 0;
}

.vk-nav-group-label {
  padding: var(--vk-space-2) var(--vk-space-3) var(--vk-space-1);
  font-size: var(--vk-text-2xs);
  font-weight: var(--vk-weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--vk-tracking-caps);
  color: var(--vk-text-muted);
}

.vk-nav-item {
  display: flex;
  align-items: center;
  gap: var(--vk-space-3);
  padding: var(--vk-space-2) var(--vk-space-3);
  border-radius: var(--vk-radius-sm);
  color: var(--vk-text-secondary);
  font-size: var(--vk-text-sm);
  font-weight: var(--vk-weight-medium);
  text-decoration: none;
  min-block-size: 36px;
  transition: var(--vk-transition-colors);
}

.vk-nav-item:hover {
  background: var(--vk-surface-hover);
  color: var(--vk-text-primary);
}

.vk-nav-item[aria-current="page"] {
  background: var(--vk-accent-subtle);
  color: var(--vk-accent-strong);
}

.vk-nav-item-icon {
  flex: none;
  color: currentColor;
  opacity: 0.75;
}
.vk-nav-item[aria-current="page"] .vk-nav-item-icon {
  opacity: 1;
}

.vk-nav-item-label {
  min-inline-size: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.vk-nav-item-badge {
  margin-inline-start: auto;
  flex: none;
}

/* Rail mode hides labels and centres the icons. The label remains in the
   DOM as an accessible name and appears as a tooltip on hover. */
.vk-shell[data-nav="rail"] .vk-sidebar-brand-text,
.vk-shell[data-nav="rail"] .vk-nav-group-label,
.vk-shell[data-nav="rail"] .vk-nav-item-label {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.vk-shell[data-nav="rail"] .vk-nav-item,
.vk-shell[data-nav="rail"] .vk-sidebar-brand {
  justify-content: center;
  padding-inline: 0;
}

/* ----------------------------------------------------------------- TOPBAR */

.vk-topbar {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--vk-z-sticky);
  display: flex;
  align-items: center;
  gap: var(--vk-space-3);
  block-size: var(--vk-topbar-height);
  padding-inline: var(--vk-space-4);
  background: var(--vk-surface-raised);
  border-block-end: var(--vk-border-width) solid var(--vk-border-subtle);
}

@media (min-width: 768px) {
  .vk-topbar {
    padding-inline: var(--vk-space-6);
  }
}

.vk-topbar-title {
  font-size: var(--vk-text-sm);
  font-weight: var(--vk-weight-semibold);
  letter-spacing: var(--vk-tracking-snug);
  min-inline-size: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.vk-topbar-actions {
  margin-inline-start: auto;
  display: flex;
  align-items: center;
  gap: var(--vk-space-1);
}

/* Compact brand shown in the topbar only when there is no sidebar. */
.vk-topbar-brand {
  display: flex;
  align-items: center;
  gap: var(--vk-space-2);
  text-decoration: none;
  color: var(--vk-text-primary);
}
@media (min-width: 1024px) {
  .vk-topbar-brand {
    display: none;
  }
}

/* ------------------------------------------------------ SHOP / CONTEXT SWITCH
   Owners and staff routinely hold more than one shop. The current context
   must be visible at all times, not buried in a settings page. */

.vk-context-switch {
  display: flex;
  align-items: center;
  gap: var(--vk-space-2);
  padding: var(--vk-space-2) var(--vk-space-3);
  border: var(--vk-border-width) solid var(--vk-border-default);
  border-radius: var(--vk-radius-sm);
  background: var(--vk-surface-raised);
  color: var(--vk-text-primary);
  font-size: var(--vk-text-sm);
  font-weight: var(--vk-weight-medium);
  cursor: pointer;
  max-inline-size: 220px;
}
.vk-context-switch:hover {
  background: var(--vk-surface-hover);
}
.vk-context-switch-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --------------------------------------------------------- MOBILE BOTTOM NAV
   Four destinations plus More. Owner and Workforce both use
   Today / Bookings / Pay / More. */

.vk-mobile-nav {
  position: fixed;
  inset-block-end: 0;
  inset-inline: 0;
  z-index: var(--vk-z-shell);
  display: flex;
  align-items: stretch;
  block-size: var(--vk-mobile-nav-height);
  padding-block-end: env(safe-area-inset-bottom, 0px);
  background: var(--vk-surface-raised);
  border-block-start: var(--vk-border-width) solid var(--vk-border-subtle);
}

@media (min-width: 1024px) {
  .vk-mobile-nav {
    display: none;
  }
}

.vk-mobile-nav-item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-inline-size: 0;
  min-block-size: var(--vk-touch-target-min);
  padding: var(--vk-space-1);
  color: var(--vk-text-muted);
  font-size: 10px;
  font-weight: var(--vk-weight-medium);
  text-decoration: none;
  background: none;
  border: 0;
  cursor: pointer;
}

.vk-mobile-nav-item[aria-current="page"] {
  color: var(--vk-accent-strong);
}

.vk-mobile-nav-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-inline-size: 100%;
}

/* Badge on a mobile nav icon (unread, pending). */
.vk-mobile-nav-icon {
  position: relative;
}
.vk-mobile-nav-dot {
  position: absolute;
  inset-block-start: -2px;
  inset-inline-end: -3px;
  inline-size: 6px;
  block-size: 6px;
  border-radius: var(--vk-radius-full);
  background: var(--vk-danger-solid);
}

/* -------------------------------------------------------------------- TABS */

.vk-tabs {
  display: flex;
  align-items: center;
  gap: var(--vk-space-1);
  border-block-end: var(--vk-border-width) solid var(--vk-border-subtle);
  overflow-x: auto;
  scrollbar-width: none;
}
.vk-tabs::-webkit-scrollbar {
  display: none;
}

.vk-tab {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--vk-space-2);
  padding: var(--vk-space-3) var(--vk-space-3);
  border: 0;
  background: none;
  color: var(--vk-text-muted);
  font: inherit;
  font-size: var(--vk-text-sm);
  font-weight: var(--vk-weight-medium);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: var(--vk-transition-colors);
}

.vk-tab:hover {
  color: var(--vk-text-primary);
}

.vk-tab[aria-selected="true"],
.vk-tab[aria-current="page"] {
  color: var(--vk-text-primary);
}

.vk-tab[aria-selected="true"]::after,
.vk-tab[aria-current="page"]::after {
  content: "";
  position: absolute;
  inset-block-end: -1px;
  inset-inline: var(--vk-space-2);
  block-size: 2px;
  background: var(--vk-accent-strong);
  border-radius: var(--vk-radius-full);
}

/* ---------------------------------------------------- SEGMENTED CONTROL
   Mutually exclusive view switch: day/week/month, all/pending/paid. */

.vk-segmented {
  display: inline-flex;
  padding: 2px;
  background: var(--vk-surface-sunken);
  border-radius: var(--vk-radius-sm);
  gap: 2px;
}

.vk-segmented-item {
  display: inline-flex;
  align-items: center;
  gap: var(--vk-space-1);
  padding: var(--vk-space-1) var(--vk-space-3);
  min-block-size: 28px;
  border: 0;
  border-radius: 4px;
  background: none;
  color: var(--vk-text-muted);
  font: inherit;
  font-size: var(--vk-text-xs);
  font-weight: var(--vk-weight-medium);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.vk-segmented-item[aria-pressed="true"],
.vk-segmented-item[aria-current="true"],
.vk-segmented-item.is-active {
  background: var(--vk-surface-raised);
  color: var(--vk-text-primary);
  box-shadow: var(--vk-shadow-xs);
}

@media (pointer: coarse) {
  .vk-segmented-item {
    min-block-size: 38px;
  }
}

/* -------------------------------------------------------------- TOOLBAR
   The filter/search row above a table or list. */

.vk-toolbar {
  display: flex;
  align-items: center;
  gap: var(--vk-space-2);
  flex-wrap: wrap;
  padding-block-end: var(--vk-space-4);
}

.vk-toolbar-end {
  margin-inline-start: auto;
  display: flex;
  align-items: center;
  gap: var(--vk-space-2);
}

.vk-search {
  position: relative;
  display: flex;
  align-items: center;
  flex: 1;
  min-inline-size: 180px;
  max-inline-size: 340px;
}
.vk-search .vk-input {
  padding-inline-start: var(--vk-space-10);
}
.vk-search-icon {
  position: absolute;
  inset-inline-start: var(--vk-space-3);
  color: var(--vk-text-muted);
  pointer-events: none;
  display: flex;
}

/* An applied filter, removable. */
.vk-filter-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--vk-space-1);
  padding: var(--vk-space-1) var(--vk-space-2);
  background: var(--vk-accent-subtle);
  border: var(--vk-border-width) solid var(--vk-accent-muted);
  border-radius: var(--vk-radius-full);
  color: var(--vk-accent-strong);
  font-size: var(--vk-text-xs);
  font-weight: var(--vk-weight-medium);
}
.vk-filter-chip-remove {
  display: flex;
  border: 0;
  background: none;
  padding: 0;
  color: inherit;
  cursor: pointer;
  opacity: 0.7;
}
.vk-filter-chip-remove:hover {
  opacity: 1;
}

/* ---------------------------------------------------------- PAGINATION */

.vk-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--vk-space-4);
  padding-block-start: var(--vk-space-4);
  flex-wrap: wrap;
}

.vk-pagination-summary {
  font-size: var(--vk-text-xs);
  color: var(--vk-text-muted);
  font-variant-numeric: tabular-nums;
}

.vk-pagination-controls {
  display: flex;
  align-items: center;
  gap: var(--vk-space-1);
}

.vk-pagination-page {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-inline-size: var(--vk-control-height-sm);
  block-size: var(--vk-control-height-sm);
  padding-inline: var(--vk-space-2);
  border: var(--vk-border-width) solid transparent;
  border-radius: var(--vk-radius-sm);
  color: var(--vk-text-secondary);
  font-size: var(--vk-text-xs);
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  cursor: pointer;
  background: none;
}
.vk-pagination-page:hover {
  background: var(--vk-surface-hover);
  color: var(--vk-text-primary);
}
.vk-pagination-page[aria-current="page"] {
  background: var(--vk-accent-subtle);
  border-color: var(--vk-accent-muted);
  color: var(--vk-accent-strong);
  font-weight: var(--vk-weight-medium);
}
.vk-pagination-page[aria-disabled="true"] {
  color: var(--vk-text-disabled);
  pointer-events: none;
}

@media (pointer: coarse) {
  .vk-pagination-page {
    min-inline-size: var(--vk-touch-target-min);
    block-size: var(--vk-touch-target-min);
  }
}

/* --------------------------------------------------------- SIDEBAR SHEET
   The full navigation on a phone, opened from "More" in the bottom bar. */

.vk-nav-sheet {
  padding: 0;
  border: 0;
  background: var(--vk-surface-overlay);
  color: var(--vk-text-primary);
  inline-size: 100vw;
  max-inline-size: 100vw;
  max-block-size: 88vh;
  margin: auto 0 0;
  border-radius: var(--vk-radius-lg) var(--vk-radius-lg) 0 0;
  box-shadow: var(--vk-elevation-modal);
}
.vk-nav-sheet::backdrop {
  background: var(--vk-surface-scrim);
}
.vk-nav-sheet[open] {
  animation: vk-sheet-in var(--vk-duration-base) var(--vk-ease-out);
}
.vk-nav-sheet-inner {
  padding: var(--vk-space-4);
  padding-block-end: calc(var(--vk-space-6) + env(safe-area-inset-bottom, 0px));
  overflow-y: auto;
  max-block-size: 88vh;
}
.vk-nav-sheet .vk-nav-item {
  min-block-size: var(--vk-touch-target-min);
}

/* A drag handle affordance at the top of any sheet. */
.vk-sheet-handle {
  inline-size: 36px;
  block-size: 4px;
  border-radius: var(--vk-radius-full);
  background: var(--vk-border-strong);
  margin: var(--vk-space-2) auto var(--vk-space-3);
}

/* ==========================================================================
   VEKMOT COMPONENTS — DOMAIN
   --------------------------------------------------------------------------
   Components that only make sense inside this product: booking records,
   payment state, terminal state, cash confirmation, receipts, VEKRYN
   evidence, chat and system telemetry.

   The payment components carry a hard product rule: a success appearance
   is reserved for the approved state, which only the backend may set.
   Nothing here may render as success while a payment is pending or
   awaiting a terminal, because the visual is the confirmation a cashier
   acts on.
   ========================================================================== */

/* ---------------------------------------------------------- BOOKING CARD */

.vk-booking {
  display: flex;
  align-items: stretch;
  gap: var(--vk-space-3);
  padding: var(--vk-space-3) var(--vk-space-4);
  background: var(--vk-surface-raised);
  border: var(--vk-border-width) solid var(--vk-border-subtle);
  border-radius: var(--vk-radius-md);
  text-decoration: none;
  color: inherit;
  inline-size: 100%;
  text-align: start;
  cursor: pointer;
  transition: var(--vk-transition-colors);
}
.vk-booking:hover {
  border-color: var(--vk-border-strong);
  background: var(--vk-surface-hover);
}

/* A coloured spine encodes state without tinting the whole card. */
.vk-booking-spine {
  flex: none;
  inline-size: 3px;
  border-radius: var(--vk-radius-full);
  background: var(--vk-neutral-solid);
}
.vk-booking-confirmed .vk-booking-spine {
  background: var(--vk-info-solid);
}
.vk-booking-completed .vk-booking-spine {
  background: var(--vk-success-solid);
}
.vk-booking-cancelled .vk-booking-spine {
  background: var(--vk-danger-solid);
}
.vk-booking-noshow .vk-booking-spine {
  background: var(--vk-warning-solid);
}

.vk-booking-time {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-inline-size: 56px;
  font-variant-numeric: tabular-nums;
  direction: ltr;
}
.vk-booking-time-start {
  font-size: var(--vk-text-sm);
  font-weight: var(--vk-weight-semibold);
  letter-spacing: var(--vk-tracking-snug);
}
.vk-booking-time-duration {
  font-size: var(--vk-text-2xs);
  color: var(--vk-text-muted);
}

.vk-booking-body {
  flex: 1;
  min-inline-size: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  justify-content: center;
}
.vk-booking-customer {
  font-size: var(--vk-text-sm);
  font-weight: var(--vk-weight-medium);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vk-booking-service {
  font-size: var(--vk-text-xs);
  color: var(--vk-text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vk-booking-meta {
  display: flex;
  align-items: center;
  gap: var(--vk-space-2);
  flex-wrap: wrap;
  margin-block-start: var(--vk-space-1);
}

.vk-booking-end {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  gap: var(--vk-space-1);
}

.vk-booking-cancelled .vk-booking-customer,
.vk-booking-cancelled .vk-booking-time-start {
  text-decoration: line-through;
  color: var(--vk-text-muted);
}

/* ------------------------------------------------------------- CALENDAR */

.vk-calendar {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 1px;
  background: var(--vk-border-subtle);
  border: var(--vk-border-width) solid var(--vk-border-subtle);
  border-radius: var(--vk-radius-md);
  overflow: hidden;
}

.vk-calendar-weekday {
  padding: var(--vk-space-2);
  background: var(--vk-surface-sunken);
  text-align: center;
  font-size: var(--vk-text-2xs);
  font-weight: var(--vk-weight-medium);
  color: var(--vk-text-muted);
  text-transform: uppercase;
  letter-spacing: var(--vk-tracking-caps);
}

.vk-calendar-day {
  position: relative;
  min-block-size: 84px;
  padding: var(--vk-space-2);
  background: var(--vk-surface-raised);
  border: 0;
  text-align: start;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: var(--vk-space-1);
}
.vk-calendar-day:hover {
  background: var(--vk-surface-hover);
}
.vk-calendar-day-outside {
  background: var(--vk-surface-sunken);
  color: var(--vk-text-disabled);
}
.vk-calendar-day-number {
  font-size: var(--vk-text-xs);
  font-variant-numeric: tabular-nums;
  color: var(--vk-text-secondary);
}
.vk-calendar-day-today .vk-calendar-day-number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 20px;
  block-size: 20px;
  border-radius: var(--vk-radius-full);
  background: var(--vk-accent-strong);
  color: var(--vk-accent-on);
  font-weight: var(--vk-weight-semibold);
}
.vk-calendar-day[aria-pressed="true"] {
  background: var(--vk-accent-subtle);
}
.vk-calendar-day-count {
  font-size: var(--vk-text-2xs);
  color: var(--vk-text-muted);
}

@media (max-width: 639px) {
  .vk-calendar-day {
    min-block-size: 52px;
    align-items: center;
    justify-content: center;
  }
}

/* A grid of bookable time slots. */
.vk-slots {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
  gap: var(--vk-space-2);
}

.vk-slot {
  display: flex;
  align-items: center;
  justify-content: center;
  min-block-size: var(--vk-touch-target-min);
  padding: var(--vk-space-2);
  background: var(--vk-surface-raised);
  border: var(--vk-border-width) solid var(--vk-border-default);
  border-radius: var(--vk-radius-sm);
  font-size: var(--vk-text-sm);
  font-variant-numeric: tabular-nums;
  direction: ltr;
  color: var(--vk-text-primary);
  cursor: pointer;
  transition: var(--vk-transition-colors);
}
.vk-slot:hover:not(:disabled) {
  border-color: var(--vk-accent-strong);
  background: var(--vk-accent-subtle);
}
.vk-slot[aria-pressed="true"] {
  background: var(--vk-accent-strong);
  border-color: var(--vk-accent-strong);
  color: var(--vk-accent-on);
  font-weight: var(--vk-weight-medium);
}
.vk-slot:disabled {
  background: var(--vk-surface-disabled);
  color: var(--vk-text-disabled);
  cursor: not-allowed;
  text-decoration: line-through;
}

/* ---------------------------------------------------------- PAYMENT STATE
   One class per backend state. The names match the payment state machine
   exactly so a template can interpolate the state without translation. */

.vk-payment-state {
  display: inline-flex;
  align-items: center;
  gap: var(--vk-space-2);
  padding: var(--vk-space-1) var(--vk-space-3);
  border: var(--vk-border-width) solid;
  border-radius: var(--vk-radius-full);
  font-size: var(--vk-text-xs);
  font-weight: var(--vk-weight-medium);
  white-space: nowrap;
}

/* Money not yet taken. Neutral: nothing has happened. */
.vk-payment-pending {
  background: var(--vk-neutral-surface);
  border-color: var(--vk-neutral-border);
  color: var(--vk-neutral-text);
}

/* Card is with the terminal. Deliberately "in progress", never success. */
.vk-payment-awaiting_terminal {
  background: var(--vk-info-surface);
  border-color: var(--vk-info-border);
  color: var(--vk-info-text);
}

/* The only state permitted to look like success. */
.vk-payment-approved {
  background: var(--vk-success-surface);
  border-color: var(--vk-success-border);
  color: var(--vk-success-text);
}

.vk-payment-declined {
  background: var(--vk-danger-surface);
  border-color: var(--vk-danger-border);
  color: var(--vk-danger-text);
}

.vk-payment-cancelled {
  background: var(--vk-neutral-surface);
  border-color: var(--vk-neutral-border);
  color: var(--vk-neutral-text);
}

.vk-payment-timeout {
  background: var(--vk-warning-surface);
  border-color: var(--vk-warning-border);
  color: var(--vk-warning-text);
}

.vk-payment-refunded,
.vk-payment-partially_refunded {
  background: var(--vk-neutral-surface);
  border-color: var(--vk-neutral-border);
  color: var(--vk-text-secondary);
}

/* ------------------------------------------------------- TERMINAL STATUS
   The full-attention surface a cashier watches while a card is presented.
   It must read from across a counter, so it is large, high contrast and
   states its own instruction. */

.vk-terminal {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--vk-space-4);
  padding: var(--vk-space-10) var(--vk-space-6);
  text-align: center;
  border: var(--vk-border-width) solid var(--vk-border-default);
  border-radius: var(--vk-radius-lg);
  background: var(--vk-surface-raised);
}

.vk-terminal-visual {
  display: flex;
  align-items: center;
  justify-content: center;
  inline-size: 72px;
  block-size: 72px;
  border-radius: var(--vk-radius-full);
  background: var(--vk-surface-sunken);
  color: var(--vk-text-muted);
}

.vk-terminal-headline {
  font-size: var(--vk-text-xl);
  font-weight: var(--vk-weight-semibold);
  letter-spacing: var(--vk-tracking-tight);
  line-height: var(--vk-leading-tight);
}

.vk-terminal-instruction {
  font-size: var(--vk-text-sm);
  color: var(--vk-text-muted);
  max-inline-size: 40ch;
  line-height: var(--vk-leading-normal);
}

.vk-terminal-amount {
  font-size: var(--vk-text-2xl);
  font-weight: var(--vk-weight-semibold);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--vk-tracking-tight);
  direction: ltr;
}

/* State treatments. Awaiting pulses the ring to show the request is live;
   approved and declined are static and final. */
.vk-terminal[data-state="awaiting_terminal"] .vk-terminal-visual {
  background: var(--vk-info-surface);
  color: var(--vk-info-text);
  box-shadow: 0 0 0 0 var(--vk-info-solid);
  animation: vk-terminal-ring 1.8s var(--vk-ease-standard) infinite;
}
@keyframes vk-terminal-ring {
  0% {
    box-shadow: 0 0 0 0 color-mix(in oklch, var(--vk-info-solid) 45%, transparent);
  }
  70% {
    box-shadow: 0 0 0 14px transparent;
  }
  100% {
    box-shadow: 0 0 0 0 transparent;
  }
}
@media (prefers-reduced-motion: reduce) {
  .vk-terminal[data-state="awaiting_terminal"] .vk-terminal-visual {
    animation: none;
  }
}

.vk-terminal[data-state="approved"] .vk-terminal-visual {
  background: var(--vk-success-surface);
  color: var(--vk-success-text);
}
.vk-terminal[data-state="declined"] .vk-terminal-visual {
  background: var(--vk-danger-surface);
  color: var(--vk-danger-text);
}
.vk-terminal[data-state="timeout"] .vk-terminal-visual,
.vk-terminal[data-state="cancelled"] .vk-terminal-visual {
  background: var(--vk-warning-surface);
  color: var(--vk-warning-text);
}

.vk-terminal-actions {
  display: flex;
  gap: var(--vk-space-2);
  flex-wrap: wrap;
  justify-content: center;
  inline-size: 100%;
}
@media (max-width: 639px) {
  .vk-terminal-actions {
    flex-direction: column-reverse;
  }
  .vk-terminal-actions .vk-btn {
    inline-size: 100%;
  }
}

/* The ordered state trail, so an operator can see where the payment is
   in the machine rather than only its current label. */
.vk-terminal-trail {
  display: flex;
  align-items: center;
  gap: var(--vk-space-2);
  font-size: var(--vk-text-2xs);
  color: var(--vk-text-muted);
  flex-wrap: wrap;
  justify-content: center;
}
.vk-terminal-trail-step {
  display: inline-flex;
  align-items: center;
  gap: var(--vk-space-1);
}
.vk-terminal-trail-step.is-done {
  color: var(--vk-text-secondary);
}
.vk-terminal-trail-step.is-current {
  color: var(--vk-text-primary);
  font-weight: var(--vk-weight-medium);
}

/* --------------------------------------------------------- CASH PAYMENT
   Cash is a physical, human interaction, not a request to a device. It
   gets an arithmetic surface — tendered, change — rather than a wait
   state, which is why it must not reuse the terminal component. */

.vk-cash {
  display: flex;
  flex-direction: column;
  gap: var(--vk-space-5);
}

.vk-cash-due {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--vk-space-1);
  padding: var(--vk-space-6);
  background: var(--vk-surface-sunken);
  border-radius: var(--vk-radius-md);
}
.vk-cash-due-amount {
  font-size: var(--vk-text-2xl);
  font-weight: var(--vk-weight-semibold);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--vk-tracking-tight);
  direction: ltr;
}

.vk-cash-quick {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
  gap: var(--vk-space-2);
}
.vk-cash-quick-btn {
  min-block-size: var(--vk-touch-target-min);
  font-variant-numeric: tabular-nums;
  direction: ltr;
}

.vk-cash-change {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--vk-space-4);
  padding: var(--vk-space-4);
  border: var(--vk-border-width) solid var(--vk-accent-muted);
  background: var(--vk-accent-subtle);
  border-radius: var(--vk-radius-md);
}
.vk-cash-change-value {
  font-size: var(--vk-text-xl);
  font-weight: var(--vk-weight-semibold);
  font-variant-numeric: tabular-nums;
  direction: ltr;
}
.vk-cash-change-short {
  border-color: var(--vk-danger-border);
  background: var(--vk-danger-surface);
  color: var(--vk-danger-text);
}

/* ------------------------------------------------------- CHECKOUT SUMMARY */

.vk-checkout {
  display: flex;
  flex-direction: column;
  gap: var(--vk-space-4);
}

.vk-checkout-line {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--vk-space-4);
  font-size: var(--vk-text-sm);
}
.vk-checkout-line-label {
  color: var(--vk-text-secondary);
  min-inline-size: 0;
}
.vk-checkout-line-value {
  font-variant-numeric: tabular-nums;
  direction: ltr;
  white-space: nowrap;
}

.vk-checkout-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--vk-space-4);
  padding-block-start: var(--vk-space-4);
  border-block-start: var(--vk-border-width) solid var(--vk-border-default);
}
.vk-checkout-total-label {
  font-size: var(--vk-text-sm);
  font-weight: var(--vk-weight-medium);
}
.vk-checkout-total-value {
  font-size: var(--vk-text-xl);
  font-weight: var(--vk-weight-semibold);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--vk-tracking-tight);
  direction: ltr;
}

/* Amount locked notice — the backend fixes the amount once a payment
   intent exists, and the UI must show that it cannot be edited. */
.vk-amount-locked {
  display: inline-flex;
  align-items: center;
  gap: var(--vk-space-1);
  font-size: var(--vk-text-2xs);
  color: var(--vk-text-muted);
}

/* ---------------------------------------------------------------- RECEIPT */

.vk-receipt {
  inline-size: 100%;
  max-inline-size: 380px;
  margin-inline: auto;
  padding: var(--vk-space-6);
  background: var(--vk-surface-raised);
  border: var(--vk-border-width) solid var(--vk-border-subtle);
  border-radius: var(--vk-radius-md);
}
.vk-receipt-head {
  text-align: center;
  padding-block-end: var(--vk-space-4);
  border-block-end: 1px dashed var(--vk-border-default);
}
.vk-receipt-lines {
  padding-block: var(--vk-space-4);
  display: flex;
  flex-direction: column;
  gap: var(--vk-space-2);
}
.vk-receipt-foot {
  padding-block-start: var(--vk-space-4);
  border-block-start: 1px dashed var(--vk-border-default);
  text-align: center;
}
.vk-receipt-code {
  font-family: var(--vk-font-mono);
  font-size: var(--vk-text-sm);
  letter-spacing: var(--vk-tracking-wide);
  direction: ltr;
  word-break: break-all;
}

@media print {
  .vk-receipt {
    border: 0;
    max-inline-size: none;
  }
  .vk-shell-sidebar,
  .vk-topbar,
  .vk-mobile-nav,
  .vk-no-print {
    display: none !important;
  }
}

/* -------------------------------------------------------------- TICKET
   The customer's booking confirmation. Deliberately card-like and
   screenshot-friendly, since that is how customers actually keep it. */

.vk-ticket {
  position: relative;
  inline-size: 100%;
  background: var(--vk-surface-raised);
  border: var(--vk-border-width) solid var(--vk-border-subtle);
  border-radius: var(--vk-radius-lg);
  overflow: hidden;
}
.vk-ticket-head {
  padding: var(--vk-space-6);
  background: var(--vk-accent-strong);
  color: var(--vk-accent-on);
}
.vk-ticket-body {
  padding: var(--vk-space-6);
}
.vk-ticket-perforation {
  position: relative;
  block-size: var(--vk-space-4);
  border-block-start: 1px dashed var(--vk-border-default);
}
.vk-ticket-perforation::before,
.vk-ticket-perforation::after {
  content: "";
  position: absolute;
  inset-block-start: calc(var(--vk-space-4) / -2);
  inline-size: var(--vk-space-4);
  block-size: var(--vk-space-4);
  border-radius: var(--vk-radius-full);
  background: var(--vk-surface-page);
}
.vk-ticket-perforation::before {
  inset-inline-start: calc(var(--vk-space-4) / -2);
}
.vk-ticket-perforation::after {
  inset-inline-end: calc(var(--vk-space-4) / -2);
}
.vk-ticket-code {
  font-family: var(--vk-font-mono);
  font-size: var(--vk-text-lg);
  font-weight: var(--vk-weight-semibold);
  letter-spacing: var(--vk-tracking-wide);
  direction: ltr;
}

/* -------------------------------------------------- VEKRYN EVIDENCE BLOCK
   VEKRYN answers must be traceable. An evidence block is the structural
   commitment that every claim carries its source, which is what separates
   this from a chatbot. */

.vk-evidence {
  display: flex;
  flex-direction: column;
  gap: var(--vk-space-3);
  padding: var(--vk-space-4);
  background: var(--vk-surface-raised);
  border: var(--vk-border-width) solid var(--vk-border-subtle);
  border-inline-start: 3px solid var(--vk-zone-secondary, var(--vk-cyan-600));
  border-radius: var(--vk-radius-md);
}

.vk-evidence-head {
  display: flex;
  align-items: center;
  gap: var(--vk-space-2);
  font-size: var(--vk-text-2xs);
  font-weight: var(--vk-weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--vk-tracking-caps);
  color: var(--vk-zone-secondary, var(--vk-cyan-700));
}

.vk-evidence-body {
  font-size: var(--vk-text-sm);
  line-height: var(--vk-leading-normal);
  color: var(--vk-text-secondary);
}

.vk-evidence-sources {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vk-space-2);
}

.vk-evidence-source {
  display: inline-flex;
  align-items: center;
  gap: var(--vk-space-1);
  padding: 2px var(--vk-space-2);
  background: var(--vk-surface-sunken);
  border: var(--vk-border-width) solid var(--vk-border-subtle);
  border-radius: var(--vk-radius-sm);
  font-size: var(--vk-text-2xs);
  color: var(--vk-text-secondary);
  font-family: var(--vk-font-mono);
}

/* Evidence strength. Shown as a labelled bar, never a bare percentage,
   because a number implies a precision the analysis may not have. */
.vk-evidence-strength {
  display: flex;
  align-items: center;
  gap: var(--vk-space-2);
  font-size: var(--vk-text-2xs);
  color: var(--vk-text-muted);
}
.vk-evidence-bars {
  display: flex;
  gap: 2px;
}
.vk-evidence-bar {
  inline-size: 14px;
  block-size: 4px;
  border-radius: var(--vk-radius-full);
  background: var(--vk-border-default);
}
.vk-evidence-bar.is-on {
  background: var(--vk-zone-secondary, var(--vk-cyan-600));
}

/* Insufficient evidence — a first-class VEKRYN outcome, not an error. */
.vk-evidence-insufficient {
  border-inline-start-color: var(--vk-warning-solid);
}
.vk-evidence-insufficient .vk-evidence-head {
  color: var(--vk-warning-text);
}

/* --------------------------------------------------------------- ANALYSIS */

.vk-analysis {
  display: flex;
  flex-direction: column;
  gap: var(--vk-space-4);
}
.vk-analysis-claim {
  font-size: var(--vk-text-base);
  line-height: var(--vk-leading-relaxed);
  color: var(--vk-text-primary);
}
.vk-analysis-meta {
  display: flex;
  align-items: center;
  gap: var(--vk-space-3);
  flex-wrap: wrap;
  font-size: var(--vk-text-2xs);
  color: var(--vk-text-muted);
}

/* ------------------------------------------------------------------ CHAT */

.vk-chat {
  display: flex;
  flex-direction: column;
  block-size: 100%;
  min-block-size: 0;
}

.vk-chat-log {
  flex: 1;
  overflow-y: auto;
  padding: var(--vk-space-5);
  display: flex;
  flex-direction: column;
  gap: var(--vk-space-5);
}

.vk-message {
  display: flex;
  gap: var(--vk-space-3);
  max-inline-size: 100%;
}

.vk-message-avatar {
  flex: none;
}

.vk-message-body {
  display: flex;
  flex-direction: column;
  gap: var(--vk-space-2);
  min-inline-size: 0;
}

.vk-message-text {
  font-size: var(--vk-text-sm);
  line-height: var(--vk-leading-relaxed);
  color: var(--vk-text-primary);
  overflow-wrap: anywhere;
}

.vk-message-meta {
  font-size: var(--vk-text-2xs);
  color: var(--vk-text-muted);
}

/* The operator's own message sits in a bubble aligned to the inline end;
   the assistant's is flush, which keeps long analytical answers readable. */
.vk-message-user {
  flex-direction: row-reverse;
}
.vk-message-user .vk-message-body {
  align-items: flex-end;
}
.vk-message-user .vk-message-text {
  padding: var(--vk-space-3) var(--vk-space-4);
  background: var(--vk-accent-subtle);
  border-radius: var(--vk-radius-md);
  max-inline-size: 44ch;
}

.vk-message-assistant .vk-message-avatar {
  color: var(--vk-accent-strong);
}

/* Thinking indicator. */
.vk-message-thinking {
  display: inline-flex;
  gap: 3px;
  align-items: center;
  padding-block: var(--vk-space-2);
}
.vk-message-thinking span {
  inline-size: 5px;
  block-size: 5px;
  border-radius: var(--vk-radius-full);
  background: var(--vk-text-disabled);
  animation: vk-thinking 1.2s var(--vk-ease-standard) infinite;
}
.vk-message-thinking span:nth-child(2) {
  animation-delay: 160ms;
}
.vk-message-thinking span:nth-child(3) {
  animation-delay: 320ms;
}
@keyframes vk-thinking {
  0%,
  60%,
  100% {
    opacity: 0.3;
    transform: translateY(0);
  }
  30% {
    opacity: 1;
    transform: translateY(-3px);
  }
}
@media (prefers-reduced-motion: reduce) {
  .vk-message-thinking span {
    animation: none;
  }
}

.vk-chat-composer {
  flex: none;
  display: flex;
  align-items: flex-end;
  gap: var(--vk-space-2);
  padding: var(--vk-space-4);
  border-block-start: var(--vk-border-width) solid var(--vk-border-subtle);
  background: var(--vk-surface-raised);
  padding-block-end: calc(var(--vk-space-4) + env(safe-area-inset-bottom, 0px));
}

.vk-chat-composer .vk-textarea {
  min-block-size: var(--vk-control-height-md);
  max-block-size: 160px;
  resize: none;
}

/* Suggested prompts shown on an empty conversation. */
.vk-chat-suggestions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vk-space-2);
  justify-content: center;
}
.vk-chat-suggestion {
  padding: var(--vk-space-2) var(--vk-space-3);
  background: var(--vk-surface-raised);
  border: var(--vk-border-width) solid var(--vk-border-default);
  border-radius: var(--vk-radius-full);
  font-size: var(--vk-text-xs);
  color: var(--vk-text-secondary);
  cursor: pointer;
}
.vk-chat-suggestion:hover {
  border-color: var(--vk-accent-strong);
  color: var(--vk-text-primary);
}

/* The persistent dock. Native to the shell, not a floating bubble. */
.vk-chat-dock {
  position: fixed;
  inset-block-end: 0;
  inset-inline-end: var(--vk-space-6);
  z-index: var(--vk-z-dropdown);
  inline-size: 380px;
  max-inline-size: calc(100vw - var(--vk-space-8));
  block-size: 520px;
  max-block-size: calc(100vh - var(--vk-space-10));
  display: flex;
  flex-direction: column;
  background: var(--vk-surface-overlay);
  border: var(--vk-border-width) solid var(--vk-border-default);
  border-block-end: 0;
  border-radius: var(--vk-radius-lg) var(--vk-radius-lg) 0 0;
  box-shadow: var(--vk-elevation-modal);
}
.vk-chat-dock[hidden] {
  display: none;
}
@media (max-width: 767px) {
  .vk-chat-dock {
    inset-inline: 0;
    inline-size: 100vw;
    max-inline-size: 100vw;
    block-size: 100dvh;
    max-block-size: 100dvh;
    border-radius: 0;
    border: 0;
  }
}

.vk-chat-dock-header {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--vk-space-2);
  padding: var(--vk-space-3) var(--vk-space-4);
  border-block-end: var(--vk-border-width) solid var(--vk-border-subtle);
}

/* --------------------------------------------------------- SYSTEM STATUS
   Super Admin telemetry. Green is a signal here, never a fill. */

.vk-system-status {
  display: flex;
  align-items: center;
  gap: var(--vk-space-3);
  padding: var(--vk-space-3) var(--vk-space-4);
  background: var(--vk-surface-raised);
  border: var(--vk-border-width) solid var(--vk-border-subtle);
  border-radius: var(--vk-radius-md);
}

.vk-system-status-label {
  font-size: var(--vk-text-xs);
  color: var(--vk-text-muted);
}
.vk-system-status-value {
  font-size: var(--vk-text-sm);
  font-weight: var(--vk-weight-medium);
  font-variant-numeric: tabular-nums;
  margin-inline-start: auto;
}

/* A thin health bar. */
.vk-health {
  display: flex;
  gap: 2px;
  align-items: center;
}
.vk-health-tick {
  inline-size: 3px;
  block-size: 16px;
  border-radius: 1px;
  background: var(--vk-border-default);
}
.vk-health-tick.is-ok {
  background: var(--vk-green-500);
}
.vk-health-tick.is-warn {
  background: var(--vk-warning-solid);
}
.vk-health-tick.is-fail {
  background: var(--vk-danger-solid);
}

/* --------------------------------------------------------------- AUDIT */

.vk-audit-entry {
  display: flex;
  gap: var(--vk-space-3);
  padding: var(--vk-space-3) 0;
  border-block-end: var(--vk-border-width) solid var(--vk-border-subtle);
  font-size: var(--vk-text-sm);
}
.vk-audit-time {
  flex: none;
  inline-size: 120px;
  font-family: var(--vk-font-mono);
  font-size: var(--vk-text-2xs);
  color: var(--vk-text-muted);
  direction: ltr;
}
.vk-audit-body {
  min-inline-size: 0;
  flex: 1;
}
@media (max-width: 639px) {
  .vk-audit-entry {
    flex-direction: column;
    gap: var(--vk-space-1);
  }
  .vk-audit-time {
    inline-size: auto;
  }
}

/* ------------------------------------------------------------ STAT STRIP
   The row of headline numbers at the top of an operational page. */

.vk-stat-strip {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--vk-space-3);
}
@media (min-width: 768px) {
  .vk-stat-strip {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--vk-space-4);
  }
}
.vk-stat-strip > * {
  padding: var(--vk-space-4);
  background: var(--vk-surface-raised);
  border: var(--vk-border-width) solid var(--vk-border-subtle);
  border-radius: var(--vk-radius-md);
}

/* ------------------------------------------------------------ MINI CHART
   Pure CSS bars. Enough for trend at a glance; anything heavier belongs
   to a real chart in the Insights domain. */

.vk-bars {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  block-size: 48px;
}
.vk-bars-bar {
  flex: 1;
  min-inline-size: 3px;
  border-radius: 2px 2px 0 0;
  background: var(--vk-accent-muted);
  transition: background-color var(--vk-duration-fast) var(--vk-ease-standard);
}
.vk-bars-bar.is-peak {
  background: var(--vk-accent-strong);
}

.vk-sparkline {
  inline-size: 100%;
  block-size: 40px;
  display: block;
  overflow: visible;
}
.vk-sparkline path {
  fill: none;
  stroke: var(--vk-accent-strong);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.vk-sparkline .vk-sparkline-area {
  fill: var(--vk-accent-subtle);
  stroke: none;
}

/* Layout shells extracted from templates so CSP style-src-elem can be 'self'. */

.vk-customer-page {
  min-block-size: 100dvh;
  display: grid;
  grid-template-rows: auto 1fr auto;
  background: var(--vk-surface-page);
}
.vk-customer-header {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--vk-z-sticky);
  background: var(--vk-surface-raised);
  border-block-end: var(--vk-border-width) solid var(--vk-border-subtle);
}
.vk-customer-header-inner {
  display: flex;
  align-items: center;
  gap: var(--vk-space-3);
  min-block-size: var(--vk-topbar-height);
  padding-block: var(--vk-space-2);
}
.vk-customer-logo {
  inline-size: 32px;
  block-size: 32px;
  border-radius: var(--vk-radius-sm);
  object-fit: cover;
  flex: none;
}
.vk-customer-main {
  inline-size: 100%;
  max-inline-size: 560px;
  margin-inline: auto;
  padding: var(--vk-space-5) var(--vk-space-4);
  padding-block-end: var(--vk-space-16);
}
@media (min-width: 640px) {
  .vk-customer-main { padding: var(--vk-space-8) var(--vk-space-5) var(--vk-space-12); }
}
.vk-customer-actionbar {
  position: sticky;
  inset-block-end: 0;
  z-index: var(--vk-z-sticky);
  display: flex;
  gap: var(--vk-space-2);
  padding: var(--vk-space-3) var(--vk-space-4);
  padding-block-end: calc(var(--vk-space-3) + env(safe-area-inset-bottom, 0px));
  background: var(--vk-surface-raised);
  border-block-start: var(--vk-border-width) solid var(--vk-border-subtle);
  margin-block-start: var(--vk-space-6);
}
.vk-customer-actionbar .vk-btn { flex: 1; }
.vk-customer-footer {
  padding: var(--vk-space-5) var(--vk-space-4);
  text-align: center;
}
.vk-customer-steps {
  padding-block: var(--vk-space-3);
  border-block-start: var(--vk-border-width) solid var(--vk-border-subtle);
}
.vk-customer-narrow { max-inline-size: 560px; }
.vk-min-0 { min-inline-size: 0; }

.vk-public-page {
  min-block-size: 100dvh;
  display: grid;
  grid-template-rows: auto 1fr auto;
  background: var(--vk-surface-page);
}
.vk-public-header {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--vk-z-sticky);
  background: var(--vk-surface-raised);
  border-block-end: var(--vk-border-width) solid var(--vk-border-subtle);
}
.vk-public-header-inner {
  display: flex;
  align-items: center;
  gap: var(--vk-space-4);
  block-size: var(--vk-topbar-height);
}
.vk-public-links {
  display: none;
  align-items: center;
  gap: var(--vk-space-1);
}
@media (min-width: 768px) {
  .vk-public-links { display: flex; }
}
.vk-public-link {
  padding: var(--vk-space-2) var(--vk-space-3);
  border-radius: var(--vk-radius-sm);
  color: var(--vk-text-secondary);
  font-size: var(--vk-text-sm);
  font-weight: var(--vk-weight-medium);
  text-decoration: none;
}
.vk-public-link:hover { background: var(--vk-surface-hover); color: var(--vk-text-primary); }
.vk-public-link[aria-current="page"] { color: var(--vk-text-primary); }
.vk-public-main { padding-block: var(--vk-space-10); }
@media (min-width: 1024px) {
  .vk-public-main { padding-block: var(--vk-space-16); }
}
.vk-public-page .vk-title-hero {
  font-size: clamp(2rem, 1.4rem + 3vw, 3.5rem);
  line-height: var(--vk-leading-tight);
  font-weight: var(--vk-weight-semibold);
  letter-spacing: var(--vk-tracking-tight);
  text-wrap: balance;
}
.vk-public-page .vk-lead {
  font-size: clamp(1rem, 0.94rem + 0.3vw, 1.25rem);
  line-height: var(--vk-leading-relaxed);
  color: var(--vk-text-secondary);
  text-wrap: pretty;
}
.vk-public-footer {
  border-block-start: var(--vk-border-width) solid var(--vk-border-subtle);
  background: var(--vk-surface-raised);
  padding-block: var(--vk-space-8);
}
.vk-footer-cols {
  display: grid;
  gap: var(--vk-space-6);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 768px) {
  .vk-footer-cols { grid-template-columns: 2fr repeat(3, minmax(0, 1fr)); }
}
.vk-brand-link {
  text-decoration: none;
  color: var(--vk-text-primary);
}
.vk-measure-32 { max-inline-size: 32ch; }
.vk-measure-46 { max-inline-size: 46ch; }
.vk-measure-48 { max-inline-size: 48ch; }
.vk-footer-rule { margin-block: var(--vk-space-6); }
.vk-error-hero {
  min-block-size: 46vh;
  text-align: center;
}
.vk-error-stack { align-items: center; }
.vk-error-actions { justify-content: center; }

.vk-auth-page {
  min-block-size: 100dvh;
  display: grid;
  grid-template-rows: auto 1fr auto;
  background: var(--vk-surface-page);
}
.vk-auth-topbar {
  display: flex;
  align-items: center;
  gap: var(--vk-space-3);
  padding: var(--vk-space-4) var(--vk-space-5);
}
.vk-auth-main {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--vk-space-5);
}
.vk-auth-card {
  inline-size: 100%;
  max-inline-size: var(--vk-auth-width, 400px);
}
.vk-auth-head {
  text-align: center;
  margin-block-end: var(--vk-space-6);
}
.vk-auth-foot {
  padding: var(--vk-space-5);
  text-align: center;
}
.vk-auth-icon { margin-inline: auto; }
.vk-brand-logo { block-size: 26px; inline-size: auto; object-fit: contain; }
.vk-sidebar-brand-mark {
  block-size: 28px;
  inline-size: auto;
  max-inline-size: 40px;
  object-fit: contain;
  flex-shrink: 0;
}
.vk-topbar-brand .vk-brand-logo {
  block-size: 22px;
}
@media (max-width: 639px) {
  .vk-auth-main { padding: var(--vk-space-4); align-items: flex-start; }
  .vk-auth-card .vk-card { border: 0; background: transparent; }
  .vk-auth-card .vk-card-body { padding-inline: 0; }
}
