/* ================================================================
   B60-POS Design System -- B60 OS
   Clean indigo shell, solid white cards, lavender canvas. One token
   file drives every .ds-* class and --ds-* variable so existing
   consumer pages inherit the new look without markup churn.
   Self-hosted Plus Jakarta Sans + JetBrains Mono (offline-first, no CDN
   fonts).
   Dark mode and LUMINA/60 glass/daylight/gold doctrines are retired.
   ================================================================ */

@font-face {
    font-family: 'Geist';
    src: url('/fonts/geist-400.woff2') format('woff2');
    font-weight: 400;
    font-display: swap;
}

@font-face {
    font-family: 'Geist';
    src: url('/fonts/geist-500.woff2') format('woff2');
    font-weight: 500;
    font-display: swap;
}

@font-face {
    font-family: 'Geist';
    src: url('/fonts/geist-600.woff2') format('woff2');
    font-weight: 600;
    font-display: swap;
}

@font-face {
    font-family: 'Geist';
    src: url('/fonts/geist-700.woff2') format('woff2');
    font-weight: 700;
    font-display: swap;
}

/* The app font since 2026-10-31. Latin only: Arabic falls through the stack to the system
   font, as it did under Geist. Geist stays behind it for rarer Latin letters. */
@font-face {
    font-family: 'Plus Jakarta Sans';
    src: url('/fonts/plus-jakarta-sans-wght.woff2') format('woff2');
    font-weight: 200 800;
    font-display: swap;
}

@font-face {
    font-family: 'JetBrains Mono';
    src: url('/fonts/jetbrains-mono-400.woff2') format('woff2');
    font-weight: 400;
    font-display: swap;
}

@font-face {
    font-family: 'JetBrains Mono';
    src: url('/fonts/jetbrains-mono-500.woff2') format('woff2');
    font-weight: 500;
    font-display: swap;
}

@font-face {
    font-family: 'JetBrains Mono';
    src: url('/fonts/jetbrains-mono-600.woff2') format('woff2');
    font-weight: 600;
    font-display: swap;
}

@font-face {
    font-family: 'JetBrains Mono';
    src: url('/fonts/jetbrains-mono-700.woff2') format('woff2');
    font-weight: 700;
    font-display: swap;
}

/* ================================================================
   TOKENS
   ================================================================ */

:root {
    color-scheme: light;

    /* ---- B60 OS primary palette ---- */
    --ds-primary: #4F46E5;
    --ds-primary-hover: #4338CA;
    --ds-primary-press: #3730A3;
    --ds-primary-tint: #EEF2FF;
    --ds-primary-gradient: linear-gradient(135deg, #5B21B6, #4F46E5);

    /* The till's product plate, mixed from the accent. It was a fixed lilac,
       so a green or crimson cafe still had indigo plates under every drink.
       Declared here, beside the accent theme.js writes onto <html>, so it
       resolves against the cafe's colour; 6% matches the old lilac on the
       default indigo. */
    --ds-plate: color-mix(in srgb, var(--ds-primary) 6%, #F4F4F6);
    --ds-plate-hover: color-mix(in srgb, var(--ds-primary) 10%, #F4F4F6);
    --ds-plate-in-order: color-mix(in srgb, var(--ds-primary) 14%, #FFFFFF);

    /* ---- Sidebar ---- */
    --ds-sidebar-bg: linear-gradient(180deg, #4F3BCF, #4834C4);
    --ds-sidebar-fg: rgba(255, 255, 255, 0.82);
    --ds-sidebar-fg-active: #4F46E5;
    --ds-sidebar-pill: #FFFFFF;

    /* ---- Surfaces ---- */
    --ds-canvas: #F7F7FC;
    --ds-surface: #FFFFFF;
    --ds-surface-alt: #FAFAFE;

    /* ---- Legacy gold scale (names kept, values repointed to primary) ---- */
    --ds-gold-500: var(--ds-primary);
    --ds-gold-400: var(--ds-primary);
    --ds-gold-600: var(--ds-primary-press);
    --ds-gold-tint: var(--ds-primary-tint);
    --ds-gold-tint-strong: var(--ds-primary-tint);

    /* ---- Legacy blue scale (names kept, values repointed to info) ---- */
    --ds-blue-500: #3B82F6;
    --ds-blue-400: #3B82F6;
    --ds-blue-600: #3B82F6;
    --ds-blue-tint: #EFF6FF;
    --ds-blue-tint-strong: #EFF6FF;

    /* ---- Neutral scale ---- */
    --ds-neutral-0: #FFFFFF;
    --ds-neutral-50: #F7F7FC;
    --ds-neutral-100: #FAFAFE;
    --ds-neutral-200: #EEF0F6;
    --ds-neutral-300: #E2E5EE;
    --ds-neutral-400: #9CA3AF;
    --ds-neutral-500: #6B7280;
    --ds-neutral-600: #6B7280;
    --ds-neutral-700: #1E1B39;
    --ds-neutral-800: #1E1B39;
    --ds-neutral-900: #1E1B39;
    --ds-neutral-950: #1E1B39;

    /* ---- Accent scale (legacy names, primary values) ---- */
    --ds-accent-050: var(--ds-primary-tint);
    --ds-accent-100: var(--ds-primary-tint);
    --ds-accent-400: var(--ds-primary);
    --ds-accent-500: var(--ds-primary);
    --ds-accent-600: var(--ds-primary-hover);
    --ds-accent-700: var(--ds-primary-press);

    /* ---- Semantic ---- */
    --ds-success-500: #10B981;
    --ds-success-100: #ECFDF5;
    --ds-warning-500: #F59E0B;
    --ds-warning-100: #FFFBEB;
    --ds-danger-500: #EF4444;
    --ds-danger-100: #FEF2F2;
    --ds-info-500: #3B82F6;
    --ds-info-100: #EFF6FF;

    /* ---- Daylight (names kept, static canvas) ---- */
    --ds-daylight-glow-a: transparent;
    --ds-daylight-glow-b: transparent;
    --ds-daylight-canvas-tint: transparent;

    /* ---- Glass (names kept, solid surfaces) ---- */
    --ds-glass-base: var(--ds-surface);
    --ds-glass-elevated: var(--ds-surface);
    --ds-glass-chrome: var(--ds-surface);
    --ds-glass-pressed: var(--ds-surface);
    --ds-glass-rim: 1px solid var(--ds-border);
    --ds-glass-rim-inset: none;

    /* ---- Role tokens ---- */
    --ds-bg-canvas: var(--ds-canvas);
    --ds-bg-surface: var(--ds-surface);
    --ds-bg-elevated: var(--ds-surface);
    --ds-bg-inset: var(--ds-surface-alt);
    --ds-bg-overlay: rgba(30, 27, 57, 0.40);
    --ds-bg-chrome: var(--ds-surface);

    --ds-border: #EEF0F6;
    --ds-border-strong: #E2E5EE;
    --ds-border-default: var(--ds-border);

    --ds-text-primary: #1E1B39;
    --ds-text-secondary: #6B7280;
    /* Tertiary must clear 4.5:1 on --ds-surface; distinct from disabled. */
    --ds-text-tertiary: #6B7280;
    --ds-text-on-accent: #FFFFFF;
    --ds-text-disabled: #9CA3AF;

    --ds-accent: var(--ds-primary);
    --ds-accent-hover: var(--ds-primary-hover);
    --ds-accent-tint: var(--ds-primary-tint);
    --ds-accent-tint-strong: var(--ds-primary-tint);

    --ds-success: #10B981;
    --ds-success-tint: #ECFDF5;
    --ds-warning: #F59E0B;
    --ds-warning-tint: #FFFBEB;
    --ds-danger: #EF4444;
    --ds-danger-tint: #FEF2F2;
    --ds-info: #3B82F6;
    --ds-info-tint: #EFF6FF;

    /* Status colours as TEXT. The ones above are for dots, borders and
       fills; as small text they read at 2.4-3.4:1 on their tints (and the
       green 2.5:1 on white), under the 4.5:1 WCAG AA asks for. These are
       4.8:1 or better on both the tint and white. */
    --ds-success-text: #047857;
    --ds-warning-text: #B45309;
    --ds-danger-text: #B91C1C;
    --ds-info-text: #1D4ED8;

    --ds-focus-ring: 0 0 0 3px var(--ds-primary-tint);

    /* ---- Type ---- */
    --ds-font-sans: 'Plus Jakarta Sans', 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --ds-font-mono: 'JetBrains Mono', 'SF Mono', Consolas, ui-monospace, monospace;

    /* xs floor 13px at 16px root -- product names stay readable on tablet. */
    --ds-text-xs: 0.8125rem;
    --ds-text-sm: 0.875rem;
    --ds-text-base: 0.9375rem;
    --ds-text-md: 1rem;
    --ds-text-lg: 1.25rem;
    --ds-text-xl: 1.5rem;
    --ds-text-2xl: 2rem;
    --ds-text-3xl: 2rem;

    --ds-fw-normal: 400;
    --ds-fw-medium: 500;
    --ds-fw-semibold: 600;
    --ds-fw-bold: 700;

    --ds-leading-tight: 1.2;
    --ds-leading-normal: 1.5;
    --ds-tracking-micro: 0.08em;

    /* ---- Spacing (4px grid) ---- */
    --ds-space-1: 4px;
    --ds-space-2: 8px;
    --ds-space-3: 12px;
    --ds-space-4: 16px;
    --ds-space-5: 20px;
    --ds-space-6: 24px;
    --ds-space-8: 32px;
    --ds-space-10: 40px;
    --ds-space-12: 48px;
    --ds-space-16: 64px;

    /* ---- Breakpoints (canonical contract; use literals in @media) ----
       Tablet / desktop / short-viewport rules live in this file and
       viewport-compact.css. POS copies in pos.css are deleted by T-H. */
    --bp-tablet: 1024px;
    --bp-pos: 1520px;
    --bp-desktop: 1600px;
    --bp-short: 800px;
    --bp-tight: 640px;

    /* ---- Alignment padding (shared page primitives) ---- */
    --ds-pad-page-inline: var(--ds-shell-gutter-inline, clamp(12px, 2vw, 24px));
    --ds-pad-page-block: var(--ds-shell-gutter-block, clamp(8px, 1.5vh, 24px));
    --ds-pad-card: var(--ds-space-5);
    --ds-pad-toolbar-block: var(--ds-space-4);
    --ds-pad-toolbar-inline: var(--ds-space-5);
    --ds-pad-table-cell-block: var(--ds-space-3);
    --ds-pad-table-cell-inline: var(--ds-space-4);

    /* ---- Radii ---- */
    --ds-radius-sm: 8px;
    --ds-radius-md: 12px;
    --ds-radius-lg: 16px;
    --ds-radius-xl: 20px;
    --ds-radius-pill: 999px;

    /* ---- Blur (retired, names kept) ---- */
    --ds-blur-card: 0;
    --ds-blur-panel: 0;
    --ds-blur-overlay: 0;

    /* ---- Shadows ---- */
    --ds-shadow-card: 0 1px 3px rgba(30, 27, 57, 0.04), 0 8px 24px rgba(30, 27, 57, 0.04);
    --ds-shadow-pop: 0 12px 32px rgba(30, 27, 57, 0.10);
    --ds-shadow-modal: 0 24px 64px rgba(30, 27, 57, 0.18);

    --ds-shadow-1: var(--ds-shadow-card);
    --ds-shadow-2: var(--ds-shadow-card);
    --ds-shadow-soft: var(--ds-shadow-card);
    --ds-shadow-3: var(--ds-shadow-pop);
    --ds-shadow-floating: var(--ds-shadow-pop);
    --ds-shadow-4: var(--ds-shadow-modal);

    --ds-rim-light: none;

    --ds-touch-target: 44px;
    --ds-touch-target-primary: 48px;

    /* ---- Motion (B1b — transform + opacity only in utilities) ---- */
    --ds-duration-fast: 120ms;
    --ds-duration-normal: 180ms;
    --ds-duration-mid: 240ms;
    --ds-duration-slow: 360ms;

    --ds-ease-standard: cubic-bezier(0.2, 0.8, 0.2, 1);
    --ds-ease-exit: cubic-bezier(0.4, 0, 1, 1);

    /* Legacy motion aliases */
    --ds-motion-tap: var(--ds-duration-fast);
    --ds-motion-hover: var(--ds-duration-normal);
    --ds-motion-panel: var(--ds-duration-mid);
    --ds-motion-drawer: var(--ds-duration-normal);
    --ds-motion-page: var(--ds-duration-mid);
    --ds-ease-spring: var(--ds-ease-standard);

    --ds-transition-fast: var(--ds-duration-fast) var(--ds-ease-standard);
    --ds-transition-normal: var(--ds-duration-normal) var(--ds-ease-standard);

    /* Legacy motion aliases (override components.css) */
    --ease-out: var(--ds-ease-standard);
    --ease-exit: var(--ds-ease-exit);
    --ease-spring: var(--ds-ease-standard);
    --dur-fast: var(--ds-duration-fast);
    --dur-mid: var(--ds-duration-normal);
    --transition-fast: var(--ds-transition-fast);
    --transition-normal: var(--ds-transition-normal);

    --ds-z-overlay: 200;
    --ds-z-modal: 300;
    --ds-z-toast: 400;
    --ds-z-prism: 500;
}

/* ================================================================
   BASE / RESET
   ================================================================ */

.ds-root {
    font-family: var(--ds-font-sans);
    font-size: var(--ds-text-base);
    line-height: var(--ds-leading-normal);
    color: var(--ds-text-primary);
    background: var(--ds-bg-canvas);
    -webkit-font-smoothing: antialiased;
}

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

.ds-root :focus-visible {
    outline: 2px solid var(--ds-primary);
    outline-offset: 2px;
}

.ds-tabular {
    font-variant-numeric: tabular-nums;
}

.ds-microcaps {
    text-transform: uppercase;
    letter-spacing: var(--ds-tracking-micro);
    font-size: var(--ds-text-xs);
    font-weight: var(--ds-fw-medium);
    color: var(--ds-text-tertiary);
}

.ds-sigil {
    font-family: var(--ds-font-mono);
    opacity: 0.04;
    color: var(--ds-text-primary);
    user-select: none;
    pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }

    .ds-motion-page-enter,
    .ds-motion-tab-enter,
    .ds-motion-slide-up,
    .ds-motion-slide-down,
    .ds-motion-fade,
    .ds-toast-enter,
    .ds-modal-enter,
    .ds-skeleton {
        animation: none !important;
    }
}

/* ================================================================
   Buttons
   ================================================================ */

.ds-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--ds-space-2);
    font-family: var(--ds-font-sans);
    font-weight: var(--ds-fw-medium);
    border-radius: var(--ds-radius-md);
    border: 1px solid transparent;
    cursor: pointer;
    white-space: nowrap;
    touch-action: manipulation;
    transition: transform var(--ds-duration-fast) var(--ds-ease-standard),
                opacity var(--ds-duration-fast) var(--ds-ease-standard);
    min-height: var(--ds-touch-target);
    padding-inline: var(--ds-space-4);
}

.ds-btn:disabled,
.ds-btn[aria-disabled="true"] {
    cursor: not-allowed;
    opacity: 0.5;
}

.ds-btn-sm {
    min-height: 36px;
    padding-inline: var(--ds-space-3);
    font-size: var(--ds-text-sm);
    border-radius: var(--ds-radius-sm);
}

.ds-btn-md {
    font-size: var(--ds-text-base);
}

.ds-btn-lg {
    min-height: var(--ds-touch-target-primary);
    padding-inline: var(--ds-space-6);
    font-size: var(--ds-text-lg);
    border-radius: var(--ds-radius-lg);
}

.ds-btn-primary {
    background: var(--ds-primary);
    color: var(--ds-text-on-accent);
    box-shadow: var(--ds-shadow-card);
}

:where(.can-hover) .ds-btn-primary:hover:not(:disabled) {
    background: var(--ds-primary-hover);
}

.ds-btn-primary:active:not(:disabled) {
    background: var(--ds-primary-press);
    transform: scale(0.98);
}

.ds-btn-secondary {
    background: var(--ds-surface);
    color: var(--ds-text-primary);
    border-color: var(--ds-border-strong);
    box-shadow: var(--ds-shadow-card);
}

:where(.can-hover) .ds-btn-secondary:hover:not(:disabled) {
    background: var(--ds-surface-alt);
}

.ds-btn-ghost {
    background: transparent;
    color: var(--ds-text-secondary);
}

:where(.can-hover) .ds-btn-ghost:hover:not(:disabled) {
    background: var(--ds-surface-alt);
    color: var(--ds-text-primary);
}

.ds-btn-danger {
    background: var(--ds-danger);
    color: var(--ds-text-on-accent);
}

:where(.can-hover) .ds-btn-danger:hover:not(:disabled) {
    filter: brightness(0.94);
}

/*
 * Quiet destructive -- for a delete that repeats on EVERY row of a list.
 *
 * Solid `.ds-btn-danger` is right where the destructive action is the one the
 * dialog is about (a confirm modal's Delete). It is wrong once it repeats: 48
 * products meant 48 saturated red buttons, making the most dangerous action on
 * the screen also the loudest thing on it, and drowning out the real primary
 * (Add Product). This reads as destructive on inspection and on hover, without
 * competing for the eye at rest.
 */
.ds-btn-danger-quiet {
    background: transparent;
    color: var(--ds-danger);
    border: 1px solid var(--ds-border);
}

:where(.can-hover) .ds-btn-danger-quiet:hover:not(:disabled) {
    background: var(--ds-danger);
    border-color: var(--ds-danger);
    color: var(--ds-text-on-accent);
}

.ds-btn-loading {
    position: relative;
    color: transparent !important;
    pointer-events: none;
}

.ds-btn-loading::after {
    content: "";
    position: absolute;
    inset-inline-start: 50%;
    inset-block-start: 50%;
    width: 16px;
    height: 16px;
    margin-inline-start: -8px;
    margin-block-start: -8px;
    border-radius: 50%;
    border: 2px solid currentColor;
    border-inline-end-color: transparent;
    color: inherit;
    animation: ds-spin 0.7s linear infinite;
}

.ds-btn-primary.ds-btn-loading::after,
.ds-btn-danger.ds-btn-loading::after {
    color: var(--ds-text-on-accent);
}

.ds-btn-secondary.ds-btn-loading::after,
.ds-btn-ghost.ds-btn-loading::after {
    color: var(--ds-text-primary);
}

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

/* Swipe a row for its buttons (Components.swipeActions). The buttons sit in a
   layer on <body> at the row's end and fill its height; the row slides aside,
   or with cover: true (Clients) stays put under them. */
body.is-swiping {
    user-select: none;
    -webkit-user-select: none;
}

.swipe-actions {
    position: fixed;
    z-index: var(--ds-z-overlay);
    display: flex;
    justify-content: flex-end;
    overflow: hidden;
}

.swipe-actions-row {
    flex: 0 0 auto;
    display: flex;
    height: 100%;
}

.swipe-action {
    flex: 1 1 0;
    min-width: 0;
    height: 100%;
    padding: 0 var(--ds-space-2);
    border: 0;
    color: var(--ds-text-on-accent);
    font: inherit;
    font-size: var(--ds-text-sm);
    font-weight: var(--ds-fw-semibold);
    cursor: pointer;
}

.swipe-action.is-neutral { background: var(--ds-neutral-600); }
.swipe-action.is-primary { background: var(--ds-primary); }
/* Dark red: white text on the light red read under 4.5:1. */
.swipe-action.is-danger { background: var(--ds-danger-text); }

.swipe-action:active {
    filter: brightness(0.9);
}

/* -- A quiet wave in a card's far corner (.ds-wave) -------------------------
   In the cafe's own colour (--ds-primary, set in Settings), drawn as two
   masks: soft folds that deepen toward the corner, then a light glow and thin
   sheen lines along them. Faded out before it reaches the middle; behind the
   content only; one static image, nothing moves. Mirrored in Arabic. Used on
   the open shift, the Dashboard summary and Start here. The element, or one
   around it, clips its corners. --wave-w / --wave-h size it, --wave-solid
   says how far in from the corner it stays at full strength. */
.ds-wave {
    position: relative;
    isolation: isolate;
}

.ds-wave::before,
.ds-wave::after {
    content: '';
    position: absolute;
    inset-block-start: 0;
    inset-inline-end: 0;
    inline-size: var(--wave-w, min(64%, 760px));
    block-size: var(--wave-h, 100%);
    z-index: -1;
    pointer-events: none;
    /* The picture, faded toward the content along the row and, where a card
       asks (--wave-fade-y), downward. */
    -webkit-mask:
        var(--wave-mask) no-repeat right center / cover,
        linear-gradient(to left, #000 var(--wave-solid, 40%), transparent),
        var(--wave-fade-y, linear-gradient(#000, #000));
    -webkit-mask-composite: source-in;
    mask:
        var(--wave-mask) no-repeat right center / cover,
        linear-gradient(to left, #000 var(--wave-solid, 40%), transparent),
        var(--wave-fade-y, linear-gradient(#000, #000));
    mask-composite: intersect;
}

.ds-wave::before {
    --wave-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 800 160' preserveAspectRatio='xMaxYMid slice'%3E%3Cdefs%3E%3CradialGradient id='g' cx='800' cy='0' r='620' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-opacity='.85'/%3E%3Cstop offset='.55' stop-opacity='.4'/%3E%3Cstop offset='1' stop-opacity='.08'/%3E%3C/radialGradient%3E%3Cfilter id='b' x='-10%25' y='-60%25' width='120%25' height='220%25'%3E%3CfeGaussianBlur stdDeviation='7'/%3E%3C/filter%3E%3Cfilter id='s' x='-10%25' y='-60%25' width='120%25' height='220%25'%3E%3CfeGaussianBlur stdDeviation='3.5'/%3E%3C/filter%3E%3C/defs%3E%3Crect width='800' height='160' fill='url(%23g)'/%3E%3Cg filter='url(%23b)'%3E%3Cpath d='M180 158C350 14 510 154 740 -45L740 -15C510 196 350 66 180 222Z' opacity='0.36'/%3E%3Cpath d='M285 157C455 12 615 151 845 -49L845 -23C615 187 455 56 285 211Z' opacity='0.3'/%3E%3Cpath d='M390 156C560 10 720 148 950 -53L950 -31C720 178 560 46 390 200Z' opacity='0.24'/%3E%3Cpath d='M495 155C665 8 825 145 1055 -57L1055 -39C825 169 665 36 495 189Z' opacity='0.18'/%3E%3C/g%3E%3C/svg%3E");
    background: color-mix(in srgb, var(--ds-primary) 28%, var(--ds-surface));
}

.ds-wave::after {
    --wave-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 800 160' preserveAspectRatio='xMaxYMid slice'%3E%3Cdefs%3E%3CradialGradient id='g' cx='800' cy='0' r='620' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-opacity='.85'/%3E%3Cstop offset='.55' stop-opacity='.4'/%3E%3Cstop offset='1' stop-opacity='.08'/%3E%3C/radialGradient%3E%3Cfilter id='b' x='-10%25' y='-60%25' width='120%25' height='220%25'%3E%3CfeGaussianBlur stdDeviation='7'/%3E%3C/filter%3E%3Cfilter id='s' x='-10%25' y='-60%25' width='120%25' height='220%25'%3E%3CfeGaussianBlur stdDeviation='3.5'/%3E%3C/filter%3E%3C/defs%3E%3Cg filter='url(%23s)'%3E%3Cpath d='M232 176C402 28 562 165 792 -38L792 -28C562 179 402 46 232 198Z' opacity='0.75'/%3E%3Cpath d='M338 172C508 24 668 160 898 -43L898 -34C668 172 508 39 338 190Z' opacity='0.65'/%3E%3Cpath d='M442 168C612 19 772 155 1002 -48L1002 -41C772 165 612 31 442 182Z' opacity='0.55'/%3E%3C/g%3E%3Cg fill='none' stroke='%23000' stroke-width='1.3' stroke-linecap='round'%3E%3Cpath d='M180 158C350 14 510 154 740 -45' opacity='0.8'/%3E%3Cpath d='M285 157C455 12 615 151 845 -49' opacity='0.7'/%3E%3Cpath d='M390 156C560 10 720 148 950 -53' opacity='0.6'/%3E%3Cpath d='M495 155C665 8 825 145 1055 -57' opacity='0.5'/%3E%3C/g%3E%3C/svg%3E");
    background: var(--ds-surface);
}

[dir="rtl"] .ds-wave::before,
[dir="rtl"] .ds-wave::after {
    transform: scaleX(-1);
}

/* A form field that needs fixing (Components.fieldError): marked, with the
   message right under it. */
.is-invalid,
[aria-invalid="true"] {
    border-color: var(--ds-danger) !important;
    box-shadow: 0 0 0 3px var(--ds-danger-tint) !important;
}

.field-error {
    margin: var(--ds-space-1) 0 0;
    color: var(--ds-danger-text);
    font-size: var(--ds-text-sm);
    text-align: start;
}

/*
 * Loading, for any button (Components.busy). Pressed and waiting: the label
 * steps back and a spinner turns where it was, in the label's own colour, and
 * the button keeps its size. Not the faded disabled look -- the button is
 * working, not unavailable. Kept above any page's :disabled fade.
 */
.is-busy-pending,
.is-busy {
    opacity: 1 !important;
    pointer-events: none;
}

.is-busy {
    color: transparent !important;
}

.is-busy > :not(.busy-spinner) {
    visibility: hidden;
}

.busy-spinner {
    position: absolute;
    inset: 0;
    margin: auto;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    border: 2px solid currentColor;
    border-inline-end-color: transparent;
    animation: ds-spin 0.7s linear infinite;
    pointer-events: none;
}

/*
 * Pressed. Only the primary and the checkout button used to answer a tap;
 * on Cancel, a ghost row action or a red Delete nothing moved, and a finger
 * that sees no change presses again.
 */
.ds-btn:active:not(:disabled):not([aria-disabled="true"]) {
    transform: scale(0.98);
}

.ds-btn-secondary:active:not(:disabled),
.ds-btn-ghost:active:not(:disabled) {
    background: var(--ds-neutral-200);
    color: var(--ds-text-primary);
}

.ds-btn-danger:active:not(:disabled) {
    filter: brightness(0.86);
}

.ds-btn-danger-quiet:active:not(:disabled) {
    background: var(--ds-danger);
    border-color: var(--ds-danger);
    color: var(--ds-text-on-accent);
}

/*
 * Tap areas on a touch screen (Fitts's law).
 *
 * Measured at 1520x730 with touch on: the compact controls were 32-40px, a
 * table's row checkbox 22px and the order tab's colour dot 10px. Making them
 * bigger would cost rows on a 730px screen, so an invisible ::after grows the
 * area that answers a tap to about 44px instead, and nothing on screen moves.
 * Segmented controls grow up and down only, so neighbours never overlap. The
 * colour dot sits inside the order tab, so it grows only a little: a larger
 * area would take taps meant for switching the tab. Only where a touch screen
 * is attached; a mouse needs none of it.
 */
@media (any-pointer: coarse) {
    .ds-btn-sm:not(.ds-btn-loading),
    .sync-chip,
    .top-bar-search,
    .orders-period-btn,
    .dash-seg-btn,
    .dash-card-link,
    .clients-overflow-btn,
    .orders-overflow-btn,
    .tbl-floor-tab,
    .tbl-floor-add,
    .tbl-filter-btn,
    .tbl-view-btn,
    .tbl-zoom-btn,
    .fp-zoom-btn,
    .pos-service-segment-btn,
    .pos-density-opt,
    .pos-context-btn,
    .ds-checkbox,
    .ds-radio,
    .order-tab-color-dot {
        position: relative;
    }

    .ds-btn-sm:not(.ds-btn-loading)::after,
    .sync-chip::after,
    .top-bar-search::after,
    .tbl-zoom-btn::after,
    .fp-zoom-btn::after,
    .clients-overflow-btn::after,
    .orders-overflow-btn::after,
    .pos-context-btn::after,
    .tbl-floor-tab::after,
    .tbl-floor-add::after,
    .tbl-filter-btn::after,
    .dash-card-link::after,
    .ds-checkbox::after,
    .ds-radio::after,
    .order-tab-color-dot::after,
    .orders-period-btn::after,
    .dash-seg-btn::after,
    .tbl-view-btn::after,
    .pos-service-segment-btn::after,
    .pos-density-opt::after {
        content: "";
        position: absolute;
        inset: -4px;
    }

    .clients-overflow-btn::after,
    .orders-overflow-btn::after,
    .pos-context-btn::after { inset: -2px; }
    .tbl-floor-tab::after,
    .tbl-floor-add::after,
    .tbl-filter-btn::after { inset: -5px; }
    .dash-card-link::after { inset: -6px; }
    .ds-checkbox::after,
    .ds-radio::after { inset: -11px; }
    .order-tab-color-dot::after { inset: -7px; }

    /* Segmented: up and down only. */
    .orders-period-btn::after { inset: -4px 0; }
    .dash-seg-btn::after { inset: -3px 0; }
    .tbl-view-btn::after,
    .pos-service-segment-btn::after { inset: -6px 0; }
    .pos-density-opt::after { inset: -2px 0; }
}

/* Primary gradient CTA (checkout, hero actions) */
.ds-btn-ingot {
    background: var(--ds-primary-gradient);
    color: var(--ds-text-on-accent);
    font-weight: var(--ds-fw-semibold);
    border: none;
    box-shadow: var(--ds-shadow-pop);
    min-height: var(--ds-touch-target-primary);
    padding-inline: var(--ds-space-6);
    font-size: var(--ds-text-lg);
    border-radius: var(--ds-radius-lg);
    transition: transform var(--ds-motion-tap) var(--ds-ease-standard),
                box-shadow var(--ds-motion-hover) var(--ds-ease-standard),
                filter var(--ds-motion-hover) var(--ds-ease-standard);
}

:where(.can-hover) .ds-btn-ingot:hover:not(:disabled) {
    filter: brightness(1.04);
    box-shadow: var(--ds-shadow-modal);
}

.ds-btn-ingot:active:not(:disabled) {
    transform: scale(0.98);
    filter: brightness(0.96);
}

.ds-btn-ingot .ds-ingot-total {
    font-variant-numeric: tabular-nums;
}

.ds-btn-ingot.is-success {
    background: linear-gradient(135deg, #10B981, #10B981);
    color: var(--ds-text-on-accent);
}

/* ================================================================
   Inputs
   ================================================================ */

.ds-field {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-2);
}

.ds-label {
    font-size: var(--ds-text-sm);
    font-weight: var(--ds-fw-medium);
    color: var(--ds-text-secondary);
    text-align: start;
}

.ds-input,
.ds-select {
    appearance: none;
    width: 100%;
    min-height: var(--ds-touch-target);
    padding-inline: var(--ds-space-3);
    font-family: var(--ds-font-sans);
    font-size: var(--ds-text-base);
    color: var(--ds-text-primary);
    background: var(--ds-surface);
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-md);
    text-align: start;
    transition: border-color var(--ds-motion-hover) var(--ds-ease-standard),
                box-shadow var(--ds-motion-hover) var(--ds-ease-standard);
}

/* The arrow is one 10x5 triangle. It was two 5px half-triangles side by
   side, which only met when the select's width was a whole pixel; in a
   grid cell (155.7px on a phone) they came apart into a notched arrow. */
.ds-select {
    background-image: conic-gradient(from -45deg at 50% 100%, currentColor 90deg, transparent 0);
    background-position: calc(100% - 15px) center;
    background-size: 10px 5px;
    background-repeat: no-repeat;
    color: var(--ds-text-primary);
    padding-inline-end: var(--ds-space-8);
}

[dir="rtl"] .ds-select {
    background-position: 15px center;
}

.ds-input::placeholder {
    color: var(--ds-text-tertiary);
}

.ds-input:focus,
.ds-select:focus {
    outline: none;
    border-color: var(--ds-primary);
    box-shadow: var(--ds-focus-ring);
}

.ds-input:disabled,
.ds-select:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.ds-check-row {
    display: inline-flex;
    align-items: center;
    gap: var(--ds-space-2);
    min-height: var(--ds-touch-target);
    cursor: pointer;
}

.ds-checkbox,
.ds-radio {
    appearance: none;
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    border: 1.5px solid var(--ds-border-strong);
    background: var(--ds-surface);
    cursor: pointer;
    display: inline-grid;
    place-content: center;
    transition: background-color var(--ds-motion-hover) var(--ds-ease-standard),
                border-color var(--ds-motion-hover) var(--ds-ease-standard);
}

.ds-checkbox {
    border-radius: var(--ds-radius-sm);
}

.ds-radio {
    border-radius: 50%;
}

.ds-checkbox::before {
    content: "";
    width: 11px;
    height: 11px;
    transform: scale(0);
    background: var(--ds-text-on-accent);
    clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
    transition: transform var(--ds-motion-tap) var(--ds-ease-standard);
}

.ds-radio::before {
    content: "";
    width: 9px;
    height: 9px;
    border-radius: 50%;
    transform: scale(0);
    background: var(--ds-text-on-accent);
    transition: transform var(--ds-motion-tap) var(--ds-ease-standard);
}

.ds-checkbox:checked,
.ds-radio:checked {
    background: var(--ds-primary);
    border-color: var(--ds-primary);
}

.ds-checkbox:checked::before,
.ds-radio:checked::before {
    transform: scale(1);
}

.ds-checkbox:focus-visible,
.ds-radio:focus-visible {
    outline: 2px solid var(--ds-primary);
    outline-offset: 2px;
}

.ds-toggle {
    appearance: none;
    width: 44px;
    height: 26px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-border-strong);
    position: relative;
    cursor: pointer;
    flex-shrink: 0;
    transition: background-color var(--ds-motion-hover) var(--ds-ease-standard);
}

.ds-toggle::before {
    content: "";
    position: absolute;
    inset-block-start: 3px;
    inset-inline-start: 3px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--ds-surface);
    box-shadow: var(--ds-shadow-card);
    transition: inset-inline-start var(--ds-motion-hover) var(--ds-ease-standard);
}

.ds-toggle:checked {
    background: var(--ds-primary);
}

.ds-toggle:checked::before {
    inset-inline-start: 21px;
}

.ds-toggle:focus-visible {
    outline: 2px solid var(--ds-primary);
    outline-offset: 2px;
}

/* ================================================================
   Card / Badge
   ================================================================ */

.ds-card {
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-lg);
    box-shadow: var(--ds-shadow-card);
    padding: var(--ds-pad-card);
}

.ds-stat-card {
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-lg);
    box-shadow: var(--ds-shadow-card);
    padding: var(--ds-space-5);
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-3);
}

.ds-stat-card-label {
    font-size: var(--ds-text-sm);
    color: var(--ds-text-secondary);
    font-weight: var(--ds-fw-medium);
}

.ds-stat-card-value {
    font-size: var(--ds-text-2xl);
    font-weight: var(--ds-fw-bold);
    color: var(--ds-text-primary);
    font-variant-numeric: tabular-nums;
    line-height: var(--ds-leading-tight);
}

.ds-stat-card-delta {
    font-size: var(--ds-text-xs);
    font-weight: var(--ds-fw-medium);
}

.ds-stat-card-delta.is-up {
    color: var(--ds-success-text);
}

.ds-stat-card-delta.is-down {
    color: var(--ds-danger-text);
}

/* An icon inside a line of text (see Components.icon): never squashed by a
   flex parent, and sitting on the text baseline rather than below it. */
.ds-inline-icon {
    flex: none;
    vertical-align: -0.15em;
}

.ds-icon-tile {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: var(--ds-radius-md);
    flex-shrink: 0;
}

.ds-icon-tile svg {
    width: 18px;
    height: 18px;
    display: block;
}

.ds-icon-tile.tile-indigo {
    background: var(--ds-primary-tint);
    color: var(--ds-primary);
}

.ds-icon-tile.tile-blue {
    background: var(--ds-info-tint);
    color: var(--ds-info);
}

.ds-icon-tile.tile-green {
    background: var(--ds-success-tint);
    color: var(--ds-success);
}

.ds-icon-tile.tile-orange {
    background: var(--ds-warning-tint);
    color: var(--ds-warning);
}

.ds-icon-tile.tile-pink {
    background: var(--ds-danger-tint);
    color: var(--ds-danger);
}

.ds-chart-card {
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-lg);
    box-shadow: var(--ds-shadow-card);
    padding: var(--ds-space-5);
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-4);
}

.ds-chart-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ds-space-3);
}

.ds-chart-card-title {
    font-size: var(--ds-text-md);
    font-weight: var(--ds-fw-semibold);
    color: var(--ds-text-primary);
    flex: 1 1 auto;
    min-width: 0;
}

/*
 * A control in a card header is a filter, not a form field.
 *
 * .ds-select / .ds-input are width:100% because they normally sit in a stacked
 * form. Left at that in a flex header they take the entire row: the Dashboard's
 * three-option period picker was ~540px wide and squeezed "Sales Overview" into
 * wrapping onto two lines beside it.
 */
.ds-chart-card-header .ds-select,
.ds-chart-card-header .ds-input {
    width: auto;
    min-width: 140px;
    max-width: 220px;
    flex: 0 0 auto;
}

.ds-chart-card-body {
    min-height: 180px;
}

.ds-chart-card-legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ds-space-3);
    font-size: var(--ds-text-xs);
    color: var(--ds-text-secondary);
}

.ds-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--ds-space-1);
    padding-inline: var(--ds-space-2);
    padding-block: 3px;
    font-size: var(--ds-text-xs);
    font-weight: var(--ds-fw-medium);
    border-radius: var(--ds-radius-sm);
    background: var(--ds-bg-inset);
    color: var(--ds-text-secondary);
}

.ds-badge-success {
    background: var(--ds-success-tint);
    color: var(--ds-success-text);
}

.ds-badge-warning {
    background: var(--ds-warning-tint);
    color: var(--ds-warning-text);
}

.ds-badge-danger {
    background: var(--ds-danger-tint);
    color: var(--ds-danger-text);
}

.ds-badge-info {
    background: var(--ds-info-tint);
    color: var(--ds-info-text);
}

.ds-badge-gold {
    background: var(--ds-primary-tint);
    color: var(--ds-primary);
}

.ds-pill-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: currentColor;
    flex-shrink: 0;
}

.ds-price-hero {
    font-variant-numeric: tabular-nums;
    font-weight: var(--ds-fw-bold);
    color: var(--ds-text-primary);
}

/* ================================================================
   Tabs / segmented control
   ================================================================ */

.ds-tabs {
    display: inline-flex;
    gap: 2px;
    padding: 3px;
    background: var(--ds-bg-inset);
    border-radius: var(--ds-radius-md);
}

.ds-tab {
    appearance: none;
    border: none;
    background: transparent;
    color: var(--ds-text-secondary);
    font-family: var(--ds-font-sans);
    font-size: var(--ds-text-sm);
    font-weight: var(--ds-fw-medium);
    padding-inline: var(--ds-space-4);
    min-height: 38px;
    border-radius: var(--ds-radius-sm);
    cursor: pointer;
    transition: background-color var(--ds-motion-hover) var(--ds-ease-standard),
                color var(--ds-motion-hover) var(--ds-ease-standard);
}

:where(.can-hover) .ds-tab:hover {
    color: var(--ds-text-primary);
}

.ds-tab.is-active {
    background: var(--ds-surface);
    color: var(--ds-primary);
    box-shadow: var(--ds-shadow-card);
}

/* ================================================================
   Modal
   ================================================================ */

.ds-modal-overlay {
    position: fixed;
    inset: 0;
    background: var(--ds-bg-overlay);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: var(--ds-z-modal);
    padding: var(--ds-space-4);
}

.ds-modal {
    width: 100%;
    max-width: 480px;
    max-height: 85vh;
    display: flex;
    flex-direction: column;
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-xl);
    box-shadow: var(--ds-shadow-modal);
    overflow: hidden;
    animation: ds-modal-enter var(--ds-duration-normal) var(--ds-ease-standard);
}

.modal-overlay.active .modal {
    animation: ds-modal-enter var(--ds-duration-normal) var(--ds-ease-standard);
}

@keyframes ds-modal-enter {
    from {
        opacity: 0;
        transform: scale(0.96);
    }
    to {
        opacity: 1;
        transform: scale(1);
    }
}

.ds-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--ds-space-5);
    border-block-end: 1px solid var(--ds-border-default);
}

.ds-modal-title {
    font-size: var(--ds-text-lg);
    font-weight: var(--ds-fw-semibold);
    text-align: start;
}

.ds-modal-body {
    padding: var(--ds-space-5);
    overflow-y: auto;
    text-align: start;
}

.ds-modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: var(--ds-space-3);
    padding: var(--ds-space-4) var(--ds-space-5);
    border-block-start: 1px solid var(--ds-border-default);
}

.ds-modal-close {
    width: var(--ds-touch-target);
    height: var(--ds-touch-target);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: transparent;
    color: var(--ds-text-tertiary);
    border-radius: var(--ds-radius-md);
    cursor: pointer;
}

:where(.can-hover) .ds-modal-close:hover {
    background: var(--ds-bg-inset);
    color: var(--ds-text-primary);
}

/* ================================================================
   Toast
   ================================================================ */

.ds-toast-region {
    position: fixed;
    inset-block-end: var(--ds-space-5);
    inset-inline-end: var(--ds-space-5);
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-2);
    z-index: var(--ds-z-toast);
    max-width: 360px;
}

.ds-toast,
.toast {
    display: flex;
    align-items: flex-start;
    gap: var(--ds-space-3);
    padding: var(--ds-space-3) var(--ds-space-4);
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-inline-start-width: 3px;
    border-inline-start-color: var(--ds-border-strong);
    border-radius: var(--ds-radius-md);
    box-shadow: var(--ds-shadow-pop);
    font-size: var(--ds-text-sm);
    color: var(--ds-text-primary);
    text-align: start;
    animation: ds-toast-enter var(--ds-duration-normal) var(--ds-ease-standard);
}

@keyframes ds-toast-enter {
    from {
        opacity: 0;
        transform: translateX(16px);
    }
    to {
        opacity: 1;
        transform: translateX(0);
    }
}

[dir="rtl"] .ds-toast,
[dir="rtl"] .toast {
    animation-name: ds-toast-enter-rtl;
}

@keyframes ds-toast-enter-rtl {
    from {
        opacity: 0;
        transform: translateX(-16px);
    }
    to {
        opacity: 1;
        transform: translateX(0);
    }
}

.toast.removing {
    animation: ds-toast-exit var(--ds-duration-fast) var(--ds-ease-exit) forwards;
}

@keyframes ds-toast-exit {
    to {
        opacity: 0;
        transform: translateX(16px);
    }
}

.ds-toast-icon {
    flex-shrink: 0;
    margin-block-start: 2px;
}

.ds-toast-success {
    border-inline-start-color: var(--ds-success);
}

.ds-toast-success .ds-toast-icon {
    color: var(--ds-success);
}

.ds-toast-warning {
    border-inline-start-color: var(--ds-warning);
}

.ds-toast-warning .ds-toast-icon {
    color: var(--ds-warning);
}

.ds-toast-danger {
    border-inline-start-color: var(--ds-danger);
}

.ds-toast-danger .ds-toast-icon {
    color: var(--ds-danger);
}

.ds-toast-info {
    border-inline-start-color: var(--ds-info);
}

.ds-toast-info .ds-toast-icon {
    color: var(--ds-info);
}

/* ================================================================
   Nav shell (design-system primitives)
   ================================================================ */

.ds-sidebar {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-1);
    width: var(--sidebar-width-expanded, 232px);
    padding: var(--ds-space-3);
    background: var(--ds-sidebar-bg);
    color: var(--ds-sidebar-fg);
    text-align: start;
}

.ds-nav-item {
    display: flex;
    align-items: center;
    gap: var(--ds-space-3);
    min-height: var(--ds-touch-target);
    padding-inline: var(--ds-space-3);
    border-radius: var(--ds-radius-xl);
    color: var(--ds-sidebar-fg);
    font-size: var(--ds-text-sm);
    font-weight: var(--ds-fw-medium);
    cursor: pointer;
    transition: background-color var(--ds-motion-hover) var(--ds-ease-standard),
                color var(--ds-motion-hover) var(--ds-ease-standard);
}

:where(.can-hover) .ds-nav-item:hover {
    color: var(--ds-sidebar-pill);
}

.ds-nav-item.is-active {
    background: var(--ds-sidebar-pill);
    color: var(--ds-sidebar-fg-active);
}

.ds-topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 56px;
    padding-inline: var(--ds-space-5);
    background: var(--ds-surface);
    border-block-end: 1px solid var(--ds-border);
}

/* ================================================================
   Typography helpers
   ================================================================ */

.ds-h1 {
    font-size: var(--ds-text-2xl);
    font-weight: var(--ds-fw-bold);
    line-height: var(--ds-leading-tight);
}

.ds-h2 {
    font-size: var(--ds-text-xl);
    font-weight: var(--ds-fw-semibold);
    line-height: var(--ds-leading-tight);
}

.ds-h3 {
    font-size: var(--ds-text-lg);
    font-weight: var(--ds-fw-semibold);
    line-height: var(--ds-leading-tight);
}

.ds-text-secondary {
    color: var(--ds-text-secondary);
}

.ds-text-mono {
    font-family: var(--ds-font-mono);
}

/* ================================================================
   Divider
   ================================================================ */

.ds-seam {
    height: 1px;
    background: var(--ds-border);
    border: none;
}

/* ================================================================
   Floor plan table chips
   ================================================================ */

.ds-atrium-canvas {
    position: relative;
    background: var(--ds-canvas);
    border-radius: var(--ds-radius-lg);
    border: 1px solid var(--ds-border);
}

.ds-atrium-table {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-lg);
    box-shadow: var(--ds-shadow-card);
    transition: transform var(--ds-motion-hover) var(--ds-ease-standard),
                box-shadow var(--ds-motion-hover) var(--ds-ease-standard),
                border-color var(--ds-motion-hover) var(--ds-ease-standard);
}

:where(.can-hover) .ds-atrium-table:hover {
    transform: translateY(-1px);
    box-shadow: var(--ds-shadow-pop);
}

.ds-atrium-table.is-seated {
    border-color: var(--ds-warning);
    box-shadow: var(--ds-shadow-card);
}

.ds-atrium-table.is-bill-dropped {
    border-color: var(--ds-info);
    box-shadow: var(--ds-shadow-card);
}

.ds-atrium-table.is-needs-attention {
    border-color: var(--ds-danger);
    box-shadow: var(--ds-shadow-card);
}

/* ================================================================
   Command palette
   ================================================================ */

.ds-command-palette-overlay,
.ds-prism-overlay {
    position: fixed;
    inset: 0;
    background: var(--ds-bg-overlay);
    z-index: var(--ds-z-prism);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding-block-start: 12vh;
}

.ds-command-palette,
.ds-prism {
    width: 100%;
    max-width: 560px;
    max-height: 60vh;
    display: flex;
    flex-direction: column;
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-xl);
    box-shadow: var(--ds-shadow-modal);
    overflow: hidden;
    transform-origin: top center;
    animation: ds-palette-enter var(--ds-motion-panel) var(--ds-ease-standard);
}

@keyframes ds-palette-enter {
    from {
        opacity: 0;
        transform: scale(0.96);
    }
    to {
        opacity: 1;
        transform: scale(1);
    }
}

.ds-command-palette-input,
.ds-prism-input {
    appearance: none;
    border: none;
    background: transparent;
    outline: none;
    width: 100%;
    min-height: var(--ds-touch-target-primary);
    padding-inline: var(--ds-space-5);
    font-family: var(--ds-font-sans);
    font-size: var(--ds-text-lg);
    color: var(--ds-text-primary);
    border-block-end: 1px solid var(--ds-border-default);
    text-align: start;
}

.ds-command-palette-input::placeholder,
.ds-prism-input::placeholder {
    color: var(--ds-text-tertiary);
}

.ds-command-palette-results,
.ds-prism-results {
    overflow-y: auto;
    padding: var(--ds-space-2);
}

.ds-command-palette-group-label,
.ds-prism-group-label {
    text-transform: uppercase;
    letter-spacing: var(--ds-tracking-micro);
    font-size: var(--ds-text-xs);
    font-weight: var(--ds-fw-medium);
    color: var(--ds-text-tertiary);
    padding: var(--ds-space-2) var(--ds-space-3);
}

.ds-command-palette-item,
.ds-prism-item {
    display: flex;
    align-items: center;
    gap: var(--ds-space-3);
    min-height: var(--ds-touch-target);
    padding-inline: var(--ds-space-3);
    border-radius: var(--ds-radius-md);
    color: var(--ds-text-primary);
    font-size: var(--ds-text-sm);
    cursor: pointer;
    transition: background-color var(--ds-motion-tap) var(--ds-ease-standard);
}

:where(.can-hover) .ds-command-palette-item:hover,
.ds-command-palette-item.is-selected,
:where(.can-hover) .ds-prism-item:hover,
.ds-prism-item.is-selected {
    background: var(--ds-primary-tint);
}

/* A result's name, then where it lives ("Display language - Localization"). */
.ds-command-palette-label {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ds-command-palette-detail {
    flex: 0 1 auto;
    max-width: 55%;
    overflow: hidden;
    color: var(--ds-text-tertiary);
    font-size: var(--ds-text-xs);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ds-command-palette-empty,
.ds-prism-empty {
    padding: var(--ds-space-6);
    text-align: center;
    color: var(--ds-text-tertiary);
    font-size: var(--ds-text-sm);
}

/* ================================================================
   Rolling total display
   ================================================================ */

.ds-total,
.ds-odometer {
    display: inline-flex;
    font-variant-numeric: tabular-nums;
    font-weight: var(--ds-fw-semibold);
    /* One flex item per character: under an RTL page the row inherited
       direction:rtl and drew "79,500 IQD" as "DQI 005,97". */
    direction: ltr;
    unicode-bidi: isolate;
}

.ds-total-digit,
.ds-odometer-digit {
    position: relative;
    display: inline-block;
    overflow: hidden;
    height: 1.2em;
    vertical-align: bottom;
}

.ds-total-digit.is-space,
.ds-odometer-digit.is-space {
    width: 0.35em;
    min-width: 0.35em;
}

.ds-total-digit-track,
.ds-odometer-digit-track {
    display: block;
    transition: transform var(--ds-motion-panel) var(--ds-ease-standard),
                opacity var(--ds-motion-panel) var(--ds-ease-standard);
}

/* ================================================================
   Avatar / branch / table / empty / page header
   ================================================================ */

.ds-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--ds-primary-tint);
    color: var(--ds-primary);
    font-size: var(--ds-text-sm);
    font-weight: var(--ds-fw-semibold);
    flex-shrink: 0;
    overflow: hidden;
}

.ds-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.ds-avatar.ds-avatar-lg {
    width: 44px;
    height: 44px;
    font-size: var(--ds-text-md);
}

.ds-branch-select {
    display: flex;
    align-items: center;
    gap: var(--ds-space-2);
    padding: var(--ds-space-2) var(--ds-space-3);
    background: rgba(255, 255, 255, 0.12);
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: var(--ds-radius-md);
    color: var(--ds-sidebar-fg);
    font-size: var(--ds-text-sm);
    font-weight: var(--ds-fw-medium);
    cursor: pointer;
    width: 100%;
}

.ds-branch-select.is-hidden {
    display: none;
}

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

.ds-table thead th,
.data-table thead th {
    background: var(--ds-surface-alt);
    color: var(--ds-text-secondary);
    font-size: var(--ds-text-sm);
    font-weight: var(--ds-fw-medium);
    text-align: start;
    padding: var(--ds-pad-table-cell-block) var(--ds-pad-table-cell-inline);
    border-block-end: 1px solid var(--ds-border);
}

.ds-table tbody td,
.data-table tbody td {
    padding: var(--ds-pad-table-cell-block) var(--ds-pad-table-cell-inline);
    border-block-end: 1px solid var(--ds-border);
    color: var(--ds-text-primary);
    min-height: 56px;
    vertical-align: middle;
}

.ds-table tbody tr {
    transition: background-color var(--ds-motion-hover) var(--ds-ease-standard);
}

:where(.can-hover) .ds-table tbody tr:hover {
    background: var(--ds-surface-alt);
}

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

.ds-empty-state-icon {
    color: var(--ds-text-tertiary);
    opacity: 0.6;
}

.ds-empty-state-title {
    font-size: var(--ds-text-lg);
    font-weight: var(--ds-fw-semibold);
    color: var(--ds-text-primary);
}

.ds-empty-state-desc {
    font-size: var(--ds-text-sm);
    color: var(--ds-text-secondary);
    max-width: 360px;
}

.page {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-4);
    width: 100%;
    min-width: 0;
}

.page-header,
.ds-page-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--ds-space-4);
    padding-block: var(--ds-space-3);
    margin-block-end: 0;
}

.ds-page-header-main {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-1);
}

.ds-page-header-title {
    font-size: var(--ds-text-2xl);
    font-weight: var(--ds-fw-bold);
    color: var(--ds-text-primary);
    line-height: var(--ds-leading-tight);
}

.ds-page-header-subtitle {
    font-size: var(--ds-text-sm);
    color: var(--ds-text-secondary);
}

.ds-page-header-actions {
    display: flex;
    align-items: center;
    gap: var(--ds-space-3);
    flex-shrink: 0;
}

/* List-page filter row. Selects/inputs are width:100% by default elsewhere;
   toolbar children must size to content so they sit on one horizontal row. */
.ds-toolbar,
.toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ds-space-3);
    min-height: 40px;
}

.ds-toolbar .ds-input,
.ds-toolbar .ds-select,
.ds-toolbar .ds-btn {
    width: auto;
    min-height: 40px;
    height: 40px;
    box-sizing: border-box;
}

.ds-toolbar .ds-select {
    flex: 0 1 auto;
    min-width: 140px;
    max-width: 220px;
}

.ds-toolbar .ds-btn {
    flex: 0 0 auto;
    padding-inline: var(--ds-space-4);
}

.ds-toolbar-search,
/*
 * Base styling for the search component, NOT scoped to an ancestor.
 *
 * Every rule that sized this thing used to live under `.ds-toolbar` or
 * `.inventory-toolbar`, so the component only worked in the one place it was
 * first written for. `_dsSearchBar()` on Inventory > Receive drops the same
 * markup into a plain <div>, where nothing matched -- and an <svg> carrying a
 * viewBox but no width/height fills its container, so the magnifier grew to
 * 969x969 and swallowed the Pick Products panel as a giant black ring.
 *
 * The icon is given real dimensions here so it can never do that again
 * wherever the component is dropped. The toolbar rules below still apply on
 * top for flex sizing inside a toolbar.
 */
.page-search {
    position: relative;
    display: block;
    width: 100%;
}

.page-search > svg {
    position: absolute;
    inset-inline-start: var(--ds-space-3);
    top: 50%;
    transform: translateY(-50%);
    width: 16px;
    height: 16px;
    flex: none;
    color: var(--ds-text-tertiary);
    pointer-events: none;
}

.page-search > .ds-input {
    width: 100%;
    min-height: 40px;
    padding-inline-start: calc(var(--ds-space-3) + 20px);
}

.ds-toolbar .page-search,
.ds-toolbar .clients-search,
.ds-toolbar .orders-search {
    position: relative;
    flex: 1 1 220px;
    min-width: 180px;
    max-width: min(100%, 380px);
}

.ds-toolbar-search svg,
.ds-toolbar .page-search svg {
    position: absolute;
    inset-inline-start: var(--ds-space-3);
    top: 50%;
    transform: translateY(-50%);
    width: 16px;
    height: 16px;
    color: var(--ds-text-tertiary);
    pointer-events: none;
}

.ds-toolbar-search .ds-input,
.ds-toolbar .page-search .ds-input {
    width: 100%;
    min-height: 40px;
    height: 40px;
    padding-inline-start: calc(var(--ds-space-3) + 20px);
}

@media (max-width: 900px) {
    .ds-toolbar .ds-select,
    .ds-toolbar .ds-btn,
    .ds-toolbar-search,
    .ds-toolbar .page-search {
        flex: 1 1 100%;
        max-width: none;
        width: 100%;
    }
}

/* Alias for pages that use .ds-empty instead of .ds-empty-state */
.ds-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--ds-space-3);
    padding: var(--ds-space-10) var(--ds-space-6);
    text-align: center;
}

/* ================================================================
   Initials / file / bar chart / kbd
   ================================================================ */

.ds-initials {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--ds-bg-inset);
    color: var(--ds-text-secondary);
    box-shadow: inset 0 0 0 1px var(--ds-border-default);
    font-weight: var(--ds-fw-semibold);
    letter-spacing: 0.02em;
    border-radius: var(--ds-radius-sm);
}

.ds-file {
    display: inline-flex;
    align-items: center;
    gap: var(--ds-space-2);
    flex-wrap: wrap;
    cursor: pointer;
}

.ds-file-input {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

.ds-file-name {
    font-size: var(--ds-text-sm);
    color: var(--ds-text-tertiary);
}

.ds-file-input:focus-visible + .ds-btn {
    outline: 2px solid var(--ds-primary);
    outline-offset: 2px;
}

.ds-barchart {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-2);
    width: 100%;
}

.ds-bar-row {
    display: grid;
    grid-template-columns: minmax(80px, 30%) 1fr auto;
    align-items: center;
    gap: var(--ds-space-3);
}

.ds-bar-name {
    font-size: var(--ds-text-sm);
    color: var(--ds-text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-align: start;
}

.ds-bar-track {
    display: block;
    height: 28px;
    border-radius: var(--ds-radius-sm);
    background: var(--ds-bg-inset);
    overflow: hidden;
}

.ds-bar-fill {
    display: block;
    height: 100%;
    min-width: 4px;
    border-radius: var(--ds-radius-sm);
    background: var(--ds-primary-tint);
    box-shadow: inset 0 0 0 1px var(--ds-primary);
    transition: width var(--ds-motion-panel) var(--ds-ease-standard);
}

.ds-bar-val {
    font-weight: var(--ds-fw-semibold);
    font-size: var(--ds-text-sm);
    color: var(--ds-text-primary);
    text-align: end;
    min-width: 2ch;
}

.ds-kbd {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 18px;
    padding: 0 4px;
    background: var(--ds-bg-inset);
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-sm);
    font-family: var(--ds-font-mono);
    font-size: var(--ds-text-xs);
    font-weight: var(--ds-fw-medium);
    color: var(--ds-text-secondary);
    white-space: nowrap;
}

/* ================================================================
   B1b — Motion utilities (transform + opacity only)
   ================================================================ */

@keyframes ds-motion-page-in {
    from {
        opacity: 0;
        transform: translateY(8px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes ds-motion-tab-in {
    from {
        opacity: 0;
        transform: translateY(8px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes ds-motion-fade-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

.ds-motion-page-enter {
    animation: ds-motion-page-in var(--ds-duration-mid) var(--ds-ease-standard) both;
}

.ds-motion-tab-enter {
    animation: ds-motion-tab-in var(--ds-duration-normal) var(--ds-ease-standard) both;
}

.ds-motion-slide-up {
    animation: ds-motion-page-in var(--ds-duration-normal) var(--ds-ease-standard) both;
}

.ds-motion-slide-down {
    animation: ds-motion-page-in var(--ds-duration-normal) var(--ds-ease-standard) both;
    transform-origin: top center;
}

.ds-motion-fade {
    animation: ds-motion-fade-in var(--ds-duration-normal) var(--ds-ease-standard) both;
}

body:not([data-page="pos"]) .page-content > * {
    animation: ds-motion-page-in var(--ds-duration-mid) var(--ds-ease-standard) both;
}

/* POS product card press — scale .97, transform + opacity only */
.pos-product-card {
    touch-action: manipulation;
    transition: transform var(--ds-duration-fast) var(--ds-ease-standard),
                opacity var(--ds-duration-fast) var(--ds-ease-standard);
}

.pos-product-card:active:not(.disabled):not(.sold-out):not(.out-of-stock) {
    transform: scale(0.97);
    transition-duration: var(--ds-duration-fast);
}

/* Skeleton placeholders */
@keyframes ds-skeleton-shimmer {
    0% { background-position: -200px 0; }
    100% { background-position: calc(200px + 100%) 0; }
}

/*
 * A solid block with a light band passing over it. The band used to be the
 * only paint (200px, no-repeat) and ran from #FAFAFE to the same #FAFAFE, so
 * on the #F7F7FC canvas a loading outline was invisible -- a blank screen.
 * The pass was 0.36s, a flicker; 1.4s reads as waiting.
 */
.ds-skeleton,
.skeleton {
    background-color: var(--ds-neutral-200);
    background-image: linear-gradient(90deg, transparent 0%, rgba(255, 255, 255, 0.7) 50%, transparent 100%);
    background-size: 200px 100%;
    background-repeat: no-repeat;
    animation: ds-skeleton-shimmer 1.4s linear infinite;
    border-radius: var(--ds-radius-sm);
}

/* The outline a page shows while it gets its data (Router._startRouteLoading). */
.route-loading {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-4);
    padding: var(--ds-pad-page-block) var(--ds-pad-page-inline);
}

.route-loading-words {
    color: var(--ds-text-secondary);
    font-size: var(--ds-text-sm);
}

/* Under five seconds the words are for screen readers only. */
.route-loading:not(.is-slow) .route-loading-words {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.route-loading-outline {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-4);
}

.route-skel-head {
    height: 40px;
    max-width: 320px;
}

.route-skel-row {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--ds-space-4);
}

.route-skel-row > .ds-skeleton {
    height: 96px;
    border-radius: var(--ds-radius-lg);
}

.route-skel-body {
    height: 240px;
    border-radius: var(--ds-radius-lg);
}

.ds-skeleton-text {
    height: 0.875rem;
    width: 100%;
    max-width: 12rem;
}

.ds-skeleton-title {
    height: 1.25rem;
    width: 60%;
    max-width: 16rem;
}

.ds-skeleton-block {
    height: 4rem;
    width: 100%;
}

.ds-skeleton-circle {
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 50%;
}

/* Legacy card / table alignment (token padding) */
.card:not(.ds-list-card):not(.pos-product-card) {
    padding: var(--ds-pad-card);
}

.data-table,
.table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--ds-text-sm);
}

.table th,
.table td {
    padding: var(--ds-pad-table-cell-block) var(--ds-pad-table-cell-inline);
}

button,
.btn,
.ds-btn,
.ds-tab,
.pos-toolbar-btn {
    touch-action: manipulation;
}

/* ================================================================
   App shell overrides (#sidebar, #topBar)
   ================================================================ */

#sidebar.sidebar,
.sidebar#sidebar {
    width: var(--sidebar-width, 72px);
    background: var(--ds-sidebar-bg);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border-inline-end: none;
    box-shadow: none;
    color: var(--ds-sidebar-fg);
    transition: width var(--ds-motion-panel) var(--ds-ease-standard);
}

#sidebar.sidebar:not(.collapsed),
.sidebar#sidebar:not(.collapsed) {
    width: var(--sidebar-width-expanded, 232px);
}

#sidebar .sidebar-header,
.sidebar .sidebar-header {
    border-block-end: 1px solid rgba(255, 255, 255, 0.12);
    padding-inline: var(--ds-space-3);
    justify-content: flex-start;
    gap: var(--ds-space-2);
    overflow: visible;
}

#sidebar:not(.collapsed) .sidebar-header,
.sidebar:not(.collapsed) .sidebar-header {
    padding-inline: var(--ds-space-4);
}

#sidebar .logo,
.sidebar .logo {
    overflow: visible;
    flex: 1;
    min-width: 0;
}

#sidebar.collapsed .logo .b60-brand-lockup,
.sidebar.collapsed .logo .b60-brand-lockup {
    display: none;
}

#sidebar.collapsed .logo #sidebarLogoMark,
.sidebar.collapsed .logo #sidebarLogoMark {
    display: none;
}

#sidebar.collapsed .logo #sidebarLogo,
.sidebar.collapsed .logo #sidebarLogo {
    display: block !important;
    margin-inline: auto;
}

/* When no uploaded logo, show a compact mark in the collapsed rail */
#sidebar.collapsed .logo::before,
.sidebar.collapsed .logo::before {
    content: '60';
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    margin-inline: auto;
    border-radius: var(--ds-radius-sm);
    background: rgba(255, 255, 255, 0.14);
    color: var(--ds-sidebar-pill);
    font-size: var(--ds-text-xs);
    font-weight: var(--ds-fw-bold);
    letter-spacing: -0.02em;
}

#sidebar.collapsed .logo:has(#sidebarLogo[src]:not([style*="display: none"]))::before,
.sidebar.collapsed .logo:has(#sidebarLogo[src]:not([style*="display: none"]))::before {
    display: none;
}

#sidebar .nav-item,
.sidebar .nav-item {
    position: relative;
}

/* Collapsed-rail tooltips (native title is a fallback; this is the styled one) */
:where(.can-hover) #sidebar.collapsed .nav-item[data-tooltip]:hover::after,
:where(.can-hover) .sidebar.collapsed .nav-item[data-tooltip]:hover::after {
    content: attr(data-tooltip);
    position: absolute;
    inset-inline-start: calc(100% + 10px);
    top: 50%;
    transform: translateY(-50%);
    background: var(--ds-surface);
    color: var(--ds-text-primary);
    padding: 8px 8px;
    border-radius: var(--ds-radius-sm);
    font-size: var(--ds-text-xs);
    font-weight: var(--ds-fw-medium);
    white-space: nowrap;
    z-index: 80;
    border: 1px solid var(--ds-border);
    box-shadow: var(--ds-shadow-card);
    pointer-events: none;
}

#sidebar .logo-text,
.sidebar .logo-text {
    color: var(--ds-sidebar-pill);
    font-weight: var(--ds-fw-semibold);
}

#sidebar .logo-mark,
.sidebar .logo-mark {
    background: rgba(255, 255, 255, 0.14);
    color: var(--ds-sidebar-pill);
    box-shadow: none;
}

.b60-logo {
    display: inline-flex;
    align-items: center;
    gap: var(--ds-space-2);
    color: var(--ds-sidebar-pill);
    font-weight: var(--ds-fw-bold);
    font-size: var(--ds-text-md);
    letter-spacing: -0.02em;
}

.b60-logo-os {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 2px 8px;
    border: 1px solid rgba(255, 255, 255, 0.55);
    border-radius: var(--ds-radius-sm);
    font-size: var(--ds-text-xs);
    font-weight: var(--ds-fw-semibold);
    letter-spacing: 0.04em;
}

.b60-brand-lockup {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.b60-brand-lockup .b60-business-name,
.b60-brand-lockup .logo-text {
    font-size: var(--ds-text-xs);
    font-weight: var(--ds-fw-medium);
    color: rgba(255, 255, 255, 0.72);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

#sidebar.collapsed .b60-brand-lockup .b60-business-name,
.sidebar.collapsed .b60-brand-lockup .b60-business-name {
    display: none;
}

#sidebar .user-badge,
.sidebar .user-badge {
    display: flex;
    align-items: center;
    gap: var(--ds-space-2);
    padding: var(--ds-space-2) var(--ds-space-3);
}

#sidebar .user-badge-text,
.sidebar .user-badge-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    flex: 1;
}

#sidebar .user-role,
.sidebar .user-role {
    font-size: var(--ds-text-xs);
    color: rgba(255, 255, 255, 0.62);
}

#sidebar .user-online-dot,
.sidebar .user-online-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--ds-success);
    flex-shrink: 0;
    box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.25);
}

#sidebar.collapsed .user-badge-text,
#sidebar.collapsed .user-role,
#sidebar.collapsed .user-online-dot,
.sidebar.collapsed .user-badge-text,
.sidebar.collapsed .user-role,
.sidebar.collapsed .user-online-dot {
    display: none;
}

#sidebar .sidebar-logout-btn,
.sidebar .sidebar-logout-btn {
    background: rgba(255, 255, 255, 0.10);
    border-color: rgba(255, 255, 255, 0.18);
    color: var(--ds-sidebar-fg);
}

:where(.can-hover) #sidebar .sidebar-logout-btn:hover,
:where(.can-hover) .sidebar .sidebar-logout-btn:hover {
    background: rgba(255, 255, 255, 0.16);
    color: var(--ds-sidebar-pill);
}

#sidebar .nav-item,
.sidebar .nav-item {
    color: var(--ds-sidebar-fg);
    border-radius: var(--ds-radius-xl);
    min-height: var(--ds-touch-target);
}

:where(.can-hover) #sidebar .nav-item:hover,
:where(.can-hover) .sidebar .nav-item:hover {
    background: rgba(255, 255, 255, 0.10);
    color: var(--ds-sidebar-pill);
}

#sidebar .nav-item.active,
.sidebar .nav-item.active {
    background: var(--ds-sidebar-pill);
    color: var(--ds-sidebar-fg-active);
    box-shadow: var(--ds-shadow-card);
    border-inline-start: none;
}

#sidebar .nav-item.active::before,
.sidebar .nav-item.active::before {
    display: none;
}

#sidebar .nav-section-label,
.sidebar .nav-section-label {
    color: rgba(255, 255, 255, 0.50);
}

#sidebar .nav-section + .nav-section,
.sidebar .nav-section + .nav-section {
    border-block-start-color: rgba(255, 255, 255, 0.12);
}

#sidebar .sidebar-toggle,
.sidebar .sidebar-toggle {
    color: var(--ds-sidebar-fg);
}

:where(.can-hover) #sidebar .sidebar-toggle:hover,
:where(.can-hover) .sidebar .sidebar-toggle:hover {
    background: rgba(255, 255, 255, 0.12);
    color: var(--ds-sidebar-pill);
}

#sidebar .sidebar-footer,
.sidebar .sidebar-footer {
    border-block-start: 1px solid rgba(255, 255, 255, 0.12);
}

#sidebar .user-badge,
.sidebar .user-badge {
    color: var(--ds-sidebar-fg);
    background: rgba(255, 255, 255, 0.08);
    border-radius: var(--ds-radius-md);
    margin-block-end: var(--ds-space-2);
}

#sidebar .user-badge .ds-avatar,
.sidebar .user-badge .ds-avatar {
    width: 32px;
    height: 32px;
}

#topBar.top-bar,
.top-bar#topBar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ds-space-4);
    padding-inline: var(--ds-space-6);
    background: var(--ds-surface);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border-block-end: 1px solid var(--ds-border);
    box-shadow: none;
}

#topBar .page-title h1,
.top-bar .page-title h1 {
    color: var(--ds-text-primary);
    font-weight: var(--ds-fw-bold);
}

#topBar .page-subtitle,
.top-bar .page-subtitle {
    color: var(--ds-text-secondary);
    font-size: var(--ds-text-sm);
}

#topBar .datetime,
.top-bar .datetime {
    font-size: var(--ds-text-sm);
    color: var(--ds-text-secondary);
    font-variant-numeric: tabular-nums;
}

#topBar .top-bar-search,
.top-bar .top-bar-search {
    display: flex;
    align-items: center;
    gap: var(--ds-space-2);
    flex: 1;
    max-width: 420px;
    padding: var(--ds-space-2) var(--ds-space-3);
    background: var(--ds-surface-alt);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-md);
    color: var(--ds-text-tertiary);
    font-size: var(--ds-text-sm);
    cursor: pointer;
}

#topBar .top-bar-search .ds-kbd,
.top-bar .top-bar-search .ds-kbd {
    margin-inline-start: auto;
}

#topBar .datetime-block,
.top-bar .datetime-block {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;
    font-size: var(--ds-text-sm);
    color: var(--ds-text-secondary);
    font-variant-numeric: tabular-nums;
}

#topBar .datetime-date,
.top-bar .datetime-date {
    font-weight: var(--ds-fw-medium);
    color: var(--ds-text-primary);
}

#topBar .datetime-time,
/* Purple is kept for what can be pressed, what is picked, and status; the
   time is none of those. */
.top-bar .datetime-time {
    font-size: var(--ds-text-xs);
    color: var(--ds-text-secondary);
}

#topBar .topbar-user-btn,
.top-bar .topbar-user-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--ds-space-1);
    width: auto;
    padding-inline: var(--ds-space-1);
}

#topBar .topbar-user-menu,
.top-bar .topbar-user-menu {
    position: absolute;
    inset-block-start: calc(100% + 4px);
    inset-inline-end: 0;
    min-width: 160px;
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-md);
    box-shadow: var(--ds-shadow-pop);
    padding: var(--ds-space-1);
    z-index: var(--ds-z-overlay);
}

#topBar .topbar-user-menu-item,
.top-bar .topbar-user-menu-item {
    display: block;
    width: 100%;
    text-align: start;
    padding: var(--ds-space-2) var(--ds-space-3);
    border: none;
    background: transparent;
    border-radius: var(--ds-radius-sm);
    font-family: var(--ds-font-sans);
    font-size: var(--ds-text-sm);
    color: var(--ds-text-primary);
    cursor: pointer;
}

:where(.can-hover) #topBar .topbar-user-menu-item:hover,
:where(.can-hover) .top-bar .topbar-user-menu-item:hover {
    background: var(--ds-surface-alt);
}

#topBar .top-bar-actions,
.top-bar .top-bar-actions {
    position: relative;
    gap: var(--ds-space-2);
}

/*
 * The bell's list (App.initNotices). "Needs action" first, then "Worth a
 * look", each under its own label. A coloured edge says how urgent; it is
 * square, because a rounded corner bends a side line (owner, 2026-10-15).
 * Rows run edge to edge with a hairline between them, so each reads as one
 * thing; the arrow says a row opens the page that deals with it.
 */
#topBar .topbar-notices {
    position: absolute;
    inset-block-start: calc(100% + 6px);
    inset-inline-end: 0;
    width: min(380px, calc(100vw - 24px));
    /* As tall as the window allows under the top bar: the till is 730px. */
    max-height: min(calc(100vh - 76px), 640px);
    overflow-y: auto;
    padding: 0 0 var(--ds-space-2);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-lg);
    background: var(--ds-surface);
    box-shadow: var(--ds-shadow-pop);
    z-index: var(--ds-z-overlay);
}

#topBar .topbar-notices[hidden],
#topBar .notification-badge[hidden] {
    display: none;
}

#topBar .topbar-notices-head {
    position: sticky;
    inset-block-start: 0;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: var(--ds-space-2);
    padding: var(--ds-space-3) var(--ds-space-4);
    border-block-end: 1px solid var(--ds-border);
    background: var(--ds-surface);
    font-size: var(--ds-text-base);
    font-weight: var(--ds-fw-semibold);
    color: var(--ds-text-primary);
}

#topBar .topbar-notices-count {
    min-width: 22px;
    padding: 1px 8px;
    border-radius: 999px;
    background: var(--ds-surface-alt);
    font-size: var(--ds-text-xs);
    font-weight: var(--ds-fw-semibold);
    font-variant-numeric: tabular-nums;
    text-align: center;
    color: var(--ds-text-secondary);
}

#topBar .topbar-notices-empty {
    margin: 0;
    padding: var(--ds-space-6) var(--ds-space-4) var(--ds-space-4);
    text-align: center;
    font-size: var(--ds-text-sm);
    color: var(--ds-text-secondary);
}

#topBar .topbar-notices-group {
    padding: var(--ds-space-3) var(--ds-space-4) var(--ds-space-2);
    font-size: var(--ds-text-xs);
    font-weight: var(--ds-fw-semibold);
    color: var(--ds-text-tertiary);
}

#topBar .topbar-notice {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding-block: var(--ds-space-3);
    /* Text lines up with the heading: the 3px edge is part of the 16px. */
    padding-inline: calc(var(--ds-space-4) - 3px) calc(var(--ds-space-4) + 16px);
    border-inline-start: 3px solid transparent;
    border-radius: 0;
    color: inherit;
    text-decoration: none;
}

#topBar .topbar-notice + .topbar-notice {
    border-block-start: 1px solid var(--ds-border);
}

#topBar .topbar-notice.is-high {
    border-inline-start-color: var(--ds-danger);
}

#topBar .topbar-notice.is-medium {
    border-inline-start-color: var(--ds-warning);
}

#topBar .topbar-notice::after {
    content: '';
    position: absolute;
    inset-inline-end: var(--ds-space-4);
    inset-block-start: 50%;
    width: 7px;
    height: 7px;
    border-block-start: 1.5px solid var(--ds-text-tertiary);
    border-inline-end: 1.5px solid var(--ds-text-tertiary);
    transform: translateY(-50%) rotate(45deg);
}

[dir="rtl"] #topBar .topbar-notice::after {
    transform: translateY(-50%) rotate(-45deg);
}

:where(.can-hover) #topBar .topbar-notice:hover {
    background: var(--ds-surface-alt);
}

#topBar .topbar-notice:focus-visible {
    background: var(--ds-surface-alt);
    outline: 2px solid var(--ds-primary);
    outline-offset: -2px;
}

#topBar .topbar-notice-title {
    font-size: var(--ds-text-sm);
    font-weight: var(--ds-fw-semibold);
    line-height: 1.35;
    color: var(--ds-text-primary);
}

#topBar .topbar-notice-desc {
    font-size: var(--ds-text-xs);
    line-height: 1.45;
    color: var(--ds-text-secondary);
}

/* Date, time, language, alerts and account always sit at the END of the bar
   -- the right in English -- with the search at the start. On the till the
   search is hidden, and with nothing pushing them over, space-between left
   them on the left of an otherwise empty bar. The owner wants them on the
   right on every page (2026-10). Arabic mirrors this by itself. */
#topBar .top-bar-actions {
    margin-inline-start: auto;
}

.main-content .page-header,
.main-content .ds-page-header {
    padding-inline: var(--ds-pad-page-inline);
    padding-block-start: var(--ds-space-3);
    padding-block-end: var(--ds-space-1);
    width: 100%;
    margin-inline: 0;
    box-sizing: border-box;
    flex-shrink: 0;
}

.main-content .page-content {
    padding: var(--ds-pad-page-block) var(--ds-pad-page-inline) var(--ds-pad-page-inline);
    background: var(--ds-canvas);
    width: 100%;
    max-width: none;
    margin-inline: 0;
    box-sizing: border-box;
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    overflow-x: hidden;
    scrollbar-gutter: stable;
}

/* Every routed page root stretches to the content column. */
.page-content > .ds-root,
.page-content > [class$="-page"] {
    flex: 1 1 auto;
    min-width: 0;
    width: 100%;
}

/* Standard page stack — fills the content column without nested padding gaps. */
.ds-page-stack,
[class$="-page"].ds-root,
.ds-root[class$="-page"] {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-4);
    width: 100%;
    min-width: 0;
    flex: 1;
    min-height: 0;
}

/* List/table card: toolbar + head + body in one surface (no orphan search card). */
.ds-list-card {
    padding: 0;
    overflow: hidden;
}

/* List pages: card grows to viewport; table body scrolls inside. */
.ds-page-stack > .ds-list-card,
.inventory-page > #invTabBody > .ds-list-card,
.orders-page > .ds-list-card {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.ds-list-card > #clientsTable,
.ds-list-card > #ordersTable,
.ds-list-card > #invoicesTable,
.ds-list-card > #productsView,
.ds-list-card > .clients-table-wrap,
.ds-list-card > .orders-table-wrap,
.ds-list-card > .products-table-wrap,
.ds-list-card > .invoices-table-wrap,
.ds-list-card > .inventory-table-wrap {
    flex: 1;
    min-height: 0;
    overflow: auto;
    -webkit-overflow-scrolling: touch;
}

.ds-list-card > .ds-toolbar,
.ds-list-card > .ds-card-toolbar,
.ds-list-card > .toolbar {
    padding: var(--ds-pad-toolbar-block) var(--ds-pad-toolbar-inline);
    border-bottom: 1px solid var(--ds-border);
    background: var(--ds-surface);
    margin: 0;
}

.ds-list-card > .ds-card-head,
.ds-list-card > .clients-card-head,
.ds-list-card > .orders-card-head,
.ds-list-card > .products-panel-header,
.ds-list-card > .invoices-panel-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--ds-space-3);
    padding: var(--ds-space-3) var(--ds-space-5);
    border-bottom: 1px solid var(--ds-border);
    margin: 0;
}

.ds-list-card > .ds-card-head .ds-h3,
.ds-list-card > .clients-card-head .orders-card-title,
.ds-list-card > .orders-card-head .orders-card-title,
.ds-list-card > .products-panel-header .ds-h3,
.ds-list-card > .invoices-panel-header .ds-h3 {
    margin: 0;
    font-size: var(--ds-text-sm);
    font-weight: var(--ds-fw-semibold);
    color: var(--ds-text-secondary);
}

.ds-list-card > .ds-card-body,
.ds-list-card > [id$="Table"],
.ds-list-card > #clientsTable,
.ds-list-card > #productsView,
.ds-list-card > #invoicesTable {
    padding: 0;
}

.ds-list-card .clients-table-wrap,
.ds-list-card .orders-table-wrap,
.ds-list-card .inventory-table-wrap,
.ds-list-card .ds-table-wrap {
    border: none;
    border-radius: 0;
    box-shadow: none;
}

.ds-result-count {
    font-size: var(--ds-text-sm);
    font-weight: var(--ds-fw-semibold);
    color: var(--ds-text-secondary);
}

/* Full-bleed ops pages: no outer scroll, inner panels handle overflow. */
body[data-page="pos"] .main-content,
body[data-page="tables"] .main-content,
body[data-page="floor-plan"] .main-content,
body[data-page="kds"] .main-content {
    min-height: 0;
    overflow: hidden;
}

body[data-page="pos"] .main-content .page-content,
body[data-page="tables"] .main-content .page-content,
body[data-page="floor-plan"] .main-content .page-content,
body[data-page="kds"] .main-content .page-content {
    padding: 0;
    overflow: hidden;
}

body[data-page="pos"] .main-content .page-header,
body[data-page="pos"] #pageHeader {
    display: none;
}

/* POS terminal: slim top bar, hide global search (product search is in-panel) */
body[data-page="pos"] .top-bar,
body[data-page="pos"] #topBar {
    height: 44px;
    min-height: 44px;
    flex-shrink: 0;
    padding: 0 var(--ds-space-4);
}

body[data-page="pos"] .top-bar-search {
    display: none;
}

/* Kill double padding: pages must not add their own outer padding on top of
   the shell gutters (that was the 150-250px dead gap). */
.page-content > .ds-root,
.page-content > [class$="-page"] {
    padding: 0;
    max-width: none;
}

#app {
    background: var(--ds-canvas);
}

.main-content {
    background: var(--ds-canvas);
    min-height: 0;
}

#topBar .notification-badge,
.top-bar .notification-badge {
    position: absolute;
    inset-block-start: 4px;
    inset-inline-end: 4px;
    min-width: 16px;
    height: 16px;
    padding-inline: 4px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-danger);
    color: var(--ds-text-on-accent);
    font-size: 10px;
    font-weight: var(--ds-fw-semibold);
    display: flex;
    align-items: center;
    justify-content: center;
}

#topBar .icon-btn,
.top-bar .icon-btn {
    position: relative;
    color: var(--ds-text-secondary);
}

:where(.can-hover) #topBar .icon-btn:hover,
:where(.can-hover) .top-bar .icon-btn:hover {
    color: var(--ds-text-primary);
    background: var(--ds-surface-alt);
}

/* Push-not-overlay: expanded sidebar shifts content (--bp-tablet: 1024px) */
@media (min-width: 1024px) {
    #app:has(.sidebar:not(.collapsed)) .main-content {
        margin-inline-start: var(--sidebar-width-expanded, 232px);
    }
}

/* ================================================================
   APP SHELL — viewport fill & terminal responsive (all pages)
   ================================================================ */

/* Tabbed / split pages that fill the content column height */
.inventory-page,
.settings-page,
.recipes-page,
.sessions-page,
.team-page {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    min-width: 0;
    gap: var(--ds-space-4);
}

/* Scrollable multi-section pages grow naturally; page-content scrolls */
.dashboard-page,
.finance-page {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-4);
    width: 100%;
    min-width: 0;
}

/*
 * The default here is SCROLL, not clip, and that direction matters.
 *
 * This rule used to be `overflow: hidden` for every tab. On Receive that cut
 * the bottom 264px off the purchase panel at 1520x730 -- Vendor, Payment
 * Method, the totals and "Record Purchase" -- and because the overflow was
 * clipped rather than overflowing, .page-content never grew a scroll range
 * either. There was no gesture that reached the button. A delivery could be
 * picked and not recorded.
 *
 * Clipping is now opt-in, and only for a tab that ends in a .ds-list-card,
 * which scrolls its own table body and would otherwise sit inside a second
 * scrollbar. Stated twice on purpose -- by class from the renderer, and by
 * :has() from the markup -- so that a stale cached inventory.js cannot bring
 * the unreachable button back.
 */
.inventory-page > #invTabBody {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-4);
    overflow-y: auto;
    overflow-x: hidden;
}

/*
 * ...and a tab that IS a list doesn't scroll here either: it scrolls with the
 * page. See css/inventory.css -- the whole height chain is released for these
 * two tabs so there is one scrollbar, at the edge of the window, instead of a
 * short one floating inside the card.
 */
.inventory-page > #invTabBody.is-list,
.inventory-page > #invTabBody:has(> .ds-list-card) {
    flex: 0 0 auto;
    overflow: visible;
}

.settings-page > .settings-shell {
    flex: 1;
    min-height: 0;
    align-items: stretch;
}

.team-page > .team-shell {
    flex: 1;
    min-height: 0;
    align-items: stretch;
}

.team-main {
    display: flex;
    flex-direction: column;
    min-height: 0;
}

.team-panel-stack {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

.settings-main {
    display: flex;
    flex-direction: column;
    min-height: 0;
}

.settings-panel-stack {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

/* Short displays (768p tills, 1024×768) — matches --bp-short: 800px */
@media (max-height: 800px) {
    :root {
        --topbar-height: 48px;
        --ds-shell-gutter-block: clamp(6px, 1vh, 16px);
    }

    .main-content .page-header,
    .main-content .ds-page-header {
        padding-block-start: var(--ds-space-2);
        padding-block-end: 0;
    }

    .order-tabs-bar {
        height: 48px;
    }

    .ds-list-card > .ds-toolbar,
    .ds-list-card > .ds-card-toolbar {
        padding-block: var(--ds-space-3);
    }
}

@media (max-height: 640px) {
    :root {
        --topbar-height: 44px;
    }

    body[data-page="pos"] .top-bar,
    body[data-page="pos"] #topBar {
        height: 40px;
        min-height: 40px;
    }
}

/* Narrow / tablet — tighten shell gutters (mobile rules in main.css go further) */
@media (max-width: 900px) {
    :root {
        --ds-shell-gutter-inline: clamp(10px, 3vw, 16px);
    }

    .top-bar-search span:not(.ds-kbd) {
        display: none;
    }
}

/* ================================================================
   Sidebar alignment corrections
   ================================================================ */

/* The rail's nav is overflow-y:auto. A classic 6px scrollbar was being
   taken out of the content box's inline-end only, so every pill and icon
   was centred in the remaining 54px instead of the 72px rail -- 2.8px
   off-centre, with a 6px gap on the left and 11.6px on the right. That
   asymmetry is the "off" look, and it only appeared when the list
   happened to overflow, so it came and went with viewport height.
   Reserving the gutter on both edges makes centring independent of
   whether the scrollbar is present. */
/* Hiding the scrollbar entirely is what keeps the rail symmetric: with no
   scrollbar box there is no gutter to steal from one side, so the 6px
   padding centres the pills at every viewport height. scrollbar-gutter:
   stable both-edges also centres, but reserves ~21px of a 72px rail and
   shrinks the active pill to 39px -- too much of the rail spent on a bar
   nobody drags. Scrolling still works via wheel, trackpad and touch. */
#sidebar .sidebar-nav,
.sidebar .sidebar-nav {
    scrollbar-width: none;
    -ms-overflow-style: none;
    overscroll-behavior: contain;
}

#sidebar .sidebar-nav::-webkit-scrollbar,
.sidebar .sidebar-nav::-webkit-scrollbar {
    width: 0;
    height: 0;
}

/* With the bar hidden, the cut-off edge is the only cue that more nav
   exists below, so fade it. app.js adds this class only while there is
   actually more to scroll to, and drops it at the end of the list. */
#sidebar .sidebar-nav.is-scrollable,
.sidebar .sidebar-nav.is-scrollable {
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent 100%);
    mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent 100%);
}

/* The header was 60.8px against a 56px topbar, so the rail's divider sat
   ~5px below the topbar's bottom edge and the two never shared a line.
   Pin it to the same 56px the .ds-topbar declares. */
#sidebar .sidebar-header,
.sidebar .sidebar-header {
    height: 56px;
    min-height: 56px;
    padding-block: 0;
    box-sizing: border-box;
}

/* Collapsed rail header. Previously .logo kept flex:1 while the 32px
   toggle and 12px inline padding took the rest, leaving .logo an 8px box
   that its own 32px brand mark then overflowed -- the cramped, colliding
   top-left corner. A 72px rail cannot seat a touch-sized control and the
   brand mark side by side, so the brand becomes the control: it is
   centred, gets a 40px hit area, and expands the rail on click (wired in
   app.js). The hamburger returns when the sidebar is expanded. */
#sidebar.collapsed.logo-expands .sidebar-header,
.sidebar.collapsed.logo-expands .sidebar-header {
    justify-content: center;
    padding-inline: 0;
    gap: 0;
}

#sidebar.collapsed.logo-expands .sidebar-toggle,
.sidebar.collapsed.logo-expands .sidebar-toggle {
    display: none;
}

#sidebar.collapsed.logo-expands .logo,
.sidebar.collapsed.logo-expands .logo {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    min-width: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--ds-radius-md);
    cursor: pointer;
    transition: background-color var(--ds-motion-hover) var(--ds-ease-standard);
}

:where(.can-hover) #sidebar.collapsed.logo-expands .logo:hover,
:where(.can-hover) .sidebar.collapsed.logo-expands .logo:hover {
    background: rgba(255, 255, 255, 0.12);
}

#sidebar.collapsed.logo-expands .logo:focus-visible,
.sidebar.collapsed.logo-expands .logo:focus-visible {
    outline: 2px solid var(--ds-sidebar-pill);
    outline-offset: 2px;
}

/* index.html ships #sidebarLogo with no src, and app.js sets an inline
   display:none on it when the business has no uploaded logo. But the
   collapsed rule further up forces display:block !important, and an
   !important declaration beats a plain inline style -- so a src-less <img>
   was painted as an empty 32px box next to the '60' mark and overflowed the
   header (scrollWidth 49 in a 40px box). Only force the logo visible when
   there is actually an image to show. */
#sidebar.collapsed .logo #sidebarLogo:not([src]),
.sidebar.collapsed .logo #sidebarLogo:not([src]),
#sidebar.collapsed .logo #sidebarLogo[src=""],
.sidebar.collapsed .logo #sidebarLogo[src=""] {
    display: none !important;
}

/* Tablet: rail + labels — truncate long labels, keep icons centred in rail */
@media (min-width: 1024px) and (max-width: 1599px) {
    #sidebar:not(.collapsed) .nav-item span,
    .sidebar:not(.collapsed) .nav-item span {
        display: block;
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    #sidebar.collapsed .nav-item,
    .sidebar.collapsed .nav-item {
        justify-content: center;
    }
}

/* Large screens: raise density (tighter gutters + table rows).
   Nav items keep the 44px touch floor -- density is padding, not hit size. */
@media (min-width: 1600px) {
    :root {
        --ds-shell-gutter-inline: clamp(16px, 1.25vw, 28px);
        --ds-pad-table-cell-block: var(--ds-space-2);
    }

    #sidebar .nav-item,
    .sidebar .nav-item {
        min-height: var(--ds-touch-target);
        padding-block: var(--ds-space-2);
    }

    .ds-toolbar,
    .toolbar {
        min-height: 36px;
        gap: var(--ds-space-2);
    }

    .ds-table tbody td,
    .data-table tbody td {
        min-height: 48px;
    }
}

/* ================================================================
   UNCONDITIONAL TOUCH TARGETS (44px floor)
   Not gated on any-pointer: a till with a mouse reports fine as the
   primary pointer, so coarse-only rules never reached the touch screen.
   Loaded in design-system (after pos.css) so .pos-order-item .qty-btn wins.
   ================================================================ */

.qty-btn,
.pos-order-item .qty-btn,
.icon-btn,
.modal-close,
.ds-modal-close {
    width: var(--ds-touch-target);
    height: var(--ds-touch-target);
    min-width: var(--ds-touch-target);
    min-height: var(--ds-touch-target);
    box-sizing: border-box;
}

.nav-item,
.ds-nav-item,
#sidebar .nav-item,
.sidebar .nav-item {
    min-height: var(--ds-touch-target);
}

/* ================================================================
   Screen-reader text and the skip-to-content button
   ================================================================ */

.ds-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* If focus lands on the page area itself, no ring round the whole page. */
#pageContent:focus,
#mainContent:focus {
    outline: none;
}
