/* =========================================================
   SMARTBEE APPLICATION DESIGN SYSTEM
   =========================================================

   ONE stylesheet for every authenticated page except the
   packing kiosk. The kiosk (index.html + style.css) is the
   visual REFERENCE and is not touched.

   The token names and values below are taken verbatim from
   wwwroot/style.css so the two are not merely similar - they
   are the same language. If the kiosk palette ever changes,
   these move with it.

   Rules for anyone extending this file:
     - No page-specific styles here, and no design-system
       styles in a page stylesheet. That split is what
       produced five unrelated-looking applications.
     - Every colour comes from a token. A raw hex in a page
       file is a bug.
     - Status is never communicated by colour alone.
   ========================================================= */


/* =========================================================
   LOCAL POPPINS
   Same four local weights the kiosk uses. No web fonts.
   ========================================================= */

@font-face {
    font-family: "Poppins";
    src: url("/assets/fonts/Poppins-Regular.woff2?v=20260823-330r1") format("woff2");
    font-style: normal;
    font-weight: 400;
    font-display: swap;
}

@font-face {
    font-family: "Poppins";
    src: url("/assets/fonts/Poppins-Medium.woff2?v=20260823-330r1") format("woff2");
    font-style: normal;
    font-weight: 500;
    font-display: swap;
}

@font-face {
    font-family: "Poppins";
    src: url("/assets/fonts/Poppins-SemiBold.woff2?v=20260823-330r1") format("woff2");
    font-style: normal;
    font-weight: 600;
    font-display: swap;
}

@font-face {
    font-family: "Poppins";
    src: url("/assets/fonts/Poppins-Bold.woff2?v=20260823-330r1") format("woff2");
    font-style: normal;
    font-weight: 700;
    font-display: swap;
}


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

:root {
    /* Surfaces — from style.css */
    --sb-bg: #f4f7f6;
    --sb-surface: #ffffff;
    --sb-surface-soft: #f8faf9;
    --sb-surface-green: #effbf5;

    --sb-border: #dfe7e3;
    --sb-border-strong: #cbd8d2;

    --sb-text: #17211d;
    --sb-muted: #6f7d77;
    --sb-muted-2: #8b9892;

    --sb-dark: #08251d;
    --sb-dark-hover: #0d3429;

    --sb-green: #00d977;
    --sb-green-brand: #00ff7f;
    --sb-green-deep: #087443;
    --sb-green-soft: rgba(0, 217, 119, 0.10);

    --sb-warning: #a66d00;
    --sb-warning-bg: #fff8e8;
    --sb-warning-text: #5d3d00;
    --sb-danger: #b53b3b;
    --sb-danger-bg: #fff1f1;
    --sb-danger-text: #7d2626;
    --sb-danger-hover-bg: #ffe4e4;
    --sb-info: #0f6d8c;
    --sb-info-bg: #eef8fb;

    /*
     * Border shades that sit on top of the *-bg tokens above (badges,
     * notices, the danger button). Named separately from --sb-border
     * because they need to stay legible against a tinted background,
     * not the plain surface — and because dark mode has to shift them
     * independently of the neutral borders.
     */
    --sb-ok-border: #bce5d0;
    --sb-warn-border: #ead8a6;
    --sb-danger-border: #f1caca;
    --sb-danger-border-strong: #e7bcbc;
    --sb-info-border: #c5e3ec;

    --sb-skeleton-mid: #eef2f0;

    /*
     * Deliberately NOT redefined in the dark theme below.
     *
     * Marketplace/cargo logos (ikas, Trendyol, Aras, …) are
     * third-party SVGs with their own fixed brand colours — some are
     * near-black wordmarks (Trendyol #231f20, n11 #1c1c1e), some are
     * saturated brand colour (ikas lime, Aras red). There is no safe
     * one CSS filter for both: inverting fixes the near-black ones
     * but turns lime green into blue and red into cyan. So instead of
     * recolouring the logos, every place one appears sits on this
     * fixed light chip regardless of theme - the one treatment that
     * keeps all of them legible without touching any brand colour.
     */
    --sb-chip-bg: #f8faf9;
    --sb-chip-border: #dfe7e3;
    --sb-chip-text: #17211d;
    --sb-chip-text-muted: #6f7d77;

    --sb-shadow: 0 8px 28px rgba(4, 42, 34, 0.055);
    --sb-shadow-soft: 0 3px 14px rgba(4, 42, 34, 0.04);
    --sb-shadow-pop: 0 12px 34px rgba(4, 42, 34, 0.14);

    --sb-radius: 14px;
    --sb-radius-sm: 10px;
    --sb-radius-lg: 18px;
    --sb-radius-pill: 999px;

    /* Spacing — 4px base */
    --sb-s1: 4px;
    --sb-s2: 8px;
    --sb-s3: 12px;
    --sb-s4: 16px;
    --sb-s5: 20px;
    --sb-s6: 24px;
    --sb-s8: 32px;
    --sb-s10: 40px;

    /* Control heights — operational density, not marketing */
    --sb-control-h: 40px;
    --sb-control-h-sm: 32px;
    --sb-control-h-lg: 48px;

    --sb-header-h: 72px;
    --sb-content-max: 1560px;

    /* Type scale */
    --sb-fs-xs: 11px;
    --sb-fs-sm: 12.5px;
    --sb-fs-md: 14px;
    --sb-fs-lg: 16px;
    --sb-fs-xl: 20px;
    --sb-fs-2xl: 26px;
    --sb-fs-3xl: 34px;

    --sb-focus: 0 0 0 3px rgba(0, 217, 119, 0.34);
}


/* =========================================================
   DARK MODE

   Every page except the packing kiosk (index.html / style.css /
   app.js, which stay frozen). Applied via `data-theme="dark"` on
   <html> — an attribute rather than a class so the tiny inline
   script each page's <head> runs (before this stylesheet paints)
   only needs one line, with no risk of colliding with a class an
   individual page already uses.

   Same token NAMES as light mode, every consumer below already
   references a token rather than a literal, so nothing outside
   this block needs to know a theme exists. The palette itself is
   not invented for this pass — it is the dark companion this same
   brand green was already paired with in the pre-shared-system
   recordings "replay" UI (bg #0b0d0f / panel #111417 / text
   #f1f3f4), so it is a restoration of an existing pairing rather
   than a new design decision.

   Toggling is per-browser (ui/smartbee-shell.js, localStorage) via
   the header control every page renders. See setTheme() there for
   the forced-remote-theme hook this pairs with.
   ========================================================= */

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

    --sb-bg: #0b0d0f;
    --sb-surface: #15181b;
    --sb-surface-soft: #1b1f22;
    --sb-surface-green: rgba(0, 255, 127, 0.09);

    --sb-border: #272b2f;
    --sb-border-strong: #3a4046;

    --sb-text: #f1f3f4;
    --sb-muted: #9aa3a8;
    --sb-muted-2: #7d868c;

    --sb-dark: #101311;
    --sb-dark-hover: #181c1a;

    --sb-green: #00d977;
    --sb-green-brand: #00ff7f;
    --sb-green-deep: #35e29a;
    --sb-green-soft: rgba(0, 217, 119, 0.16);

    --sb-warning: #e8c374;
    --sb-warning-bg: #3a2f10;
    --sb-warning-text: #f3dca4;
    --sb-danger: #e58c8c;
    --sb-danger-bg: #3a1414;
    --sb-danger-text: #f5b9b9;
    --sb-danger-hover-bg: #4a1a1a;
    --sb-info: #b4beb9;
    --sb-info-bg: #1a1e1c;

    --sb-ok-border: #1f5c3f;
    --sb-warn-border: #5c4a1f;
    --sb-danger-border: #5c2a2a;
    --sb-danger-border-strong: #6e3232;
    --sb-info-border: #343b38;

    --sb-skeleton-mid: #22262a;

    --sb-shadow: 0 8px 28px rgba(0, 0, 0, 0.4);
    --sb-shadow-soft: 0 3px 14px rgba(0, 0, 0, 0.3);
    --sb-shadow-pop: 0 12px 34px rgba(0, 0, 0, 0.5);

    --sb-focus: 0 0 0 3px rgba(0, 217, 119, 0.45);
}

/*
 * body already reads `background: var(--sb-bg)` below, so no
 * separate dark-mode rule is needed for it.
 *
 * The brand mark and toast text are deliberately white regardless of
 * theme (they sit on --sb-dark / --sb-green, not on the page
 * surface) — no override needed. Only things that read the neutral
 * surface/border/text tokens change here, and everything below
 * already does.
 */


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

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

html {
    font-synthesis: none;
    -webkit-text-size-adjust: 100%;
}

body,
button,
input,
select,
textarea {
    font-family: "Poppins", Arial, Helvetica, sans-serif;
}

body {
    margin: 0;
    min-height: 100vh;
    background: var(--sb-bg);
    color: var(--sb-text);
    font-size: var(--sb-fs-md);
    line-height: 1.45;
}

h1, h2, h3, h4 {
    margin: 0;
    font-weight: 600;
    letter-spacing: -0.01em;
}

/*
 * The [hidden] attribute must actually hide.
 *
 * The UA stylesheet implements it as `display: none`, which ANY author
 * `display` declaration outranks - so a component like .sb-notice
 * (display: flex) stayed fully visible while carrying `hidden`. This file
 * uses `hidden` as the standard show/hide mechanism across every page, so
 * the rule is stated once here rather than patched per component.
 */
[hidden] {
    display: none !important;
}

a {
    color: var(--sb-green-deep);
}

/*
 * Visible keyboard focus everywhere. :focus-visible so a mouse
 * click does not paint a ring, but Tab always does.
 */
:focus-visible {
    outline: none;
    box-shadow: var(--sb-focus);
    border-radius: var(--sb-radius-sm);
}

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

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


/* =========================================================
   APPLICATION SHELL

   One header for every page. The session/user control lives
   INSIDE it — see the note on .sb-user below.
   ========================================================= */

.sb-shell {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.sb-header {
    position: sticky;
    top: 0;
    z-index: 40;
    display: flex;
    align-items: center;
    gap: var(--sb-s4);
    height: var(--sb-header-h);
    padding: 0 var(--sb-s4);
    background: var(--sb-surface);
    border-bottom: 1px solid var(--sb-border);
}

.sb-brand {
    display: flex;
    align-items: center;
    gap: var(--sb-s3);
    flex-shrink: 0;
    text-decoration: none;
    color: inherit;
}

/*
 * Logo only - no wordmark, no module label (removed; each page
 * already states its own name in .sb-page-title, so the header no
 * longer repeats it). 29px is ~11% over the previous 26px, since
 * the mark now carries the whole left side of the header on its
 * own. Not applied to index.html - the kiosk header is untouched.
 */
.sb-brand img {
    height: 60px;
    width: auto;
    display: block;
}

/*
 * smartbee-logo.svg has no fill of its own (default SVG black), so
 * on a white header it just works. On a dark surface it would
 * vanish, and there is no CSS `fill` for an <img> reference, so a
 * filter is the only lever: invert(1) turns its solid black into
 * solid white — exact, because the mark is genuinely one colour.
 *
 * This does NOT extend to the marketplace/cargo logo images
 * (.sb-platform img, .platform-logo, .cargo-logo, …) — those are
 * real multi-colour brand marks (ikas lime, Trendyol orange, Aras
 * red, …) and inverting them would erase the exact colour cue this
 * design system otherwise goes out of its way to keep consistent.
 * They already sit on a --sb-surface-soft card in both themes,
 * which is light enough to keep their dark ink legible without
 * recolouring anything.
 */
html[data-theme="dark"] .sb-brand img,
html[data-theme="dark"] .sb-auth-brand img {
    filter: invert(1);
}


/*
 * THEME TOGGLE. Per-browser, instant — see the THEME block in
 * ui/smartbee-shell.js for what it persists and how a future
 * server-forced theme would override it.
 */
.sb-theme-toggle {
    display: grid;
    place-items: center;
    width: var(--sb-control-h-sm);
    height: var(--sb-control-h-sm);
    flex-shrink: 0;
    margin-left: var(--sb-s2);
    padding: 0;
    background: transparent;
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-radius-pill);
    color: var(--sb-muted);
    cursor: pointer;
}

.sb-theme-toggle:hover {
    background: var(--sb-surface-soft);
    color: var(--sb-text);
    border-color: var(--sb-border-strong);
}

.sb-theme-toggle svg {
    display: block;
}

/* Only the icon matching the CURRENT theme is shown. */
.sb-theme-toggle .sb-theme-icon-dark {
    display: none;
}

html[data-theme="dark"] .sb-theme-toggle .sb-theme-icon-light {
    display: none;
}

html[data-theme="dark"] .sb-theme-toggle .sb-theme-icon-dark {
    display: block;
}

/*
 * THE USER MENU.
 *
 * This replaces the fixed .sb-session pill that smartbee-session.js
 * used to inject at top:12px / right:14px / z-index:9999. That
 * element floated above finished pages and read as a debug widget
 * pasted into the corner.
 *
 * It is a normal flex child of the header. It scrolls with the
 * header, participates in tab order in the right place, and its
 * dropdown is anchored to the trigger rather than the viewport.
 */
.sb-user {
    position: relative;
    flex-shrink: 0;
    margin-left: var(--sb-s2);
}

.sb-user-trigger {
    display: flex;
    align-items: center;
    gap: var(--sb-s3);
    height: var(--sb-control-h);
    padding: 0 var(--sb-s2) 0 var(--sb-s2);
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--sb-radius-sm);
    cursor: pointer;
    font: inherit;
    color: inherit;
    text-align: left;
}

.sb-user-trigger:hover {
    background: var(--sb-surface-soft);
    border-color: var(--sb-border);
}

.sb-avatar {
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    border-radius: var(--sb-radius-pill);
    background: var(--sb-dark);
    color: var(--sb-green-brand);
    font-size: var(--sb-fs-xs);
    font-weight: 700;
    letter-spacing: 0.03em;
}

.sb-user-meta {
    display: flex;
    flex-direction: column;
    line-height: 1.2;
}

.sb-user-name {
    font-size: var(--sb-fs-sm);
    font-weight: 600;
}

.sb-user-role {
    font-size: var(--sb-fs-xs);
    color: var(--sb-muted);
}

.sb-user-caret {
    color: var(--sb-muted-2);
    flex-shrink: 0;
}

.sb-user-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    min-width: 220px;
    padding: var(--sb-s2);
    background: var(--sb-surface);
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-radius);
    box-shadow: var(--sb-shadow-pop);
    display: none;
}

.sb-user-menu[data-open="true"] {
    display: block;
}

.sb-user-menu-head {
    padding: var(--sb-s2) var(--sb-s3) var(--sb-s3);
    border-bottom: 1px solid var(--sb-border);
    margin-bottom: var(--sb-s2);
}

.sb-user-menu-head strong {
    display: block;
    font-size: var(--sb-fs-md);
    font-weight: 600;
}

.sb-user-menu-head span {
    font-size: var(--sb-fs-sm);
    color: var(--sb-muted);
}

.sb-user-menu button {
    display: flex;
    align-items: center;
    gap: var(--sb-s2);
    width: 100%;
    height: var(--sb-control-h);
    padding: 0 var(--sb-s3);
    background: transparent;
    border: 0;
    border-radius: var(--sb-radius-sm);
    font: inherit;
    font-size: var(--sb-fs-md);
    color: var(--sb-danger);
    cursor: pointer;
    text-align: left;
}

.sb-user-menu button:hover {
    background: var(--sb-danger-bg);
}

.sb-main {
    flex: 1;
    width: 100%;
    max-width: var(--sb-content-max);
    margin: 0 auto;
    padding: var(--sb-s4) var(--sb-s4) var(--sb-s8);
}

.sb-page-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--sb-s4);
    flex-wrap: wrap;
    margin-bottom: var(--sb-s5);
}

.sb-page-title {
    font-size: var(--sb-fs-2xl);
    font-weight: 700;
    letter-spacing: -0.02em;
}

.sb-page-sub {
    margin-top: 2px;
    font-size: var(--sb-fs-md);
    color: var(--sb-muted);
}

.sb-footer {
    padding: var(--sb-s5);
    text-align: center;
    font-size: var(--sb-fs-sm);
    color: var(--sb-muted-2);
}


/* =========================================================
   SECONDARY (CONTEXTUAL) NAVIGATION
   Admin has many sections; they live inside this shell rather
   than in a separate application-looking sidebar.
   ========================================================= */

.sb-subnav {
    display: flex;
    gap: var(--sb-s1);
    padding: var(--sb-s1);
    margin-bottom: var(--sb-s5);
    background: var(--sb-surface);
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-radius);
    overflow-x: auto;
    scrollbar-width: thin;
}

.sb-subnav button {
    flex-shrink: 0;
    height: var(--sb-control-h-sm);
    padding: 0 var(--sb-s4);
    background: transparent;
    border: 0;
    border-radius: var(--sb-radius-sm);
    font: inherit;
    font-size: var(--sb-fs-md);
    font-weight: 500;
    color: var(--sb-muted);
    cursor: pointer;
    white-space: nowrap;
}

.sb-subnav button:hover {
    background: var(--sb-surface-soft);
    color: var(--sb-text);
}

.sb-subnav button[aria-selected="true"] {
    background: var(--sb-dark);
    color: #ffffff;
    font-weight: 600;
}


/* =========================================================
   SURFACES
   ========================================================= */

.sb-card {
    background: var(--sb-surface);
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-radius);
    box-shadow: var(--sb-shadow-soft);
}

.sb-card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sb-s3);
    padding: var(--sb-s4) var(--sb-s5);
    border-bottom: 1px solid var(--sb-border);
}

.sb-card-title {
    font-size: var(--sb-fs-lg);
    font-weight: 600;
}

.sb-card-sub {
    font-size: var(--sb-fs-sm);
    color: var(--sb-muted);
    font-weight: 400;
}

.sb-card-body {
    padding: var(--sb-s5);
}

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

.sb-grid {
    display: grid;
    gap: var(--sb-s4);
}

.sb-grid--kpi   { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.sb-grid--metric{ grid-template-columns: repeat(auto-fit, minmax(168px, 1fr)); }
.sb-grid--2     { grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); }

.sb-section {
    margin-bottom: var(--sb-s6);
}

.sb-section-title {
    display: flex;
    align-items: baseline;
    gap: var(--sb-s3);
    margin-bottom: var(--sb-s3);
    font-size: var(--sb-fs-lg);
    font-weight: 600;
}

.sb-section-title small {
    font-size: var(--sb-fs-sm);
    font-weight: 400;
    color: var(--sb-muted);
}


/* =========================================================
   KPI / STAT TILES

   Deliberately two weights. Putting every number in an
   equally loud card is what made the old dashboard
   unreadable — nothing was primary, so nothing stood out.
   ========================================================= */

.sb-kpi {
    padding: var(--sb-s5);
    background: var(--sb-surface);
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-radius);
    box-shadow: var(--sb-shadow-soft);
}

.sb-kpi-label {
    font-size: var(--sb-fs-sm);
    font-weight: 500;
    color: var(--sb-muted);
}

.sb-kpi-value {
    margin-top: var(--sb-s2);
    font-size: var(--sb-fs-3xl);
    font-weight: 700;
    letter-spacing: -0.03em;
    font-variant-numeric: tabular-nums;
}

.sb-kpi-foot {
    margin-top: var(--sb-s2);
    display: flex;
    align-items: center;
    gap: var(--sb-s2);
    font-size: var(--sb-fs-sm);
    color: var(--sb-muted);
}

/* Secondary metric — compact, quieter. */
.sb-metric {
    padding: var(--sb-s4);
    background: var(--sb-surface);
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-radius-sm);
}

.sb-metric-label {
    font-size: var(--sb-fs-xs);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--sb-muted-2);
}

.sb-metric-value {
    margin-top: var(--sb-s1);
    font-size: var(--sb-fs-xl);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.sb-delta {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: var(--sb-fs-sm);
    font-weight: 600;
}

.sb-delta--up   { color: var(--sb-green-deep); }
.sb-delta--down { color: var(--sb-danger); }
.sb-delta--flat { color: var(--sb-muted); }


/* =========================================================
   LIVE OPERATIONS

   Visually distinct from the period-filtered analytics above
   it, because it is NOT affected by the date filter. Making
   that difference visible is the point — the two numbers get
   confused precisely when they look alike.
   ========================================================= */

.sb-live {
    background:
        linear-gradient(180deg, var(--sb-surface-green), var(--sb-surface));
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-radius);
    box-shadow: var(--sb-shadow-soft);
    padding: var(--sb-s5);
}

.sb-live-head {
    display: flex;
    align-items: center;
    gap: var(--sb-s3);
    flex-wrap: wrap;
    margin-bottom: var(--sb-s4);
}

.sb-live-title {
    font-size: var(--sb-fs-sm);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--sb-green-deep);
}

.sb-live-total {
    font-size: var(--sb-fs-3xl);
    font-weight: 700;
    letter-spacing: -0.03em;
    font-variant-numeric: tabular-nums;
}

.sb-live-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: var(--sb-s3);
}

.sb-live-item {
    display: flex;
    align-items: center;
    gap: var(--sb-s3);
    padding: var(--sb-s3);
    background: var(--sb-surface);
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-radius-sm);
}

.sb-live-item img {
    width: 20px;
    height: 20px;
    object-fit: contain;
    flex-shrink: 0;
    /* Fixed light chip — see --sb-chip-bg above. */
    padding: 2px;
    border-radius: 5px;
    background: var(--sb-chip-bg);
    border: 1px solid var(--sb-chip-border);
    box-sizing: content-box;
}

.sb-live-item-name {
    font-size: var(--sb-fs-sm);
    color: var(--sb-muted);
}

.sb-live-item-count {
    margin-left: auto;
    font-size: var(--sb-fs-lg);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}


/* =========================================================
   BUTTONS
   One button system. Previously each page had its own.
   ========================================================= */

.sb-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sb-s2);
    height: var(--sb-control-h);
    padding: 0 var(--sb-s4);
    border: 1px solid var(--sb-border-strong);
    border-radius: var(--sb-radius-sm);
    background: var(--sb-surface);
    color: var(--sb-text);
    font: inherit;
    font-size: var(--sb-fs-md);
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
    text-decoration: none;
    transition: background 0.12s ease, border-color 0.12s ease;
}

.sb-btn:hover:not(:disabled) {
    background: var(--sb-surface-soft);
    border-color: var(--sb-muted-2);
}

.sb-btn:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

.sb-btn--primary {
    background: var(--sb-dark);
    border-color: var(--sb-dark);
    color: #ffffff;
    font-weight: 600;
}

.sb-btn--primary:hover:not(:disabled) {
    background: var(--sb-dark-hover);
    border-color: var(--sb-dark-hover);
}

.sb-btn--accent {
    background: var(--sb-green);
    border-color: var(--sb-green);
    color: var(--sb-dark);
    font-weight: 600;
}

/* Destructive actions are visually distinct, never just red text. */
.sb-btn--danger {
    background: var(--sb-danger-bg);
    border-color: var(--sb-danger-border-strong);
    color: var(--sb-danger);
    font-weight: 600;
}

.sb-btn--danger:hover:not(:disabled) {
    background: var(--sb-danger-hover-bg);
}

.sb-btn--ghost {
    background: transparent;
    border-color: transparent;
    color: var(--sb-muted);
}

.sb-btn--ghost:hover:not(:disabled) {
    background: var(--sb-surface-soft);
    color: var(--sb-text);
}

.sb-btn--sm { height: var(--sb-control-h-sm); padding: 0 var(--sb-s3); font-size: var(--sb-fs-sm); }
.sb-btn--lg { height: var(--sb-control-h-lg); padding: 0 var(--sb-s6); font-size: var(--sb-fs-lg); }
.sb-btn--block { width: 100%; }

.sb-btn-row {
    display: flex;
    gap: var(--sb-s2);
    flex-wrap: wrap;
}

.sb-btn-row--center {
    align-items: center;
}


/* =========================================================
   SEGMENTED CONTROL (period / filter switches)
   ========================================================= */

.sb-segment {
    display: inline-flex;
    padding: 3px;
    background: var(--sb-surface-soft);
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-radius-sm);
    gap: 2px;
}

.sb-segment button {
    height: 30px;
    padding: 0 var(--sb-s3);
    border: 0;
    border-radius: 7px;
    background: transparent;
    font: inherit;
    font-size: var(--sb-fs-sm);
    font-weight: 500;
    color: var(--sb-muted);
    cursor: pointer;
    white-space: nowrap;
}

.sb-segment button[aria-pressed="true"] {
    background: var(--sb-surface);
    color: var(--sb-text);
    font-weight: 600;
    box-shadow: var(--sb-shadow-soft);
}


/* =========================================================
   FORMS
   ========================================================= */

.sb-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: var(--sb-s4);
}

.sb-label {
    font-size: var(--sb-fs-sm);
    font-weight: 500;
    color: var(--sb-text);
}

.sb-hint {
    font-size: var(--sb-fs-sm);
    color: var(--sb-muted);
}

.sb-input,
.sb-select,
.sb-textarea {
    width: 100%;
    height: var(--sb-control-h);
    padding: 0 var(--sb-s3);
    background: var(--sb-surface);
    border: 1px solid var(--sb-border-strong);
    border-radius: var(--sb-radius-sm);
    font: inherit;
    font-size: var(--sb-fs-md);
    color: var(--sb-text);
}

.sb-textarea {
    height: auto;
    min-height: 90px;
    padding: var(--sb-s3);
    resize: vertical;
}

.sb-input:focus,
.sb-select:focus,
.sb-textarea:focus {
    outline: none;
    border-color: var(--sb-green);
    box-shadow: var(--sb-focus);
}

.sb-input[aria-invalid="true"] {
    border-color: var(--sb-danger);
}

.sb-field-error {
    font-size: var(--sb-fs-sm);
    color: var(--sb-danger);
    font-weight: 500;
}

.sb-switch {
    display: inline-flex;
    align-items: center;
    gap: var(--sb-s3);
    cursor: pointer;
}

.sb-form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 0 var(--sb-s5);
}

.sb-fieldset {
    border: 0;
    padding: 0;
    margin: 0 0 var(--sb-s6);
}

.sb-fieldset legend {
    padding: 0;
    margin-bottom: var(--sb-s3);
    font-size: var(--sb-fs-md);
    font-weight: 600;
}


/* =========================================================
   TABLES

   Horizontally scrollable at narrow widths rather than
   crushed. Where a card layout is genuinely more usable,
   pages opt in with .sb-table--stack.
   ========================================================= */

.sb-table-wrap {
    width: 100%;
    overflow-x: auto;
    scrollbar-width: thin;
}

.sb-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--sb-fs-md);
}

.sb-table th {
    padding: var(--sb-s3) var(--sb-s4);
    text-align: left;
    font-size: var(--sb-fs-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--sb-muted-2);
    background: var(--sb-surface-soft);
    border-bottom: 1px solid var(--sb-border);
    white-space: nowrap;
}

.sb-table td {
    padding: var(--sb-s3) var(--sb-s4);
    border-bottom: 1px solid var(--sb-border);
    vertical-align: middle;
}

.sb-table tbody tr:last-child td {
    border-bottom: 0;
}

.sb-table tbody tr:hover td {
    background: var(--sb-surface-soft);
}

.sb-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.sb-product-cell {
    display: flex;
    align-items: center;
    gap: var(--sb-s3);
    min-width: 0;
}

.sb-thumb {
    width: 36px;
    height: 36px;
    flex-shrink: 0;
    object-fit: cover;
    background: var(--sb-surface-soft);
    border: 1px solid var(--sb-border);
    border-radius: 8px;
}

/*
 * Placeholder for a product with no VERIFIED canonical row.
 * Deliberately not a guessed image: the wrong product photo is
 * worse than no photo.
 */
.sb-thumb--empty {
    display: grid;
    place-items: center;
    color: var(--sb-muted-2);
    font-size: var(--sb-fs-xs);
    font-weight: 600;
}

.sb-cell-title {
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sb-cell-sub {
    font-size: var(--sb-fs-sm);
    color: var(--sb-muted);
}


/* =========================================================
   BADGES / STATUS

   Every status carries a text label, so colour is never the
   only channel.
   ========================================================= */

.sb-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 22px;
    padding: 0 var(--sb-s2);
    border-radius: var(--sb-radius-pill);
    font-size: var(--sb-fs-xs);
    font-weight: 600;
    background: var(--sb-surface-soft);
    color: var(--sb-muted);
    border: 1px solid var(--sb-border);
    white-space: nowrap;
}

.sb-badge--ok      { background: var(--sb-surface-green); color: var(--sb-green-deep); border-color: var(--sb-ok-border); }
.sb-badge--warn    { background: var(--sb-warning-bg);    color: var(--sb-warning);    border-color: var(--sb-warn-border); }
.sb-badge--danger  { background: var(--sb-danger-bg);     color: var(--sb-danger);     border-color: var(--sb-danger-border); }
.sb-badge--info    { background: var(--sb-info-bg);       color: var(--sb-info);       border-color: var(--sb-info-border); }

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

.sb-platform {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: var(--sb-fs-md);
}

/* One logo path and one size for a platform, on every page. */
.sb-platform img {
    width: 18px;
    height: 18px;
    object-fit: contain;
    flex-shrink: 0;
    /* Fixed light chip — see --sb-chip-bg above. */
    padding: 2px;
    border-radius: 5px;
    background: var(--sb-chip-bg);
    border: 1px solid var(--sb-chip-border);
    box-sizing: content-box;
}


/* =========================================================
   SHARED UI STATES
   One implementation each — not one per page.
   ========================================================= */

.sb-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--sb-s3);
    padding: var(--sb-s10) var(--sb-s5);
    text-align: center;
    color: var(--sb-muted);
}

.sb-state-title {
    font-size: var(--sb-fs-lg);
    font-weight: 600;
    color: var(--sb-text);
}

.sb-state-text {
    font-size: var(--sb-fs-md);
    max-width: 46ch;
}

.sb-spinner {
    width: 22px;
    height: 22px;
    border: 2.5px solid var(--sb-border-strong);
    border-top-color: var(--sb-green);
    border-radius: 50%;
    animation: sb-spin 0.7s linear infinite;
}

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

.sb-skeleton {
    background: linear-gradient(
        90deg,
        var(--sb-surface-soft) 25%,
        var(--sb-skeleton-mid) 37%,
        var(--sb-surface-soft) 63%
    );
    background-size: 400% 100%;
    animation: sb-shimmer 1.3s ease infinite;
    border-radius: var(--sb-radius-sm);
}

@keyframes sb-shimmer {
    0%   { background-position: 100% 50%; }
    100% { background-position: 0 50%; }
}

.sb-notice {
    display: flex;
    align-items: flex-start;
    gap: var(--sb-s3);
    padding: var(--sb-s3) var(--sb-s4);
    border-radius: var(--sb-radius-sm);
    font-size: var(--sb-fs-md);
    border: 1px solid var(--sb-border);
    background: var(--sb-surface-soft);
    color: var(--sb-text);
}

.sb-notice--ok     { background: var(--sb-surface-green); border-color: var(--sb-ok-border); }
.sb-notice--warn   { background: var(--sb-warning-bg);    border-color: var(--sb-warn-border); color: var(--sb-warning-text); }
.sb-notice--danger { background: var(--sb-danger-bg);     border-color: var(--sb-danger-border); color: var(--sb-danger-text); }
.sb-notice--info   { background: var(--sb-info-bg);       border-color: var(--sb-info-border); }

.sb-notice-title {
    font-weight: 600;
    display: block;
    margin-bottom: 2px;
}

/* Toast — transient feedback, one implementation. */
.sb-toasts {
    position: fixed;
    right: var(--sb-s5);
    bottom: var(--sb-s5);
    z-index: 90;
    display: flex;
    flex-direction: column;
    gap: var(--sb-s2);
    pointer-events: none;
}

.sb-toast {
    min-width: 240px;
    max-width: 380px;
    padding: var(--sb-s3) var(--sb-s4);
    background: var(--sb-dark);
    color: #ffffff;
    border-radius: var(--sb-radius-sm);
    box-shadow: var(--sb-shadow-pop);
    font-size: var(--sb-fs-md);
    pointer-events: auto;
}

.sb-toast--ok     { background: var(--sb-green-deep); }
.sb-toast--danger { background: var(--sb-danger); }

/* Confirmation dialog */
.sb-dialog {
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-radius);
    box-shadow: var(--sb-shadow-pop);
    padding: 0;
    max-width: 460px;
    width: calc(100vw - 32px);
    background: var(--sb-surface);
    color: var(--sb-text);
}

.sb-dialog::backdrop {
    background: rgba(8, 37, 29, 0.42);
}

.sb-dialog-body { padding: var(--sb-s5); }

.sb-dialog-foot {
    display: flex;
    justify-content: flex-end;
    gap: var(--sb-s2);
    padding: var(--sb-s4) var(--sb-s5);
    border-top: 1px solid var(--sb-border);
    background: var(--sb-surface-soft);
    border-radius: 0 0 var(--sb-radius) var(--sb-radius);
}


/* =========================================================
   AUTH PAGE (login / forced password change)
   ========================================================= */

.sb-auth {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: var(--sb-s5);
    background: var(--sb-bg);
}

.sb-auth-card {
    width: 100%;
    max-width: 392px;
    padding: var(--sb-s8);
    background: var(--sb-surface);
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-radius-lg);
    box-shadow: var(--sb-shadow);
}

.sb-auth-brand {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sb-s3);
    margin-bottom: var(--sb-s6);
    text-align: center;
}

.sb-auth-brand img { height: 34px; width: auto; }

.sb-auth-title {
    font-size: var(--sb-fs-xl);
    font-weight: 700;
    letter-spacing: -0.02em;
}

.sb-auth-sub {
    font-size: var(--sb-fs-md);
    color: var(--sb-muted);
}


/* =========================================================
   RESPONSIVE

   Layouts change shape rather than merely shrinking.
   ========================================================= */

@media (max-width: 1080px) {
    :root { --sb-content-max: 100%; }
}

@media (max-width: 860px) {
    .sb-header {
        height: auto;
        flex-wrap: wrap;
        padding: var(--sb-s3) var(--sb-s4);
        gap: var(--sb-s3);
    }

    /*
     * Navigation collapses to a scrollable row on its own line.
     * The account control stays part of navigation and never
     * becomes a floating badge.
     */
    .sb-nav {
        order: 3;
        width: 100%;
        margin-left: 0;
        overflow-x: auto;
        scrollbar-width: none;
        padding-bottom: 2px;
    }

    .sb-nav::-webkit-scrollbar { display: none; }

    .sb-user { margin-left: auto; }

    /* The name collapses to the avatar; the role stays in the menu. */
    .sb-user-meta { display: none; }

    .sb-main { padding: var(--sb-s3) var(--sb-s3) var(--sb-s6); }

    .sb-kpi        { padding: var(--sb-s4); }

    .sb-grid--kpi    { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .sb-grid--metric { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .sb-grid--2      { grid-template-columns: minmax(0, 1fr); }

    .sb-toasts { left: var(--sb-s4); right: var(--sb-s4); bottom: var(--sb-s4); }
    .sb-toast  { max-width: none; }
}

@media (max-width: 560px) {
    .sb-grid--kpi { grid-template-columns: minmax(0, 1fr); }

    /* Touch-friendly targets. */
    .sb-btn        { height: 44px; }
    .sb-btn--sm    { height: 36px; }
    .sb-input,
    .sb-select     { height: 44px; }

    .sb-auth-card  { padding: var(--sb-s5); }

    /*
     * Opt-in card layout for tables whose rows read better
     * stacked than scrolled sideways on a phone.
     */
    .sb-table--stack thead { display: none; }

    .sb-table--stack tbody tr {
        display: block;
        padding: var(--sb-s3) 0;
        border-bottom: 1px solid var(--sb-border);
    }

    .sb-table--stack td {
        display: flex;
        justify-content: space-between;
        gap: var(--sb-s4);
        padding: 3px var(--sb-s4);
        border: 0;
        text-align: right;
    }

    .sb-table--stack td::before {
        content: attr(data-label);
        font-size: var(--sb-fs-xs);
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.05em;
        color: var(--sb-muted-2);
        text-align: left;
    }
}

@media print {
    .sb-header, .sb-subnav, .sb-toasts { display: none; }
}

/* =========================================================
   v3.1.0-r2.1 — RETAIL-ALIGNED MANAGEMENT HEADER

   Desktop keeps the compact back-office density, but the SmartBee wordmark
   now has the same visual presence as the retail storefront. On phones the
   header is a true three-zone bar: hamburger / centred logo / account.
   ========================================================= */
.sb-nav {
    display: flex;
    align-items: center;
    gap: var(--sb-s1);
}

.sb-nav > a,
.sb-nav-dropdown-trigger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: var(--sb-control-h-sm);
    padding: 0 var(--sb-s3);
    border: 0;
    border-radius: var(--sb-radius-sm);
    background: transparent;
    font: inherit;
    font-size: var(--sb-fs-md);
    font-weight: 500;
    color: var(--sb-muted);
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
}

.sb-nav > a:hover,
.sb-nav-dropdown-trigger:hover {
    background: var(--sb-surface-soft);
    color: var(--sb-text);
}

.sb-nav > a[aria-current="page"],
.sb-nav-dropdown-trigger[aria-current="page"] {
    background: var(--sb-surface-green);
    color: var(--sb-green-deep);
    font-weight: 600;
}

.sb-nav-dropdown {
    position: relative;
    flex-shrink: 0;
}

.sb-nav-dropdown-trigger svg {
    flex-shrink: 0;
    transition: transform 140ms ease;
}

.sb-nav-dropdown[data-open="true"] .sb-nav-dropdown-trigger svg {
    transform: rotate(180deg);
}

.sb-nav-dropdown-menu {
    display: none;
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    z-index: 60;
    width: 310px;
    max-height: min(72vh, 620px);
    overflow-y: auto;
    padding: var(--sb-s3);
    background: var(--sb-surface);
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-radius);
    box-shadow: var(--sb-shadow-pop);
}

.sb-nav-dropdown[data-open="true"] .sb-nav-dropdown-menu { display: grid; }

.sb-nav-dropdown-group {
    display: grid;
    gap: 2px;
    padding: var(--sb-s2) 0;
    border-bottom: 1px solid var(--sb-border);
}

.sb-nav-dropdown-group:first-child { padding-top: 0; }
.sb-nav-dropdown-group:last-child { padding-bottom: 0; border-bottom: 0; }

.sb-nav-dropdown-group > span {
    padding: 0 var(--sb-s2) 4px;
    color: var(--sb-muted-2);
    font-size: var(--sb-fs-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .06em;
}

.sb-nav-dropdown-group a {
    display: flex;
    align-items: center;
    min-height: 36px;
    padding: 0 var(--sb-s2);
    border-radius: var(--sb-radius-sm);
    color: var(--sb-text);
    font-size: var(--sb-fs-md);
    font-weight: 500;
    text-decoration: none;
}

.sb-nav-dropdown-group a:hover {
    background: var(--sb-surface-green);
    color: var(--sb-green-deep);
}

.sb-header-menu {
    display: flex;
    align-items: center;
    gap: var(--sb-s2);
    margin-left: auto;
    min-width: 0;
}

.sb-header-menu .sb-nav { margin-left: 0; }
.sb-mobile-menu-toggle { display: none; }

/* The account stays outside the collapsible navigation so it remains visible
   at the right edge of the mobile retail-style header. */
.sb-header > .sb-user { margin-left: var(--sb-s1); }

@media (max-width: 1180px) and (min-width: 861px) {
    .sb-nav > a,
    .sb-nav-dropdown-trigger { padding-inline: var(--sb-s2); }
    .sb-user-meta { display: none; }
    .sb-user-caret { display: none; }
}

@media (max-width: 860px) {
    .sb-header {
        display: grid;
        grid-template-columns: 44px minmax(0, 1fr) 44px;
        align-items: center;
        height: 58px;
        min-height: 58px;
        padding: 0 8px;
        gap: 4px;
    }

    .sb-mobile-menu-toggle {
        display: grid;
        grid-column: 1;
        grid-row: 1;
        place-items: center;
        width: 44px;
        height: 44px;
        margin: 0;
        padding: 0;
        border: 0;
        border-radius: var(--sb-radius-sm);
        background: transparent;
        color: var(--sb-text);
        cursor: pointer;
    }

    .sb-mobile-menu-toggle:hover { background: var(--sb-surface-soft); }

    .sb-brand {
        grid-column: 2;
        grid-row: 1;
        justify-self: center;
        min-width: 0;
    }

    .sb-brand img {
        height: 45px;
        width: auto;
    }

    .sb-header > .sb-user {
        grid-column: 3;
        grid-row: 1;
        justify-self: end;
        margin: 0;
        width: 44px;
    }

    .sb-header > .sb-user .sb-user-trigger {
        width: 44px;
        height: 44px;
        justify-content: center;
        padding: 0;
        border: 0;
    }

    .sb-header > .sb-user .sb-avatar {
        width: 32px;
        height: 32px;
    }

    .sb-header > .sb-user .sb-user-meta,
    .sb-header > .sb-user .sb-user-caret { display: none; }

    .sb-header > .sb-user .sb-user-menu {
        position: fixed;
        top: 54px;
        right: 8px;
        width: min(260px, calc(100vw - 16px));
    }

    .sb-header-menu {
        display: none;
        position: absolute;
        top: calc(100% + 1px);
        left: 8px;
        right: 8px;
        z-index: 55;
        margin-left: 0;
        padding: var(--sb-s3);
        align-items: stretch;
        flex-direction: column;
        gap: var(--sb-s2);
        background: var(--sb-surface);
        border: 1px solid var(--sb-border);
        border-radius: 0 0 var(--sb-radius) var(--sb-radius);
        box-shadow: var(--sb-shadow-pop);
        max-height: calc(100vh - 74px);
        overflow-y: auto;
    }

    .sb-header-menu[data-open="true"] { display: flex; }

    .sb-header-menu .sb-nav {
        display: grid;
        order: 0;
        width: 100%;
        overflow: visible;
        padding: 0;
        gap: 2px;
    }

    .sb-header-menu .sb-nav > a,
    .sb-header-menu .sb-nav-dropdown-trigger {
        width: 100%;
        min-height: 42px;
        height: 42px;
        justify-content: flex-start;
        padding: 0 var(--sb-s3);
    }

    .sb-nav-dropdown { width: 100%; }
    .sb-nav-dropdown-trigger svg { margin-left: auto; }

    .sb-nav-dropdown-menu {
        position: static;
        width: 100%;
        max-height: none;
        margin-top: 3px;
        padding: var(--sb-s2) var(--sb-s2) var(--sb-s2) var(--sb-s4);
        border: 0;
        border-left: 2px solid var(--sb-border-strong);
        border-radius: 0;
        box-shadow: none;
        background: var(--sb-surface-soft);
    }

    .sb-nav-dropdown-group { padding: var(--sb-s1) 0; }
    .sb-nav-dropdown-group a { min-height: 38px; }

    .sb-header-menu .sb-theme-toggle {
        order: 1;
        width: 100%;
        height: 42px;
        margin: 0;
        border-radius: var(--sb-radius-sm);
    }
}


/* =========================================================
   v3.1.0-r2.2 — GLOBAL PLAINADMIN-STYLE APPLICATION SIDEBAR

   The management surface now uses one navigation model everywhere:
   a fixed left rail on desktop and the same rail as an off-canvas
   drawer on mobile/tablet. The previous horizontal header navigation
   is intentionally retired. SmartBee colours, type scale and control
   sizing remain authoritative; only the information architecture and
   responsive composition borrow the proven PlainAdmin pattern.
   ========================================================= */
:root {
    --sb-header-h: 56px;
    --sb-sidebar-w: 252px;
    --sb-sidebar-head-h: 74px;
}

.sb-shell {
    display: block;
    min-height: 100vh;
}

.sb-sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 60;
    display: flex;
    flex-direction: column;
    width: var(--sb-sidebar-w);
    height: 100vh;
    background: var(--sb-surface);
    border-right: 1px solid var(--sb-border);
    box-shadow: 4px 0 18px rgba(4, 42, 34, .025);
}

html[data-theme="dark"] .sb-sidebar {
    box-shadow: 6px 0 24px rgba(0, 0, 0, .16);
}

.sb-sidebar-head {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: var(--sb-sidebar-head-h);
    padding: 6px var(--sb-s4);
    border-bottom: 1px solid var(--sb-border);
}

.sb-sidebar-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
    text-decoration: none;
}

.sb-sidebar-brand img {
    display: block;
    width: auto;
    height: 60px;
    max-width: 100%;
}

html[data-theme="dark"] .sb-sidebar-brand img {
    filter: invert(1);
}

.sb-sidebar-close {
    display: none;
    place-items: center;
    width: 40px;
    height: 40px;
    margin-left: auto;
    padding: 0;
    border: 0;
    border-radius: var(--sb-radius-sm);
    background: transparent;
    color: var(--sb-muted);
    cursor: pointer;
}

.sb-sidebar-close:hover {
    background: var(--sb-surface-soft);
    color: var(--sb-text);
}

.sb-sidebar-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: var(--sb-s4) var(--sb-s3);
    scrollbar-width: thin;
}

.sb-sidebar-nav,
.sb-sidebar-group,
.sb-sidebar-settings,
.sb-sidebar-submenu,
.sb-sidebar-sub-group {
    display: grid;
}

.sb-sidebar-nav { gap: var(--sb-s4); }
.sb-sidebar-group { gap: 3px; }

.sb-sidebar-group-label {
    min-height: 22px;
    padding: 2px var(--sb-s3) 4px;
    color: var(--sb-muted-2);
    font-size: var(--sb-fs-xs);
    font-weight: 700;
    letter-spacing: .075em;
    text-transform: uppercase;
}

.sb-sidebar-link,
.sb-sidebar-theme {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--sb-s3);
    width: 100%;
    min-height: 42px;
    padding: 0 var(--sb-s3);
    border: 0;
    border-radius: var(--sb-radius-sm);
    background: transparent;
    color: var(--sb-muted);
    font: inherit;
    font-size: var(--sb-fs-md);
    font-weight: 550;
    line-height: 1.25;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}

.sb-sidebar-link:hover,
.sb-sidebar-theme:hover {
    background: var(--sb-surface-soft);
    color: var(--sb-text);
}

.sb-sidebar-link[aria-current="page"],
.sb-sidebar-settings-trigger[aria-current="page"] {
    background: var(--sb-surface-green);
    color: var(--sb-text);
    font-weight: 650;
}

.sb-sidebar-link[aria-current="page"]::before,
.sb-sidebar-settings-trigger[aria-current="page"]::before {
    content: "";
    position: absolute;
    top: 8px;
    bottom: 8px;
    left: 0;
    width: 3px;
    border-radius: 0 999px 999px 0;
    background: var(--sb-green);
}

.sb-sidebar-link-icon {
    display: grid;
    place-items: center;
    width: 21px;
    height: 21px;
    flex: 0 0 21px;
    color: var(--sb-muted-2);
}

.sb-sidebar-link-icon svg {
    display: block;
    width: 19px;
    height: 19px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.sb-sidebar-link[aria-current="page"] .sb-sidebar-link-icon,
.sb-sidebar-settings-trigger[aria-current="page"] .sb-sidebar-link-icon {
    color: var(--sb-green-deep);
}

.sb-sidebar-caret {
    width: 10px;
    height: 10px;
    margin-left: auto;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
    transition: transform 140ms ease;
}

.sb-sidebar-settings[data-open="true"] .sb-sidebar-caret {
    transform: rotate(180deg);
}

.sb-sidebar-submenu {
    display: none;
    gap: var(--sb-s2);
    margin: 4px 0 2px 31px;
    padding: var(--sb-s2) 0 var(--sb-s1) var(--sb-s3);
    border-left: 1px solid var(--sb-border-strong);
}

.sb-sidebar-settings[data-open="true"] .sb-sidebar-submenu { display: grid; }

.sb-sidebar-sub-group { gap: 2px; }

.sb-sidebar-sub-group + .sb-sidebar-sub-group {
    margin-top: var(--sb-s1);
    padding-top: var(--sb-s2);
    border-top: 1px solid var(--sb-border);
}

.sb-sidebar-sub-group > span {
    padding: 0 var(--sb-s2) 3px;
    color: var(--sb-muted-2);
    font-size: var(--sb-fs-xs);
    font-weight: 700;
    letter-spacing: .055em;
    text-transform: uppercase;
}

.sb-sidebar-sub-link {
    display: flex;
    align-items: center;
    min-height: 36px;
    padding: 0 var(--sb-s2);
    border-radius: 8px;
    color: var(--sb-muted);
    font-size: var(--sb-fs-md);
    font-weight: 500;
    line-height: 1.25;
    text-decoration: none;
}

.sb-sidebar-sub-link:hover {
    background: var(--sb-surface-soft);
    color: var(--sb-text);
}

.sb-sidebar-sub-link[aria-current="page"] {
    background: var(--sb-surface-green);
    color: var(--sb-green-deep);
    font-weight: 650;
}

.sb-sidebar-foot {
    flex: 0 0 auto;
    padding: var(--sb-s3);
    border-top: 1px solid var(--sb-border);
    background: var(--sb-surface);
}

.sb-sidebar-theme .sb-theme-icon-light,
.sb-sidebar-theme .sb-theme-icon-dark {
    width: 18px;
    height: 18px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
}

.sb-sidebar-theme .sb-theme-icon-dark { display: none; fill: currentColor; stroke: none; }
html[data-theme="dark"] .sb-sidebar-theme .sb-theme-icon-light { display: none; }
html[data-theme="dark"] .sb-sidebar-theme .sb-theme-icon-dark { display: block; }

.sb-sidebar-overlay {
    display: none;
}

/* Compact application header: sidebar owns navigation on desktop. */
.sb-header {
    position: sticky;
    top: 0;
    z-index: 40;
    display: flex;
    align-items: center;
    width: calc(100% - var(--sb-sidebar-w));
    height: var(--sb-header-h);
    min-height: var(--sb-header-h);
    margin-left: var(--sb-sidebar-w);
    padding: 0 var(--sb-s5);
    gap: var(--sb-s3);
    background: color-mix(in srgb, var(--sb-surface) 96%, transparent);
    border-bottom: 1px solid var(--sb-border);
    backdrop-filter: blur(10px);
}

.sb-header-brand { display: none; }
.sb-mobile-menu-toggle { display: none; }

.sb-header-context {
    min-width: 0;
    overflow: hidden;
    color: var(--sb-muted);
    font-size: var(--sb-fs-md);
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sb-header > .sb-user {
    margin-left: auto;
}

/* Main canvas uses the entire space left by the fixed rail. */
.sb-main {
    width: calc(100% - var(--sb-sidebar-w));
    max-width: none;
    margin: 0 0 0 var(--sb-sidebar-w);
    padding: var(--sb-s4) var(--sb-s5) var(--sb-s8);
}

.sb-footer {
    width: calc(100% - var(--sb-sidebar-w));
    margin-left: var(--sb-sidebar-w);
}

@media (max-width: 1024px) {
    :root {
        --sb-header-h: 58px;
    }

    .sb-sidebar {
        z-index: 80;
        width: min(286px, calc(100vw - 42px));
        transform: translateX(-102%);
        transition: transform 180ms ease;
        box-shadow: 18px 0 44px rgba(0, 0, 0, .18);
    }

    .sb-sidebar[data-open="true"] { transform: translateX(0); }

    .sb-sidebar-head {
        justify-content: space-between;
        min-height: 64px;
        padding: 6px var(--sb-s3) 6px var(--sb-s4);
    }

    .sb-sidebar-brand img { height: 45px; }
    .sb-sidebar-close { display: grid; }

    .sb-sidebar-overlay {
        position: fixed;
        inset: 0;
        z-index: 70;
        display: block;
        background: rgba(6, 10, 9, .42);
        opacity: 0;
        pointer-events: none;
        transition: opacity 180ms ease;
    }

    .sb-sidebar-overlay[data-open="true"] {
        opacity: 1;
        pointer-events: auto;
    }

    html.sb-sidebar-open,
    html.sb-sidebar-open body {
        overflow: hidden;
    }

    .sb-header {
        display: grid;
        grid-template-columns: 44px minmax(0, 1fr) 44px;
        width: 100%;
        height: var(--sb-header-h);
        min-height: var(--sb-header-h);
        margin-left: 0;
        padding: 0 8px;
        gap: 4px;
    }

    .sb-mobile-menu-toggle {
        display: grid;
        grid-column: 1;
        grid-row: 1;
        place-items: center;
        width: 44px;
        height: 44px;
        margin: 0;
        padding: 0;
        border: 0;
        border-radius: var(--sb-radius-sm);
        background: transparent;
        color: var(--sb-text);
        cursor: pointer;
    }

    .sb-mobile-menu-toggle:hover { background: var(--sb-surface-soft); }

    .sb-header-brand {
        display: flex;
        grid-column: 2;
        grid-row: 1;
        justify-self: center;
        min-width: 0;
    }

    .sb-header-brand img {
        width: auto;
        height: 45px;
    }

    .sb-header-context { display: none; }

    .sb-header > .sb-user {
        grid-column: 3;
        grid-row: 1;
        justify-self: end;
        width: 44px;
        margin: 0;
    }

    .sb-header > .sb-user .sb-user-trigger {
        width: 44px;
        height: 44px;
        justify-content: center;
        padding: 0;
        border: 0;
    }

    .sb-header > .sb-user .sb-user-meta,
    .sb-header > .sb-user .sb-user-caret { display: none; }

    .sb-header > .sb-user .sb-user-menu {
        position: fixed;
        top: 54px;
        right: 8px;
        width: min(260px, calc(100vw - 16px));
    }

    .sb-main {
        width: 100%;
        margin-left: 0;
        padding: var(--sb-s3) var(--sb-s3) var(--sb-s6);
    }

    .sb-footer {
        width: 100%;
        margin-left: 0;
    }
}

@media print {
    .sb-sidebar,
    .sb-sidebar-overlay { display: none !important; }
    .sb-main,
    .sb-footer {
        width: 100% !important;
        margin-left: 0 !important;
    }
}

/* v3.3 account-aware shell */
.sb-avatar--photo {
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    color: transparent;
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--sb-border) 78%, transparent);
}

.sb-user-menu-link {
    display: flex;
    align-items: center;
    width: 100%;
    height: var(--sb-control-h);
    padding: 0 var(--sb-s3);
    border-radius: var(--sb-radius-sm);
    color: var(--sb-text);
    font-size: var(--sb-fs-md);
    text-decoration: none;
}

.sb-user-menu-link:hover {
    background: var(--sb-surface-soft);
}


/* =========================================================
   =========================================================
   UI MASTER PATCH — r3.8
   =========================================================

   Everything below is additive and loads last, so it refines
   the system above without any page having to change a class
   name. Three jobs:

     1. Fill in the tokens the system was missing (motion,
        elevation steps, an explicit focus ring) so components
        stop inventing their own.
     2. Add the components the application had been doing
        without: an in-UI file uploader, real tab strips, a
        toolbar that survives narrow viewports.
     3. Close the responsive holes found by rendering every
        page at 320 / 375 / 768 / 1024 / 1280 / 1920.

   No colour is introduced that is not derived from a token
   already defined at the top of this file.
   ========================================================= */

:root {
    /* Motion — one duration/easing vocabulary instead of five. */
    --sb-ease: cubic-bezier(.32, .72, 0, 1);
    --sb-dur-1: 120ms;
    --sb-dur-2: 200ms;
    --sb-dur-3: 320ms;

    /* Elevation, as steps rather than one-off shadows. */
    --sb-e1: 0 1px 2px rgba(4, 42, 34, .05);
    --sb-e2: 0 2px 6px rgba(4, 42, 34, .06), 0 1px 2px rgba(4, 42, 34, .04);
    --sb-e3: 0 10px 30px rgba(4, 42, 34, .09), 0 2px 8px rgba(4, 42, 34, .04);

    /* One ring for every focusable thing. */
    --sb-ring: 0 0 0 2px var(--sb-surface), 0 0 0 4px var(--sb-green-deep);

    --sb-tap: 44px;
}

html[data-theme="dark"] {
    --sb-e1: 0 1px 2px rgba(0, 0, 0, .34);
    --sb-e2: 0 2px 8px rgba(0, 0, 0, .38);
    --sb-e3: 0 12px 34px rgba(0, 0, 0, .46);
    --sb-ring: 0 0 0 2px var(--sb-surface), 0 0 0 4px var(--sb-green);
}

/* Let the browser paint form controls, scrollbars and the
   overscroll gutter in the theme the page is actually in. */
:root { color-scheme: light; }
html[data-theme="dark"] { color-scheme: dark; }


/* ---------------------------------------------------------
   GLOBAL OVERFLOW GUARD

   A single element wider than the viewport makes the whole
   document scroll sideways, which on a phone reads as a broken
   page. Long unbroken strings — order numbers, SKUs, file
   paths, user agents, base URLs — were the usual cause.
   --------------------------------------------------------- */

html, body { max-width: 100%; overflow-x: clip; }

.sb-main,
.sb-card,
.sb-card-body,
.sb-grid,
.sb-form-grid,
.sb-field { min-width: 0; }

.sb-card-title,
.sb-card-sub,
.sb-cell-title,
.sb-cell-sub,
.sb-hint,
.sb-label,
.sb-notice,
.sb-state-text { overflow-wrap: break-word; }

img, svg, video, canvas { max-width: 100%; }


/* ---------------------------------------------------------
   FOCUS

   Keyboard focus was previously inconsistent — some controls
   used the green glow, some fell back to the UA outline, and
   inside dark cards neither was visible. One rule now.
   --------------------------------------------------------- */

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline: none;
    box-shadow: var(--sb-ring);
    border-radius: var(--sb-radius-sm);
}

.sb-btn:focus-visible,
.sb-input:focus-visible,
.sb-select:focus-visible,
.sb-textarea:focus-visible { box-shadow: var(--sb-ring); }

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


/* =========================================================
   UPLOADER

   The control behind SmartBeeShell.uploader(). Drop zone,
   queue and per-file progress. Deliberately built from the
   same surface/border/radius tokens as .sb-card so an upload
   panel does not look like it came from another application.
   ========================================================= */

.sb-uploader { display: grid; gap: var(--sb-s3); min-width: 0; }

.sb-uploader-drop {
    display: flex;
    align-items: center;
    gap: var(--sb-s4);
    min-height: 92px;
    padding: var(--sb-s4) var(--sb-s5);
    border: 1.5px dashed var(--sb-border-strong);
    border-radius: var(--sb-radius);
    background: var(--sb-surface-soft);
    cursor: pointer;
    transition: border-color var(--sb-dur-2) var(--sb-ease),
                background var(--sb-dur-2) var(--sb-ease);
}

.sb-uploader-drop:hover,
.sb-uploader-drop[data-over="true"] {
    border-color: var(--sb-green-deep);
    background: var(--sb-surface-green);
}

.sb-uploader-drop[data-over="true"] { border-style: solid; }

.sb-uploader-icon {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    border-radius: var(--sb-radius-sm);
    background: var(--sb-green-soft);
    color: var(--sb-green-deep);
}

.sb-uploader-icon svg {
    width: 22px;
    height: 22px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.sb-uploader-copy { display: grid; gap: 2px; min-width: 0; }
.sb-uploader-copy strong { font-size: var(--sb-fs-md); font-weight: 600; color: var(--sb-text); }
.sb-uploader-copy span   { font-size: var(--sb-fs-sm); color: var(--sb-muted); }

.sb-uploader-cta { margin-left: auto; flex: 0 0 auto; pointer-events: none; }

.sb-uploader[data-busy="true"] .sb-uploader-drop { opacity: .6; pointer-events: none; }

.sb-uploader-queue { display: grid; gap: var(--sb-s2); }

.sb-uploader-item {
    display: grid;
    gap: 6px;
    padding: var(--sb-s3) var(--sb-s4);
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-radius-sm);
    background: var(--sb-surface);
}

.sb-uploader-item[data-state="done"]  { border-color: var(--sb-ok-border); }
.sb-uploader-item[data-state="error"] { border-color: var(--sb-danger-border); background: var(--sb-danger-bg); }

.sb-uploader-item-head {
    display: flex;
    align-items: baseline;
    gap: var(--sb-s3);
    min-width: 0;
}

.sb-uploader-item-name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    font-size: var(--sb-fs-sm);
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sb-uploader-item-meta {
    flex: 0 0 auto;
    color: var(--sb-muted);
    font-size: var(--sb-fs-xs);
    font-variant-numeric: tabular-nums;
}

.sb-uploader-item-error {
    color: var(--sb-danger-text);
    font-size: var(--sb-fs-xs);
}

.sb-uploader-bar {
    height: 4px;
    border-radius: var(--sb-radius-pill);
    background: var(--sb-skeleton-mid);
    overflow: hidden;
}

.sb-uploader-bar > span {
    display: block;
    height: 100%;
    width: 0;
    border-radius: inherit;
    background: var(--sb-green-deep);
    transition: width var(--sb-dur-2) var(--sb-ease);
}

.sb-uploader-item[data-state="error"] .sb-uploader-bar > span { background: var(--sb-danger); }

/* Compact variant for tight cards (the account photo tile). */
.sb-uploader--inline .sb-uploader-drop {
    min-height: 0;
    padding: var(--sb-s3) var(--sb-s4);
    gap: var(--sb-s3);
}
.sb-uploader--inline .sb-uploader-icon { width: 34px; height: 34px; }
.sb-uploader--inline .sb-uploader-icon svg { width: 18px; height: 18px; }

@media (max-width: 620px) {
    .sb-uploader-drop { flex-wrap: wrap; padding: var(--sb-s4); }
    .sb-uploader-cta  { margin-left: 0; width: 100%; justify-content: center; }
}


/* =========================================================
   TABS

   Real tab strips. The settings page had six anchor links
   that scrolled an 8,000px form; this is what replaces them.
   ========================================================= */

.sb-tabs {
    display: flex;
    gap: 4px;
    margin-bottom: var(--sb-s5);
    padding: 4px;
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-radius);
    background: var(--sb-surface);
    box-shadow: var(--sb-e1);
    overflow-x: auto;
    scrollbar-width: none;
    scroll-snap-type: x proximity;
    overscroll-behavior-x: contain;
}

.sb-tabs::-webkit-scrollbar { display: none; }

.sb-tab {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: var(--sb-s2);
    min-height: 36px;
    padding: 0 var(--sb-s4);
    border: 0;
    border-radius: var(--sb-radius-sm);
    background: transparent;
    color: var(--sb-muted);
    font: inherit;
    font-size: var(--sb-fs-sm);
    font-weight: 600;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
    scroll-snap-align: start;
    transition: background var(--sb-dur-1) var(--sb-ease), color var(--sb-dur-1) var(--sb-ease);
}

.sb-tab:hover { background: var(--sb-surface-soft); color: var(--sb-text); }

.sb-tab[aria-selected="true"] {
    background: var(--sb-dark);
    color: #fff;
}

html[data-theme="dark"] .sb-tab[aria-selected="true"] {
    background: var(--sb-green-deep);
    color: #fff;
}

.sb-tab-count {
    display: inline-grid;
    place-items: center;
    min-width: 20px;
    height: 18px;
    padding: 0 5px;
    border-radius: var(--sb-radius-pill);
    background: var(--sb-surface-soft);
    color: var(--sb-muted);
    font-size: 10.5px;
    font-weight: 700;
}

.sb-tab[aria-selected="true"] .sb-tab-count {
    background: rgba(255, 255, 255, .18);
    color: #fff;
}


/* =========================================================
   TOOLBAR

   A filter/action row that wraps instead of pushing its last
   controls past the right edge. Orders and Recordings both
   lost their sort picker and reset button below ~1400px
   because the row was a single nowrap flex line.
   ========================================================= */

.sb-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sb-s3);
    min-width: 0;
}

.sb-toolbar > * { min-width: 0; }
.sb-toolbar-spacer { flex: 1 1 auto; }

.sb-toolbar-group {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sb-s2);
    min-width: 0;
}


/* =========================================================
   RESPONSIVE HARDENING
   ========================================================= */

/* KPI rows: never leave a single orphan card on its own row on
   a wide screen. auto-fit already reflows; the change is the
   floor, which was low enough (210px) to produce 6-across at
   1920 and then a 1-card orphan row. */
.sb-grid--kpi    { grid-template-columns: repeat(auto-fit, minmax(min(232px, 100%), 1fr)); }
.sb-grid--metric { grid-template-columns: repeat(auto-fit, minmax(min(176px, 100%), 1fr)); }
.sb-grid--2      { grid-template-columns: repeat(auto-fit, minmax(min(380px, 100%), 1fr)); }

/* Tables: let a wide table scroll inside its own box rather
   than dragging the page with it, and make that scroll
   discoverable instead of silent. */
.sb-table-wrap {
    max-width: 100%;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
}

.sb-table-wrap::-webkit-scrollbar { height: 8px; }
.sb-table-wrap::-webkit-scrollbar-thumb {
    border-radius: var(--sb-radius-pill);
    background: var(--sb-border-strong);
}

/* break-word, not anywhere: `anywhere` also lets the column's
   min-content width collapse, which is how "Yönetici" ended up
   printed as "Yöne / tici" and an e-mail broke after "loc".
   break-word wraps only what genuinely cannot fit. */
.sb-table td { overflow-wrap: break-word; }
.sb-table td, .sb-table th { hyphens: none; }
.sb-table .sb-num { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Stacked rows read as cards rather than as a run-on list. */
@media (max-width: 720px) {
    .sb-table--stack tbody tr {
        margin-bottom: var(--sb-s3);
        padding: var(--sb-s3) 0;
        border: 1px solid var(--sb-border);
        border-radius: var(--sb-radius-sm);
        background: var(--sb-surface);
    }

    .sb-table--stack tbody tr:last-child { margin-bottom: 0; }

    .sb-table--stack td {
        align-items: center;
        gap: var(--sb-s3);
        min-height: 34px;
    }

    /* A control in a stacked cell gets the whole width; a
       half-width <select> next to its label was unusable. */
    .sb-table--stack td:has(> .sb-input),
    .sb-table--stack td:has(> .sb-select),
    .sb-table--stack td:has(> .sb-textarea) {
        display: grid;
        gap: 4px;
        text-align: left;
    }

    .sb-table--stack td > .sb-input,
    .sb-table--stack td > .sb-select,
    .sb-table--stack td > .sb-textarea { width: 100%; }
}

/* Touch: anything tappable clears 44px on a coarse pointer. */
@media (pointer: coarse) {
    .sb-btn,
    .sb-input,
    .sb-select,
    .sb-sidebar-link,
    .sb-sidebar-sub-link,
    .sb-tab { min-height: max(var(--sb-tap), var(--sb-control-h)); }

    .sb-btn--sm { min-height: 38px; }
}

/* Notches and home indicators. */
@supports (padding: max(0px)) {
    .sb-main {
        padding-left:  max(var(--sb-s5), env(safe-area-inset-left));
        padding-right: max(var(--sb-s5), env(safe-area-inset-right));
        padding-bottom: max(var(--sb-s8), calc(env(safe-area-inset-bottom) + var(--sb-s6)));
    }

    .sb-sidebar { padding-bottom: env(safe-area-inset-bottom); }
}

/* Very small phones: the system was authored down to 375px and
   collapsed below it. */
@media (max-width: 400px) {
    :root {
        --sb-s5: 16px;
        --sb-fs-3xl: 27px;
        --sb-fs-2xl: 22px;
    }

    .sb-main { padding-left: var(--sb-s3); padding-right: var(--sb-s3); }
    .sb-card-head { flex-wrap: wrap; gap: var(--sb-s3); }
    .sb-btn-row { flex-wrap: wrap; }
    .sb-btn-row > .sb-btn { flex: 1 1 auto; justify-content: center; }
}


/* =========================================================
   SIDEBAR

   Two problems the render pass surfaced:

     - The brand lock-up ate 74px of a rail whose content
       already overflowed on a 900px-tall screen, so on the
       Ayarlar page the entire settings submenu sat below the
       fold of a scroll container with no visible scrollbar.
     - Nothing indicated that the rail scrolled at all.
   ========================================================= */

:root { --sb-sidebar-head-h: 62px; }

.sb-sidebar-brand img { height: 42px; }

.sb-sidebar-body {
    scrollbar-gutter: stable;
    /* Fade the top and bottom edges so a clipped nav item
       reads as "there is more", not as "that is the end". */
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 12px, #000 calc(100% - 14px), transparent 100%);
            mask-image: linear-gradient(to bottom, transparent 0, #000 12px, #000 calc(100% - 14px), transparent 100%);
}

.sb-sidebar-body::-webkit-scrollbar { width: 8px; }
.sb-sidebar-body::-webkit-scrollbar-thumb {
    border: 2px solid transparent;
    border-radius: var(--sb-radius-pill);
    background: var(--sb-border-strong);
    background-clip: content-box;
}

.sb-sidebar-nav { gap: var(--sb-s3); }

.sb-sidebar-link,
.sb-sidebar-theme,
.sb-sidebar-settings-trigger {
    transition: background var(--sb-dur-1) var(--sb-ease), color var(--sb-dur-1) var(--sb-ease);
}

.sb-sidebar-submenu {
    /* An eleven-item submenu that is always open is what pushed
       the rail past its own height. Animate it and let the
       trigger actually mean something. */
    overflow: hidden;
}

@media (max-width: 1024px) {
    .sb-sidebar-brand img { height: 40px; }
}


/* =========================================================
   HEADER
   ========================================================= */

.sb-header { box-shadow: none; }

.sb-header-context {
    font-size: var(--sb-fs-lg);
    font-weight: 650;
    color: var(--sb-text);
    letter-spacing: -.01em;
}

@media (max-width: 1024px) {
    .sb-header-context { font-size: var(--sb-fs-md); text-align: center; }
}


/* =========================================================
   CARDS / TYPE
   ========================================================= */

.sb-card {
    box-shadow: var(--sb-e1);
    transition: box-shadow var(--sb-dur-2) var(--sb-ease);
}

.sb-card-title { letter-spacing: -.01em; }

.sb-page-title { letter-spacing: -.02em; }

/* Card heads carry a title block plus actions; on a narrow
   card the actions were being squeezed to zero width. */
.sb-card-head { flex-wrap: wrap; row-gap: var(--sb-s3); }
.sb-card-head > :first-child { min-width: 0; flex: 1 1 240px; }

.sb-btn { transition: background var(--sb-dur-1) var(--sb-ease), border-color var(--sb-dur-1) var(--sb-ease), color var(--sb-dur-1) var(--sb-ease); }


/* =========================================================
   ADJACENT-TEXT SPACING

   Several panels render "<strong>Label</strong>explanatory
   text" with no separator, which renders as "Erişim
   İzinleriikas personel izinleri…". Give the label its own
   line wherever it heads a block of prose.
   ========================================================= */

.sb-notice-title,
.sb-inline-label {
    display: block;
    margin-bottom: 2px;
    font-weight: 650;
}

.sb-notice > div > strong:first-child,
.sb-notice > strong:first-child {
    display: block;
    margin-bottom: 2px;
}


/* =========================================================
   SIDEBAR DENSITY — r3.8

   Measured, not guessed. The navigation needed 797px of
   vertical space; a 1366x768 laptop gives the rail 591px once
   browser chrome, the sidebar head and the old footer are
   subtracted. "Ayarlar" — the entry point to every
   configuration screen in the product — was 206px below the
   fold of a scroll container whose scrollbar was invisible.

   Row height, label height and the gaps come down; the footer
   is gone (its one control moved into the account menu). The
   nav now measures ~640px, which clears 768 with room, and
   the edge fades above still mark it as scrollable for the
   permission sets that are longer.
   ========================================================= */

:root { --sb-sidebar-head-h: 56px; }

.sb-sidebar-head { min-height: var(--sb-sidebar-head-h); padding: 4px var(--sb-s4); }
.sb-sidebar-brand img { height: 34px; }

.sb-sidebar-body { padding: var(--sb-s3) 10px; }

.sb-sidebar-nav { gap: 10px; }
.sb-sidebar-group { gap: 2px; }

.sb-sidebar-group-label {
    min-height: 0;
    padding: 6px var(--sb-s3) 3px;
    font-size: 10px;
    letter-spacing: .09em;
}

.sb-sidebar-link,
.sb-sidebar-settings-trigger {
    min-height: 36px;
    padding-top: 0;
    padding-bottom: 0;
}

.sb-sidebar-sub-link { min-height: 32px; }

.sb-sidebar-foot { display: none; }

/* On the drawer there is room to breathe, and fingers need it. */
@media (max-width: 1024px) {
    .sb-sidebar-brand img { height: 38px; }
    .sb-sidebar-body { padding: var(--sb-s4) var(--sb-s3); }
    .sb-sidebar-link,
    .sb-sidebar-settings-trigger { min-height: 44px; }
    .sb-sidebar-sub-link { min-height: 40px; }
}


/* ---------------------------------------------------------
   THEME SWITCH IN THE ACCOUNT MENU
   --------------------------------------------------------- */

.sb-user-menu-theme {
    display: flex;
    align-items: center;
    gap: var(--sb-s3);
    width: 100%;
}

.sb-user-menu-theme-icon {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
}

.sb-user-menu-theme .sb-theme-icon-light,
.sb-user-menu-theme .sb-theme-icon-dark {
    width: 16px;
    height: 16px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
}

.sb-user-menu-theme .sb-theme-icon-dark { display: none; fill: currentColor; stroke: none; }
html[data-theme="dark"] .sb-user-menu-theme .sb-theme-icon-light { display: none; }
html[data-theme="dark"] .sb-user-menu-theme .sb-theme-icon-dark  { display: block; }

/* Short viewports — a 1366x768 laptop leaves the rail ~660px
   once browser chrome is subtracted. Rather than crushing the
   density everywhere for that one case, compact only when the
   window is actually short. */
@media (min-width: 1025px) and (max-height: 800px) {
    :root { --sb-sidebar-head-h: 50px; }

    .sb-sidebar-brand img { height: 30px; }
    .sb-sidebar-body { padding: var(--sb-s2) 10px; }
    .sb-sidebar-nav { gap: 7px; }
    .sb-sidebar-group-label { padding: 4px var(--sb-s3) 2px; }
    .sb-sidebar-link,
    .sb-sidebar-settings-trigger { min-height: 33px; }
    .sb-sidebar-sub-link { min-height: 29px; }
}

/* The Ayarlar submenu is eleven links deep; give it a slightly
   tighter rhythm than the top-level rail so the two read as
   different levels and the group fits more often. */
.sb-sidebar-submenu { gap: 1px; }
.sb-sidebar-sub-group + .sb-sidebar-sub-group { margin-top: 6px; padding-top: 6px; }
.sb-sidebar-sub-group > span { padding-top: 2px; padding-bottom: 2px; font-size: 10px; }


/* =========================================================
   STACKED TABLE CELLS — r3.8

   The label/value flex row had no width discipline, so on a
   375px phone the label "CİHAZ" broke across two lines as
   "CİH / AZ" while the value beside it — a full user agent
   string, an IP, a timestamp — ran off the right edge and was
   clipped by the card.

   Flex could not fix it, because most of these cells mix a
   bare text node with an element ("28.08.2026 20:16" followed
   by a <div class="sb-cell-sub">45 dk önce</div>): the text
   node becomes an anonymous flex item that no selector can
   reach, so it was the part that got crushed — a date printed
   as "28.08.2 / 026 / 20:16".

   Two grid columns solve it. The generated label auto-places
   into column one; every real child is pinned to column two
   and stacks down it, and the anonymous text node auto-places
   into column two ahead of them. Nothing is unreachable and
   nothing is squeezed.
   ========================================================= */

@media (max-width: 720px) {
    .sb-table--stack td {
        display: grid;
        grid-template-columns: minmax(80px, 38%) minmax(0, 1fr);
        gap: 2px var(--sb-s3);
        align-items: baseline;
        padding: 5px var(--sb-s4);
        text-align: right;
        overflow-wrap: anywhere;
    }

    .sb-table--stack td::before {
        grid-column: 1;
        grid-row: 1;
        align-self: baseline;
        overflow-wrap: normal;
        word-break: keep-all;
        hyphens: none;
    }

    .sb-table--stack td > * {
        grid-column: 2;
        min-width: 0;
        max-width: 100%;
        text-align: right;
        overflow-wrap: anywhere;
    }

    /* Dates, money and IPs are read as one token — never split. */
    .sb-table--stack td { hyphens: none; }

    .sb-table--stack td > .sb-cell-sub,
    .sb-table--stack td > .account-device-ua {
        color: var(--sb-muted);
        font-size: var(--sb-fs-xs);
        line-height: 1.4;
    }

    /* An action column has no label, so it takes both tracks. */
    .sb-table--stack td:not([data-label]) { grid-template-columns: minmax(0, 1fr); }
    .sb-table--stack td:not([data-label])::before { display: none; }
    .sb-table--stack td:not([data-label]) > * { grid-column: 1; }

    /* Controls fill the value track rather than sitting flush right. */
    .sb-table--stack td > .sb-input,
    .sb-table--stack td > .sb-select,
    .sb-table--stack td > .sb-textarea { width: 100%; text-align: left; }

    .sb-table--stack td > .admin-row-actions,
    .sb-table--stack td > .sb-btn-row { justify-content: flex-end; }
}


/* =========================================================
   PLACEHOLDER PAGE — r3.8

   A screen that has not shipped yet should say what it will
   be, not fail silently into an empty card. Used by
   /cost-calculation.
   ========================================================= */

.sb-placeholder { max-width: 720px; }

.sb-placeholder-body {
    display: grid;
    justify-items: start;
    gap: var(--sb-s4);
    padding: var(--sb-s8) var(--sb-s6);
}

.sb-placeholder-body h2 {
    margin: 0;
    font-size: var(--sb-fs-2xl);
    font-weight: 650;
    letter-spacing: -.02em;
}

.sb-placeholder-body > p {
    max-width: 58ch;
    margin: 0;
    color: var(--sb-muted);
    line-height: 1.55;
}

.sb-placeholder-list {
    display: grid;
    gap: var(--sb-s3);
    width: 100%;
    margin: 0;
    padding: 0;
    list-style: none;
}

.sb-placeholder-list li {
    display: grid;
    gap: 2px;
    padding: var(--sb-s3) var(--sb-s4);
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-radius-sm);
    background: var(--sb-surface-soft);
}

.sb-placeholder-list strong { font-size: var(--sb-fs-md); font-weight: 600; }
.sb-placeholder-list span   { color: var(--sb-muted); font-size: var(--sb-fs-sm); line-height: 1.45; }

@media (max-width: 560px) {
    .sb-placeholder-body { padding: var(--sb-s6) var(--sb-s4); }
}


/* =========================================================
   VISUALLY-HIDDEN CONTAINMENT — r3.8

   .sb-visually-hidden is position:absolute. Inside a table
   that is wider than its scroll box, it resolved against the
   nearest positioned ancestor — which was nothing — and so
   landed at the document's right edge, making the whole page
   scroll sideways by the 1px the element occupies. That was
   the 1287 > 1280 on the Kullanıcılar panel: a screen-reader
   caption dragging the layout.

   Containing it in the scroll box costs nothing and it stays
   exactly as available to assistive technology as before.
   ========================================================= */

.sb-table-wrap { position: relative; }

/* Belt and braces: a hidden label can never be a layout input. */
.sb-visually-hidden {
    clip-path: inset(50%);
    contain: size layout style;
}
