/* ============================================================================
   Smart Food Quality System — design system v3
   Every class name from earlier phases is preserved below. This pass fixes
   a real layout bug (filter-bar inputs were being stretched to 100% width
   by the generic form-input rule, forcing them to stack instead of sitting
   inline) and substantially deepens the visual design per explicit request
   — richer color, real elevation, a proper login screen, a real logout
   button instead of a link, and consistent button treatment everywhere.
   ============================================================================ */

:root {
    /* Brand green stays; everything around it is a calm, cool neutral
       (no green tint in the greys) with soft, low-saturation status tints. */
    --color-primary: #16865f;
    --color-primary-dark: #0f6848;
    --color-primary-darker: #0a4a34;
    --color-primary-light: #eaf6f0;
    --color-accent: #22a06b;
    --color-bg: #f5f7f9;
    --color-surface: #ffffff;
    --color-neutral-bg: #f2f4f7;
    --color-row-hover: #f9fafb;
    --color-border: #e7eaee;
    --color-border-strong: #d4dae1;
    --color-text: #111827;
    --color-text-secondary: #374151;
    --color-text-muted: #6b7280;
    --color-text-faint: #9ca3af;
    --color-error: #d0453b;
    --color-error-bg: #fef2f1;
    --color-success: #16865f;
    --color-success-bg: #ecf7f1;
    --color-warning: #b86e0b;
    --color-warning-bg: #fff7e8;
    --color-info: #2f6fb3;
    --color-info-bg: #eff5fc;
    --radius: 12px;
    --radius-sm: 8px;
    --header-height: 56px;
    --shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.04), 0 1px 3px rgba(16, 24, 40, 0.04);
    --shadow-md: 0 4px 12px -2px rgba(16, 24, 40, 0.08);
    --shadow-lg: 0 16px 32px -8px rgba(16, 24, 40, 0.14);
    --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

/* Several elements (e.g. .btn-primary/.btn-secondary) set an explicit
   `display`, which — being an author-stylesheet rule — otherwise silently
   overrides the browser's built-in `[hidden] { display: none }` default;
   author styles always beat the user-agent stylesheet regardless of
   selector specificity or source order. Without this, toggling the
   `hidden` attribute on a styled button/link does nothing visible. */
[hidden] { display: none !important; }

body {
    margin: 0;
    font-family: var(--font-sans);
    background: var(--color-bg);
    color: var(--color-text);
    font-size: 14px;
    line-height: 1.5;
    /* Inter's alternate "1", "l" and "0" read more clearly in tables of figures. */
    font-feature-settings: "cv05", "cv08", "ss01";
    -webkit-font-smoothing: antialiased;
}

h1 { font-size: 22px; font-weight: 600; margin: 0 0 4px; letter-spacing: -0.022em; }
h2 { font-size: 15px; font-weight: 600; margin: 0 0 14px; letter-spacing: -0.01em; }
a { color: var(--color-primary-dark); }
code { background: var(--color-bg); padding: 2px 6px; border-radius: 4px; font-size: 12px; }

/* ---------- Header ----------
   Was a full-bleed dark-green gradient bar; refined to a slim light
   surface with green kept only where it carries meaning (the brand
   badge, the avatar tint) — the "heavy" feeling was the solid dark fill
   covering the whole bar, not the brand color itself. */
.app-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: var(--color-surface);
    color: var(--color-text);
    padding: 0 22px;
    height: var(--header-height);
    border-bottom: 1px solid var(--color-border);
    box-shadow: var(--shadow-sm);
    position: relative;
    z-index: 10;
}
.app-header__brand { display: flex; align-items: center; gap: 10px; min-width: 0; flex-shrink: 1; }
.brand-mark {
    background: var(--color-primary);
    color: #fff;
    font-weight: 700;
    font-size: 10.5px;
    letter-spacing: 0.06em;
    padding: 5px 8px;
    border-radius: var(--radius-sm);
    flex-shrink: 0;
}
/* Truncates with an ellipsis instead of forcing the header (and page)
   wider than the viewport on very narrow screens — same text, same
   element, just clipped visually when there's no room for it. */
.brand-name { font-weight: 600; font-size: 14.5px; letter-spacing: -0.01em; color: var(--color-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }

.app-header__user { display: flex; align-items: center; gap: 16px; min-width: 0; flex-shrink: 1; }
.user-chip { display: flex; align-items: center; gap: 9px; min-width: 0; }
.user-avatar {
    width: 30px; height: 30px; border-radius: 50%;
    flex-shrink: 0;
    background: var(--color-primary-light);
    color: var(--color-primary-dark);
    display: flex; align-items: center; justify-content: center;
    font-weight: 600; font-size: 12.5px;
}
.user-meta { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; max-width: 140px; }
.user-name, .user-role { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-name { font-size: 12.5px; font-weight: 600; color: var(--color-text); }
.user-role { font-size: 11px; color: var(--color-text-muted); }

.btn-logout {
    background: transparent;
    color: var(--color-text-muted);
    border: 1px solid var(--color-border-strong);
    padding: 6px 13px;
    border-radius: var(--radius-sm);
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    flex-shrink: 0;
    font-family: inherit;
    transition: background 0.14s ease, border-color 0.14s ease, color 0.14s ease;
}
.btn-logout:hover { background: var(--color-bg); color: var(--color-text); border-color: var(--color-border-strong); }

/* ---------- Layout ---------- */
.app-body { display: flex; min-height: calc(100vh - var(--header-height)); align-items: stretch; }

.app-sidebar {
    width: 234px;
    flex-shrink: 0;
    background: var(--color-surface);
    border-right: 1px solid var(--color-border);
    padding: 18px 0;
    transition: width 0.15s ease;
}
.app-sidebar ul { list-style: none; margin: 0 0 4px; padding: 0; }
.app-sidebar a {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 8px 18px;
    margin: 1px 12px;
    border-radius: var(--radius-sm);
    color: var(--color-text-secondary);
    text-decoration: none;
    font-size: 13.5px;
    font-weight: 500;
    transition: background 0.12s ease, color 0.12s ease;
}
.app-sidebar a svg { width: 17px; height: 17px; flex-shrink: 0; }
.app-sidebar a:hover { background: var(--color-bg); color: var(--color-text); }
/* A left accent bar, not a bold background block — reads as "you are
   here" without competing with the rest of the sidebar for attention. */
.app-sidebar a.is-active {
    background: var(--color-primary-light);
    color: var(--color-primary-dark);
    font-weight: 600;
    box-shadow: inset 2px 0 0 var(--color-primary);
}
.sidebar-section-label {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-text-faint);
    margin: 22px 20px 7px;
}
.app-sidebar > ul:first-child { margin-top: 0; }
.app-sidebar > ul:first-child + .sidebar-section-label { margin-top: 20px; }

/* ---------- Sidebar collapse toggle ---------- */
.sidebar-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    margin: 0 0 14px 18px;
    padding: 0;
    background: transparent;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    color: var(--color-text-muted);
    cursor: pointer;
    flex-shrink: 0;
}
.sidebar-toggle:hover { background: var(--color-bg); color: var(--color-text); }
.sidebar-toggle svg { width: 17px; height: 17px; }

/* Collapsed: icons only. The class lives on <html> (set synchronously in
   header.php, toggled in app.js) rather than on .app-sidebar itself so the
   very first inline script — which runs before the sidebar node even
   exists yet — has something to attach it to. */
html.sidebar-collapsed .app-sidebar { width: 68px; }
html.sidebar-collapsed .sidebar-label,
html.sidebar-collapsed .sidebar-section-label { display: none; }
html.sidebar-collapsed .app-sidebar a { justify-content: center; padding-left: 0; padding-right: 0; }
html.sidebar-collapsed .sidebar-toggle { margin-left: 18px; }

/* Below this width the sidebar's fixed 234px alone leaves too little room
   for any page's content — the real, app-wide source of horizontal
   overflow on mobile (the Dashboard's charts/cards just make it visible).
   Stacking the sidebar above the content instead of beside it removes
   nothing — every link stays present and clickable — it just reflows. */
@media (max-width: 768px) {
    .app-body { flex-direction: column; }
    .app-sidebar {
        width: 100%;
        border-right: none;
        border-bottom: 1px solid var(--color-border);
    }
    /* The stacked mobile layout already solves the space problem the
       collapse toggle exists for — an icon-only 68px column makes no
       sense stacked full-width above the main content, so the toggle is
       hidden here and any saved "collapsed" state is overridden back to
       full width + labels shown. */
    .sidebar-toggle { display: none; }
    html.sidebar-collapsed .app-sidebar { width: 100%; }
    html.sidebar-collapsed .sidebar-label { display: inline; }
    html.sidebar-collapsed .sidebar-section-label { display: block; }
    html.sidebar-collapsed .app-sidebar a { justify-content: flex-start; padding-left: 20px; padding-right: 20px; }
}

.app-main { flex: 1; padding: 30px 34px; min-width: 0; }

/* ---------- Page header pattern ---------- */
.page-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: 22px;
    gap: 16px;
    flex-wrap: wrap;
}
.page-header > div:first-child { min-width: 220px; flex: 1; }
.page-subtitle { color: var(--color-text-muted); font-size: 13px; margin: 3px 0 0; }
.page-actions { display: flex; gap: 8px; align-items: center; flex-shrink: 0; flex-wrap: wrap; margin-bottom: 18px; }
/* Standalone .page-actions (below an <h1>, above a detail panel) needs its
   own bottom margin now that it's a div instead of a <p> with browser
   default spacing. Nested inside .page-header it's a flex sibling of the
   heading block, and .page-header's own margin-bottom already spaces the
   whole header from what follows — an extra margin here would double it. */
.page-header .page-actions { margin-bottom: 0; }

/* ---------- Cards ---------- */
.card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    padding: 22px 24px;
    margin-bottom: 18px;
}
.card > table.data-table { margin: -22px -24px; width: calc(100% + 48px); }
.card > table.data-table thead th:first-child,
.card > table.data-table tbody td:first-child { padding-left: 24px; }
.card > table.data-table thead th:last-child,
.card > table.data-table tbody td:last-child { padding-right: 24px; }
.form-card { max-width: 640px; }
.detail-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 18px; }

.welcome-card { max-width: 640px; }
.welcome-card__badge {
    display: inline-block;
    background: var(--color-primary-light);
    color: var(--color-primary-dark);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 4px 10px;
    border-radius: 20px;
    margin-bottom: 12px;
}

/* ---------- Auth pages ---------- */
.auth-page { background: var(--color-bg); }
.auth-split {
    display: flex;
    min-height: 100vh;
    align-items: center;
    justify-content: center;
    padding: 40px 24px;
}
.auth-split__inner {
    display: flex;
    width: 100%;
    max-width: 1040px;
    min-height: 600px;
    border-radius: 18px;
    overflow: hidden;
    box-shadow: var(--shadow-lg);
}
.auth-hero {
    flex: 1 1 55%;
    background: linear-gradient(150deg, var(--color-primary-darker) 0%, var(--color-primary-dark) 55%, var(--color-accent) 130%);
    color: #fff;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 56px 60px;
    position: relative;
    overflow: hidden;
}
.auth-hero::before {
    content: "";
    position: absolute;
    width: 420px; height: 420px;
    border-radius: 50%;
    background: rgba(255,255,255,0.06);
    top: -140px; right: -120px;
}
.auth-hero::after {
    content: "";
    position: absolute;
    width: 280px; height: 280px;
    border-radius: 50%;
    background: rgba(255,255,255,0.05);
    bottom: -90px; left: 40px;
}
.brand-mark--lg { font-size: 14px; padding: 9px 13px; margin-bottom: 22px; display: inline-block; width: fit-content; }
.auth-hero__title { font-size: 28px; font-weight: 600; letter-spacing: -0.02em; margin: 0 0 12px; max-width: 380px; position: relative; }
.auth-hero__tagline { font-size: 14.5px; color: rgba(255,255,255,0.85); max-width: 340px; line-height: 1.65; position: relative; }

.auth-card {
    flex: 1 1 45%;
    background: var(--color-surface);
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 56px 52px;
}
.auth-card__heading { font-size: 21px; font-weight: 600; margin: 0 0 6px; letter-spacing: -0.015em; }
.auth-card__subheading { font-size: 13.5px; color: var(--color-text-muted); margin: 0 0 24px; }
.auth-card__footer { margin-top: 20px; font-size: 13px; text-align: center; }
.auth-card__footer a, .auth-card__footer .btn-link { font-weight: 600; text-decoration: none; }
.auth-card__footer a:hover, .auth-card__footer .btn-link:hover { text-decoration: underline; }

@media (max-width: 860px) {
    .auth-split { padding: 0; }
    .auth-split__inner { max-width: 100%; min-height: 100vh; border-radius: 0; box-shadow: none; }
    .auth-hero { display: none; }
    .auth-card { flex: 1 1 100%; }
}

/* ---------- Forms ---------- */
form label { display: block; margin-top: 14px; font-size: 12.5px; font-weight: 600; color: var(--color-text-secondary); }
/* Every form here follows the same markup: <label> immediately followed by
   its <input>/<select>/<textarea> sibling — so one rule marks every
   mandatory field app-wide (current and future) instead of hand-adding an
   asterisk per label in ~20 separate form templates. A password field with
   a show/hide toggle button is the one exception — its <input> sits inside
   a .password-field-wrap div right after the label instead of being the
   label's direct sibling, so that case is matched separately below. */
form label:has(+ input[required])::after,
form label:has(+ select[required])::after,
form label:has(+ textarea[required])::after,
form label:has(+ .password-field-wrap input[required])::after {
    content: " *";
    color: var(--color-error);
    font-weight: 600;
}
form input, form select, form textarea {
    width: 100%;
    padding: 10px 12px;
    margin-top: 5px;
    border: 1.5px solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    font-size: 13.5px;
    font-family: inherit;
    background: var(--color-surface);
    color: var(--color-text);
    transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
form input::placeholder { color: var(--color-text-faint); }
form input:focus, form select:focus, form textarea:focus {
    outline: none;
    border-color: var(--color-accent);
    box-shadow: 0 0 0 3.5px rgba(22, 134, 95, 0.14);
}
.form-narrow { max-width: 480px; }
.form-row { display: flex; gap: 16px; }
.form-row > div { flex: 1; }

.password-field-wrap { position: relative; margin-top: 5px; }
.password-field-wrap input { margin-top: 0; padding-right: 42px; }
.password-toggle {
    position: absolute;
    top: 50%;
    right: 6px;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 6px;
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--color-text-muted);
    cursor: pointer;
}
.password-toggle:hover, .password-toggle:focus-visible { background: var(--color-bg); color: var(--color-text); }
.password-toggle svg { width: 18px; height: 18px; }

.btn-primary {
    margin-top: 20px;
    background: var(--color-primary);
    color: #fff;
    border: none;
    padding: 11px 20px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: 13.5px;
    font-weight: 600;
    font-family: inherit;
    text-decoration: none;
    display: inline-block;
    box-shadow: 0 1px 2px rgba(16, 24, 40, 0.10);
    transition: background 0.12s ease, box-shadow 0.12s ease, transform 0.06s ease;
}
.btn-primary:hover { background: var(--color-primary-dark); box-shadow: var(--shadow-sm); text-decoration: none; }
.btn-primary:active { transform: translateY(1px); }
.btn-block { width: 100%; display: block; text-align: center; }

.btn-secondary {
    margin-top: 20px;
    display: inline-block;
    background: var(--color-surface);
    color: var(--color-text);
    border: 1.5px solid var(--color-border-strong);
    padding: 10px 18px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: 13.5px;
    font-weight: 600;
    font-family: inherit;
    text-decoration: none;
    transition: background 0.12s ease, border-color 0.12s ease;
}
.btn-secondary:hover { background: var(--color-bg); border-color: var(--color-text-faint); text-decoration: none; }
.btn-danger {
    margin-top: 20px;
    display: inline-block;
    background: var(--color-surface);
    color: var(--color-error);
    border: 1.5px solid #f0c4bf;
    padding: 10px 18px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: 13.5px;
    font-weight: 600;
    font-family: inherit;
    text-decoration: none;
    transition: background 0.12s ease, border-color 0.12s ease;
}
.btn-danger:hover { background: var(--color-error-bg); border-color: var(--color-error); }
/* Buttons inside a page-actions row sit next to a heading, not below a
   form's last field, so the margin-top the standalone button classes
   carry (for form contexts) would misalign this row — drop it here. */
.page-actions .btn-primary, .page-actions .btn-secondary, .page-actions .btn-danger { margin-top: 0; }
.btn-link {
    background: none;
    border: none;
    color: var(--color-primary-dark);
    text-decoration: underline;
    cursor: pointer;
    font-size: inherit;
    padding: 0;
    font-family: inherit;
    text-align: left;
}
.btn-link--danger { color: var(--color-error); }

.alert { padding: 12px 15px; border-radius: var(--radius-sm); margin-bottom: 16px; font-size: 13px; font-weight: 500; }
.alert-error { background: var(--color-error-bg); color: var(--color-error); border: 1px solid #f2c7c3; }
.alert-success { background: var(--color-success-bg); color: var(--color-success); border: 1px solid #b9e3cd; }
.api-key-reveal { display: inline-block; margin-top: 6px; word-break: break-all; font-size: 12.5px; }
.field-error { color: var(--color-error); font-size: 12px; margin: 5px 0 0; font-weight: 600; }
.field-hint { color: var(--color-text-muted); font-size: 12.5px; margin: 5px 0 0; }

/* ---------- Filter bar ---------- */
/* Explicit width here overrides the generic `form input {width:100%}` rule
   above — without this, every filter field stretches to fill the row and
   they stack instead of sitting inline (the bug reported in the UI review). */
.filter-bar {
    display: flex;
    gap: 10px;
    align-items: center;
    margin-bottom: 18px;
    flex-wrap: wrap;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 14px 16px;
    box-shadow: var(--shadow-sm);
}
.filter-bar input[type="text"],
.filter-bar input[type="datetime-local"] {
    width: 220px;
    max-width: 100%;
    flex-shrink: 1;
    padding: 8px 11px;
    margin-top: 0;
    border: 1.5px solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    font-size: 13px;
    background: var(--color-surface);
}
.filter-bar select {
    width: auto;
    max-width: 220px;
    margin-top: 0;
    padding: 8px 11px;
    border: 1.5px solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    font-size: 13px;
    background: var(--color-surface);
}
.filter-bar .btn-primary { margin-top: 0; padding: 8px 16px; }
.filter-bar a, .filter-bar .btn-link { font-size: 13px; font-weight: 600; text-decoration: none; }
.filter-bar a:hover, .filter-bar .btn-link:hover { text-decoration: underline; }
.checkbox-label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
    flex-shrink: 0;
    color: var(--color-text);
}
.checkbox-label input[type="checkbox"] {
    width: auto;
    margin-top: 0;
    accent-color: var(--color-primary);
}

/* ---------- Tables ---------- */
.data-table { width: 100%; border-collapse: collapse; background: var(--color-surface); }
.data-table th, .data-table td {
    text-align: left;
    padding: 12px 14px;
    border-bottom: 1px solid var(--color-border);
    font-size: 13.5px;
}
.data-table th {
    background: transparent;
    font-weight: 600;
    font-size: 11.5px;
    text-transform: uppercase;
    letter-spacing: 0.045em;
    color: var(--color-text-muted);
    border-bottom: 1.5px solid var(--color-border-strong);
}
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr:hover { background: var(--color-row-hover); }
.data-table a, .data-table .btn-link { text-decoration: none; font-weight: 600; }
.data-table a:hover, .data-table .btn-link:hover { text-decoration: underline; }
.data-table td a:not([href*="route=" ]):hover,
.data-table td form { display: inline; }
.empty-state { color: var(--color-text-muted); text-align: center; padding: 30px !important; font-size: 13px; }
.row-low-stock { background: var(--color-warning-bg); }
.row-low-stock:hover { background: #fbe6c2; }

/* Row-level action links get a light pill treatment so they read clearly
   as clickable actions, not ambiguous plain text. nowrap keeps multiple
   actions (e.g. Edit + Delete) on one line instead of stacking when a wider
   table (more columns, e.g. Sensors) leaves the last column too narrow to
   fit both inline-block pills side by side. */
.data-table td:last-child {
    white-space: nowrap;
}
.data-table td:last-child a,
.data-table td:last-child .btn-link {
    display: inline-block;
    padding: 4px 10px;
    border-radius: 20px;
    font-size: 12.5px;
    font-weight: 600;
    text-decoration: none;
    background: var(--color-bg);
    color: var(--color-primary-dark);
    transition: background 0.12s ease;
    margin-right: 4px;
}
.data-table td:last-child a:hover,
.data-table td:last-child .btn-link:hover {
    background: var(--color-primary-light);
    text-decoration: none;
}
/* .btn-link--danger needs to out-specificity the pill rule above (it also
   matches .btn-link) so the Delete action still reads as red inside the
   table, not the default green/teal action pill. */
.data-table td:last-child .btn-link--danger {
    background: var(--color-error-bg);
    color: var(--color-error);
}
.data-table td:last-child .btn-link--danger:hover {
    background: #f2c7c3;
    color: var(--color-error);
}

/* ---------- Pagination ---------- */
.pagination { display: flex; align-items: center; gap: 16px; margin-top: 16px; font-size: 13px; }
.pagination a { color: var(--color-primary-dark); text-decoration: none; font-weight: 600; }
.pagination a:hover { text-decoration: underline; }
.pagination__status { color: var(--color-text-muted); }

/* ---------- Detail panels ---------- */
.detail-panel, section.card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 20px 24px;
    margin-bottom: 18px;
    box-shadow: var(--shadow-sm);
}
.detail-list { display: grid; grid-template-columns: 170px 1fr; row-gap: 10px; margin: 0; }
.detail-list dt { font-weight: 600; color: var(--color-text-muted); font-size: 12.5px; }
.detail-list dd { margin: 0; }

.inline-form { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.inline-form select {
    padding: 8px 11px; border: 1.5px solid var(--color-border-strong);
    border-radius: var(--radius-sm); background: var(--color-surface); font-size: 13px;
}
.inline-form .btn-primary, .inline-form .btn-secondary { margin-top: 0; }

/* ---------- Badges & status ---------- */
.badge {
    padding: 4px 10px;
    border-radius: 20px;
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: 0.01em;
    display: inline-block;
}
.badge-active, .badge-good, .badge-calibrated, .badge-resolved, .badge-low { background: var(--color-success-bg); color: var(--color-success); }
.badge-inactive, .badge-depleted, .badge-dismissed { background: var(--color-neutral-bg); color: var(--color-text-muted); }
.badge-locked, .badge-quarantine, .badge-expired, .badge-overdue, .badge-faulty, .badge-excursion, .badge-high-risk, .badge-high, .badge-critical { background: var(--color-error-bg); color: var(--color-error); }
.badge-maintenance, .badge-use-soon, .badge-watch, .badge-inspect, .badge-due, .badge-open, .badge-medium, .badge-new { background: var(--color-warning-bg); color: var(--color-warning); }
.badge-offline, .badge-acknowledged { background: var(--color-neutral-bg); color: var(--color-text-muted); }

/* ---------- Health indicators ---------- */
.health-summary { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 4px; }
.health-badge { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; }
.health-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.dot-online { background: var(--color-success); box-shadow: 0 0 0 3px var(--color-success-bg); }
.dot-offline { background: var(--color-error); box-shadow: 0 0 0 3px var(--color-error-bg); }
.dot-unknown { background: var(--color-text-faint); box-shadow: 0 0 0 3px var(--color-neutral-bg); }
.latest-value { font-size: 25px; font-weight: 600; margin: 4px 0 0; letter-spacing: -0.015em; }

.battery-indicator {
    display: inline-block;
    padding: 3px 10px;
    border-radius: var(--radius-sm);
    font-size: 12px;
    font-weight: 600;
    margin-top: 8px;
}
.battery-high { background: var(--color-success-bg); color: var(--color-success); }
.battery-mid { background: var(--color-warning-bg); color: var(--color-warning); }
.battery-low { background: var(--color-error-bg); color: var(--color-error); }

/* ---------- Telemetry placeholders ---------- */
.telemetry-panel .telemetry-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 12px;
    margin: 12px 0;
}
.telemetry-card {
    background: var(--color-bg);
    border: 1px dashed var(--color-border-strong);
    border-radius: var(--radius-sm);
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.telemetry-card__label { font-size: 11px; color: var(--color-text-muted); font-weight: 600; text-transform: uppercase; letter-spacing: 0.045em; }
.telemetry-card__value { font-size: 18px; font-weight: 600; }
.telemetry-card__value--empty { color: var(--color-text-faint); font-style: italic; font-size: 13px; font-weight: 400; }
.telemetry-graph-placeholder {
    border: 1px dashed var(--color-border-strong);
    border-radius: var(--radius-sm);
    padding: 42px;
    text-align: center;
    color: var(--color-text-faint);
    font-size: 13px;
    background: var(--color-bg);
}

/* ---------- Monitoring status (Phase 3.3) — reusable, no hardcoded colours.
   Every colour here is one of the existing --color-* custom properties
   already used throughout app.css, mapped through named status classes
   rather than repeated anywhere as a literal colour value. ---------- */
.status-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border-radius: 20px;
    font-size: 12px;
    font-weight: 500;
}
.status-pill::before {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 50%;
    display: inline-block;
}
.status-normal   { background: var(--color-success-bg); color: var(--color-success); }
.status-normal::before   { background: var(--color-success); }
.status-watch    { background: var(--color-warning-bg); color: var(--color-warning); }
.status-watch::before    { background: var(--color-warning); }
.status-critical { background: var(--color-error-bg); color: var(--color-error); }
.status-critical::before { background: var(--color-error); }
.status-unknown  { background: var(--color-neutral-bg); color: var(--color-text-muted); }
.status-unknown::before  { background: var(--color-text-faint); }

/* Border accent on a monitoring card reuses the same status colour as the
   pill inside it — one source of truth per status, not two. */
.monitoring-card { border-left: 4px solid var(--color-border-strong); }
.monitoring-card.status-border-normal   { border-left-color: var(--color-success); }
.monitoring-card.status-border-watch    { border-left-color: var(--color-warning); }
.monitoring-card.status-border-critical { border-left-color: var(--color-error); }
.monitoring-card.status-border-unknown  { border-left-color: var(--color-text-faint); }

.monitoring-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 16px;
}
.monitoring-card__header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: 12px;
}
.monitoring-card__title { font-size: 15px; font-weight: 600; margin: 0; }
.monitoring-card__readings {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    margin-bottom: 10px;
}
.monitoring-reading__label { font-size: 11px; color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.04em; font-weight: 600; }
.monitoring-reading__value { font-size: 20px; font-weight: 600; margin-top: 2px; }
.monitoring-reading__value--empty { font-size: 14px; font-weight: 400; color: var(--color-text-faint); font-style: italic; }
.monitoring-card__footer { font-size: 12px; color: var(--color-text-muted); border-top: 1px solid var(--color-border); padding-top: 10px; margin-top: 4px; }

/* ---------- Charts (Phase 3.3) ---------- */
.time-filter-bar {
    display: flex;
    gap: 8px;
    align-items: center;
    margin-bottom: 16px;
    flex-wrap: wrap;
}
.time-filter-bar button {
    background: var(--color-surface);
    border: 1.5px solid var(--color-border-strong);
    color: var(--color-text);
    padding: 7px 14px;
    border-radius: 20px;
    font-size: 12.5px;
    font-weight: 600;
    cursor: pointer;
    font-family: inherit;
    transition: background 0.12s ease, border-color 0.12s ease;
}
.time-filter-bar button:hover { background: var(--color-bg); }
.time-filter-bar button.is-active { background: var(--color-primary); border-color: var(--color-primary); color: #fff; }
.time-filter-bar input[type="datetime-local"] {
    padding: 6px 10px;
    border: 1.5px solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    font-size: 12.5px;
    font-family: inherit;
}

.chart-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); gap: 18px; }
.chart-container { position: relative; height: 260px; width: 100%; max-width: 100%; box-sizing: border-box; }
.chart-container canvas { max-width: 100%; }
.chart-empty-message {
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    margin: 0; padding: 0 16px; text-align: center;
    color: var(--color-text-muted); font-size: 13px;
}
.chart-card h3 { font-size: 13.5px; font-weight: 600; margin: 0 0 12px; color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.03em; }

/* ---------- Expandable Quality Events rows ---------- */
.qe-row { cursor: pointer; }
.qe-row:hover { background: var(--color-bg); }
.qe-row__caret { color: var(--color-text-muted); font-size: 11px; width: 18px; }
.qe-row__detail td {
    background: var(--color-bg);
    color: var(--color-text);
    font-size: 13px;
    line-height: 1.6;
    white-space: normal;
    padding: 14px 16px !important;
    border-bottom: 1px solid var(--color-border);
}

/* ---------- Dashboard (v2 — layout + filters) ----------
   Toolbar + filter bar on top, then a grid of panels that size to their
   content — no panel scrolls or clips; long lists use "Show more" / "View
   all" and the page itself scrolls. */
.dash {
    display: flex; flex-direction: column; gap: 14px; min-width: 0;
    /* Inventory category colours (the donut and its legend). */
    --cat-veg: #1a8f68; --cat-meat: #c0362c; --cat-sea: #0e8a9a; --cat-dairy: #2563a8; --cat-other: #7c5cc4;
}

.dash-toolbar { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.dash-toolbar__title { min-width: 0; }
.dash-toolbar__title h1 { margin: 0 0 2px; }
.dash-context { margin: 0; font-size: 13px; color: var(--color-text-muted); overflow-wrap: anywhere; }
.dash-context__sep { margin: 0 6px; color: var(--color-border-strong); }
.dash-toolbar__actions { display: flex; align-items: center; gap: 12px; }
.dash-updated { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--color-text-muted); white-space: nowrap; }
/* Live dot: green while auto-refresh is working, red after a failed refresh. */
.dash-updated:not(:empty)::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--color-success); box-shadow: 0 0 0 3px var(--color-success-bg); }
.dash[data-state="error"] .dash-updated::before { background: var(--color-error); box-shadow: 0 0 0 3px var(--color-error-bg); }
.dash-refresh { display: inline-flex; align-items: center; gap: 6px; margin-top: 0; padding: 7px 13px; }
.dash-refresh svg { width: 15px; height: 15px; }
.dash[data-state="loading"] .dash-refresh svg { animation: dash-spin 0.9s linear infinite; }

/* Filter bar — a card, not .filter-bar, because each control carries its
   own small label; the generic `form label`/`form input` rules are reset
   here so fields sit inline instead of stacking full-width. */
.dash-filters { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; padding: 12px 16px; margin: 0; }
.dash-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; border: 0; padding: 0; margin: 0; }
.dash-field > label, .dash-field > legend, .dash-field__label { margin: 0; padding: 0; font-size: 12px; font-weight: 500; color: var(--color-text-muted); }
.dash-field > legend { margin-bottom: 4px; }
.dash-field select, .dash-field input[type="date"] {
    width: 160px; max-width: 100%; margin-top: 0; padding: 7px 10px; font-size: 13px;
}
.dash-field input[type="date"] { width: 145px; }
.dash-field select:disabled { background: var(--color-bg); color: var(--color-text-muted); cursor: not-allowed; }
/* Single-organisation users: the name as text in place of a locked dropdown, same height as the other fields. */
.dash-field__static { display: block; max-width: 220px; padding: 7px 0; font-size: 13.5px; font-weight: 600; line-height: 1.35; color: var(--color-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; border: 1.5px solid transparent; }

.dash-period {
    display: inline-flex; flex-wrap: wrap; gap: 2px; padding: 3px;
    background: var(--color-bg); border: 1px solid var(--color-border); border-radius: var(--radius-sm);
}
.dash-period__option { position: relative; margin: 0; cursor: pointer; }
.dash-period__option input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; pointer-events: none; }
.dash-period__option span {
    display: block; padding: 5px 11px; border-radius: 5px;
    font-size: 12.5px; font-weight: 500; color: var(--color-text-muted); white-space: nowrap;
    transition: background 0.12s ease, color 0.12s ease;
}
.dash-period__option:hover span { color: var(--color-text); }
.dash-period__option input:checked + span { background: var(--color-surface); color: var(--color-text); font-weight: 600; box-shadow: var(--shadow-sm); }
.dash-period__option input:focus-visible + span { outline: 2px solid var(--color-accent); outline-offset: 1px; }

.dash-custom { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
/* Custom From/To sit on their own row once chosen, so their labels go inline to keep that row short. */
.dash-custom .dash-field { flex-direction: row; align-items: center; gap: 6px; }
.dash-custom__apply, .dash-filters__submit { margin-top: 0; padding: 7px 14px; }
.dash-filters__end { display: flex; align-items: center; gap: 12px; margin-left: auto; }
.dash-filters.is-live .dash-filters__submit { display: none; }
.dash-filters__error, .dash-filters__empty { flex-basis: 100%; margin: 0; }

/* Panels */
.dash-grid {
    display: grid;
    /* 12-column tracks: the trend chart, compliance and inventory on one
       row (6/3/3), then activity, connectivity and alerts side by side
       (4/4/4). */
    grid-template-columns: repeat(12, minmax(0, 1fr));
    grid-template-areas:
        "trend trend trend trend trend trend compliance compliance compliance inventory inventory inventory"
        "activity activity activity activity connectivity connectivity connectivity connectivity alerts alerts alerts alerts";
    gap: 14px;
    min-height: 0;
}
.dash .dash-panel { margin: 0; padding: 14px 16px; display: flex; flex-direction: column; min-height: 0; min-width: 0; }
.dash-panel--trend        { grid-area: trend; }
.dash-panel--compliance   { grid-area: compliance; }
.dash-panel--inventory    { grid-area: inventory; }
.dash-panel--activity     { grid-area: activity; }
.dash-panel--connectivity { grid-area: connectivity; }
.dash-panel--alerts       { grid-area: alerts; }
.dash-panel__header { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; flex: 0 0 auto; }
.dash-panel__header h2 { margin: 0; font-size: 14px; font-weight: 600; color: var(--color-text); }
/* Panels never scroll inside themselves — they grow with their content. */
.dash-panel__body { position: relative; flex: 1 1 auto; min-height: 0; overflow: hidden; display: flex; flex-direction: column; gap: 10px; }
.dash-panel__scope { font-size: 12px; font-weight: 500; color: var(--color-text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.dash-empty { margin: auto 0; text-align: center; font-size: 13px; line-height: 1.55; color: var(--color-text-faint); }
.text-critical { color: var(--color-error); }

/* KPI strip: six tiles. Icon + label share a fixed-height header row (room
   for a two-line label), so every tile's value, caption and pill start on
   the same line. Tones: normal / warning / critical as elsewhere; `stale` =
   a dimmed last-known value (its pill says why); `muted` = nothing to show. */
.dash-kpis { min-width: 0; }
.kpis { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 12px; }
.kpi {
    display: flex; flex-direction: column; align-items: flex-start; gap: 4px; min-width: 0; padding: 12px 14px;
    background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius); box-shadow: var(--shadow-sm);
}
.kpi__head { display: flex; align-items: center; gap: 9px; width: 100%; min-height: 34px; margin-bottom: 4px; }
.kpi__icon {
    flex: 0 0 auto; display: grid; place-items: center; width: 34px; height: 34px; border-radius: 50%;
    background: var(--kpi-bg, var(--color-primary-light)); color: var(--kpi-fg, var(--color-primary));
}
.kpi__icon svg { width: 17px; height: 17px; }
.kpi--temp    { --kpi-bg: var(--color-error-bg);   --kpi-fg: var(--color-error); }
.kpi--humid   { --kpi-bg: var(--color-success-bg); --kpi-fg: var(--color-success); }
.kpi--door    { --kpi-bg: #efeafa;                 --kpi-fg: #7c5cc4; }
.kpi--count   { --kpi-bg: var(--color-info-bg);    --kpi-fg: var(--color-info); }
.kpi--avgopen { --kpi-bg: var(--color-warning-bg); --kpi-fg: var(--color-warning); }
.kpi--avgtemp { --kpi-bg: var(--color-success-bg); --kpi-fg: var(--color-primary); }
.kpi__label { min-width: 0; font-size: 12.5px; font-weight: 500; line-height: 1.3; color: var(--color-text-muted); display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.kpi__value { font-size: 26px; font-weight: 600; line-height: 1.15; letter-spacing: -0.03em; color: var(--color-text); white-space: nowrap; font-variant-numeric: tabular-nums; }
.kpi__value small { font-size: 14px; font-weight: 500; margin-left: 2px; letter-spacing: 0; color: var(--color-text-muted); }
.kpi__sep { color: var(--color-text-muted); font-weight: 500; }
.kpi__meta { max-width: 100%; font-size: 11.5px; line-height: 1.35; color: var(--color-text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kpi .status-pill { margin-top: 2px; padding: 2px 8px; font-size: 11.5px; gap: 5px; white-space: nowrap; }
.kpi .status-pill::before { width: 6px; height: 6px; }
.kpi.tone-critical .kpi__value { color: var(--color-error); }
.kpi.tone-warning .kpi__value  { color: var(--color-warning); }
.kpi.tone-muted .kpi__value    { color: var(--color-text-faint); }
.kpi.tone-stale .kpi__value    { color: var(--color-text-muted); }

/* Temperature & Humidity */
.dash-temp-hint { font-size: 11.5px; color: var(--color-text-muted); }

.dash-temp-chart { display: flex; flex-direction: column; gap: 4px; min-width: 0; min-height: 0; flex: 1 1 auto; }
.dash-temp-legend { display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: 11px; color: var(--color-text-muted); }
.dash-temp-legend span { display: inline-flex; align-items: center; gap: 5px; }
.dash-temp-legend i { display: inline-block; width: 14px; height: 10px; }
.dash-temp-legend .lg-line { height: 0; border-top: 2px solid var(--color-success); }
.dash-temp-legend .lg-threshold { height: 0; border-top: 2px dashed var(--color-error); }
.dash-temp-legend .lg-breach { background: rgba(192, 54, 44, 0.18); border-radius: 2px; }
.dash-temp-legend .lg-humidity { height: 0; border-top: 2px solid rgba(37, 99, 168, 0.45); }
.dash-temp-legend .lg-fault { width: 2px; height: 9px; background: var(--color-warning); }
.dash-temp-fault { color: var(--color-warning); font-weight: 600; cursor: help; }
.dash-temp-canvas { position: relative; flex: 1 1 auto; min-height: 240px; }
.dash-temp-canvas canvas { position: absolute; inset: 0; width: 100% !important; height: 100% !important; }

.dash-temp-table-wrap { flex: 1 1 auto; min-height: 0; overflow: hidden; }
.dash-temp-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.dash-temp-table th, .dash-temp-table td { padding: 6px 8px; border-bottom: 1px solid var(--color-border); text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.dash-temp-table thead th { position: sticky; top: 0; background: var(--color-surface); font-size: 12px; font-weight: 500; color: var(--color-text-muted); }
.dash-temp-table th:first-child, .dash-temp-table td:first-child { text-align: left; padding-left: 0; }
.dash-temp-table tbody th { font-weight: 600; color: var(--color-text); }
.dash-temp-table tbody th span { display: block; font-size: 11px; font-weight: 500; color: var(--color-text-muted); }
.dash-temp-table td.is-missing, .dash-temp-table .is-missing { text-align: left; color: var(--color-text-faint); font-style: italic; }
.dash-temp-table td.tone-normal   { color: var(--color-success); }
.dash-temp-table td.tone-warning  { color: var(--color-warning); }
.dash-temp-table td.tone-critical { color: var(--color-error); }
.dash-temp-partial { display: block; font-size: 10.5px; font-weight: 500; color: var(--color-warning); }

/* Donuts (compliance, inventory) — a conic-gradient ring, no chart script.
   Compliance sets --pct; the inventory donut sets its own background. */
.dash-donut-wrap { display: flex; flex-direction: column; align-items: center; gap: 12px; margin: auto 0; }
.dash-donut {
    --ring: var(--color-success);
    position: relative; flex: 0 0 auto; width: 118px; height: 118px; border-radius: 50%;
    background: conic-gradient(var(--ring) calc(var(--pct, 0) * 1%), var(--color-error) 0);
    display: grid; place-items: center;
}
.dash-donut::after { content: ""; position: absolute; inset: 14px; border-radius: 50%; background: var(--color-surface); }
.dash-donut.tone-warning { --ring: var(--color-warning); }
.dash-donut.tone-muted { background: var(--color-border); }
.dash-donut__value { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; font-size: 22px; font-weight: 600; line-height: 1.1; color: var(--color-text); }
.dash-donut__value small { font-size: 10.5px; font-weight: 600; color: var(--color-text-muted); margin-top: 2px; }
.dash-donut--multi { width: 96px; height: 96px; }
.dash-donut--multi::after { inset: 18px; }
.dash-donut-legend { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; font-size: 12px; min-width: 0; width: 100%; }
.dash-donut-legend li { display: flex; align-items: center; gap: 7px; min-width: 0; }
.dash-donut-legend i { flex: 0 0 auto; width: 9px; height: 9px; border-radius: 50%; }
.dash-donut-legend i.is-ok { background: var(--color-success); }
.dash-donut-legend i.is-out { background: var(--color-error); }
.dash-donut-legend span { color: var(--color-text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dash-donut-target { align-self: flex-start; font-size: 11px; color: var(--color-text-muted); }
.dash-donut-legend strong { margin-left: auto; font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }

/* Inventory currently inside, by category */
.dash-invcat { display: flex; flex-direction: column; gap: 12px; flex: 1 1 auto; }
.dash-invcat__total strong { display: block; font-size: 26px; font-weight: 600; line-height: 1.1; letter-spacing: -0.02em; }
.dash-invcat__total strong small { font-size: 14px; font-weight: 600; }
.dash-invcat__total span { font-size: 12px; color: var(--color-text-muted); }
.dash-invcat__body { display: flex; align-items: center; gap: 16px; }
.dash-invcat .dash-list-footer { margin-top: auto; }

.dash-list-item__tag { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-text-muted); background: var(--color-bg); padding: 0 6px; border-radius: 10px; }

/* Stock Movements page (reuses .dash-dir for the IN/OUT badge). */
.mv-summary { margin: 0 0 12px; font-size: 13px; color: var(--color-text-muted); }
.mv-summary strong { color: var(--color-text); }
.mv-in { color: var(--color-success); font-weight: 600; }
.mv-out { color: var(--color-info); font-weight: 600; }
.mv-qty { white-space: nowrap; font-variant-numeric: tabular-nums; }
.mv-custom { display: inline-flex; align-items: center; gap: 6px; }
.filter-bar input[type="date"] { width: auto; margin-top: 0; padding: 7px 10px; border: 1.5px solid var(--color-border-strong); border-radius: var(--radius-sm); font-size: 13px; }

/* All-units table rows drill into that unit on the dashboard. */
.dash-drill-row { cursor: pointer; }
.dash-drill-row:hover { background: var(--color-bg); }
.dash-temp-table th .dash-drill { font: inherit; font-weight: 600; text-decoration: none; margin: 0; padding: 0; text-align: left; }
.dash-drill-row:hover .dash-drill { text-decoration: underline; }

/* Rows past the visible count are in the page but hidden until "Show more". */
.dash-alerts > li.is-extra, .dash-temp-table tr.is-extra, .dash-table tr.is-extra { display: none; }
.dash-list-footer { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 12px; flex: 0 0 auto; font-size: 11.5px; color: var(--color-text-muted); padding-top: 2px; }
.dash-list-footer .btn-link { font-size: 12px; font-weight: 600; text-decoration: none; margin: 0; padding: 0; }
.dash-list-footer .btn-link:hover { text-decoration: underline; }
.dash-list-footer__link { margin-left: auto !important; }
/* "View all" link(s), kept together on one line at the right. */
.dash-list-footer__links { display: inline-flex; gap: 12px; margin-left: auto; white-space: nowrap; }

/* IN/OUT badge — also used by the Stock Movements page. */
.dash-dir { flex: 0 0 auto; display: inline-block; width: 34px; text-align: center; font-size: 10px; font-weight: 700; letter-spacing: 0.04em; padding: 2px 0; border-radius: 4px; }
.dash-dir.is-in { background: var(--color-success-bg); color: var(--color-success); }
.dash-dir.is-out { background: var(--color-info-bg); color: var(--color-info); }

/* Compact tables on the bottom row (activity, connectivity). */
.dash-table { width: 100%; border-collapse: collapse; font-size: 12.5px; table-layout: auto; }
.dash-table th, .dash-table td { padding: 7px 6px; border-bottom: 1px solid var(--color-border); text-align: left; vertical-align: middle; }
.dash-table th:first-child, .dash-table td:first-child { padding-left: 0; }
.dash-table thead th { background: var(--color-bg); font-size: 11.5px; font-weight: 600; color: var(--color-text-muted); }
.dash-table thead th:first-child { padding-left: 8px; border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.dash-table thead th:last-child { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.dash-table tbody td:first-child { padding-left: 8px; }
.dash-table tbody tr:last-child td { border-bottom: 0; }
.dash-table .is-nowrap { white-space: nowrap; font-variant-numeric: tabular-nums; }
.dash-table .is-nowrap small { display: block; font-size: 10.5px; color: var(--color-text-muted); }
.dash-table .is-clip { max-width: 140px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-right: 10px; }
.dash-table .is-missing { color: var(--color-text-faint); font-style: italic; }
.dash-table__link { font: inherit; font-weight: 600; margin: 0; padding: 0; text-decoration: none; }
.dash-table__link:hover { text-decoration: underline; }
.dash-table__sub { color: var(--color-text-muted); font-size: 11.5px; margin-left: 3px; }
.dash-table__line2 { display: block; font-size: 10.5px; color: var(--color-text-muted); overflow: hidden; text-overflow: ellipsis; }
.dash-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; vertical-align: 1px; background: var(--color-text-faint); }
.dash-dot.tone-normal   { background: var(--color-success); }
.dash-dot.tone-warning  { background: var(--color-warning); }
.dash-dot.tone-critical { background: var(--color-error); }

/* Critical/Warning tag — used by the Alerts page. */
.dash-sev { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; padding: 1px 6px; border-radius: 4px; }
.dash-sev.tone-critical { background: var(--color-error); color: #fff; }
.dash-sev.tone-warning { background: var(--color-warning-bg); color: var(--color-warning); border: 1px solid #f0dcb3; }

/* Active alert rows: severity icon (octagon = critical, triangle = warning,
   so the groups read apart without relying on colour alone), text, time.
   A row that opens a detail page is a <button data-href>, else a <div>. */
.dash-alerts { list-style: none; margin: 0; padding: 0; }
.dash-alerts > li { border-bottom: 1px solid var(--color-border); }
.dash-alerts > li:last-child { border-bottom: 0; }
.dash-alert-row {
    display: flex; align-items: flex-start; gap: 10px; width: 100%; padding: 8px 2px; margin: 0;
    background: none; border: 0; border-radius: 0; text-align: left; font: inherit; color: inherit;
}
button.dash-alert-row { cursor: pointer; }
button.dash-alert-row:hover { background: var(--color-bg); }
button.dash-alert-row:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }
.dash-alert-row__icon { flex: 0 0 auto; width: 22px; height: 22px; color: var(--color-warning); }
.dash-alert-row__icon svg { display: block; width: 100%; height: 100%; }
.dash-alert-row.tone-critical .dash-alert-row__icon { color: var(--color-error); }
.dash-alert-row__main { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.dash-alert-row__title { font-size: 12.5px; font-weight: 600; color: var(--color-text); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.dash-alert-row.tone-critical .dash-alert-row__title { color: var(--color-error); }
.dash-alert-row__text { font-size: 12px; color: var(--color-text-muted); line-height: 1.35; display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.dash-alert-row__meta { font-size: 11px; color: var(--color-text-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dash-alert-row__time { flex: 0 0 auto; font-size: 11px; color: var(--color-text-muted); white-space: nowrap; }

.dash-sysstatus {
    display: flex; align-items: center; gap: 10px; margin-top: auto; padding: 10px 12px;
    border-radius: var(--radius-sm); font-size: 12px; color: var(--color-text-muted);
    background: var(--color-success-bg); border: 1px solid #c7e8d8;
}
.dash-sysstatus strong { display: block; font-size: 13px; color: var(--color-success); }
.dash-sysstatus__icon { flex: 0 0 auto; display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: var(--color-success); color: #fff; font-weight: 700; font-size: 13px; }
.dash-sysstatus.tone-critical { background: var(--color-error-bg); border-color: #f1cbc8; }
.dash-sysstatus.tone-critical strong { color: var(--color-error); }
.dash-sysstatus.tone-critical .dash-sysstatus__icon { background: var(--color-error); }
.visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* Refresh states: every live panel dims while a refresh is in flight. */
.dash[data-state="loading"] .dash-panel__body { opacity: 0.55; transition: opacity 0.15s ease; }
.dash[data-state="error"] .dash-panel__body { opacity: 0.6; }

@keyframes dash-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
    .dash[data-state="loading"] .dash-refresh svg { animation: none; }
}

@media (max-width: 1280px) {
    .kpis { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .dash-grid {
        grid-template-areas:
            "trend trend trend trend trend trend trend trend trend trend trend trend"
            "compliance compliance compliance compliance compliance compliance inventory inventory inventory inventory inventory inventory"
            "activity activity activity activity activity activity connectivity connectivity connectivity connectivity connectivity connectivity"
            "alerts alerts alerts alerts alerts alerts alerts alerts alerts alerts alerts alerts";
    }
}
@media (max-width: 900px) {
    .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .dash-grid {
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas: "trend" "compliance" "inventory" "activity" "connectivity" "alerts";
    }
    .dash-filters__end { margin-left: 0; }
}
@media (max-width: 560px) {
    .kpis { grid-template-columns: minmax(0, 1fr); }
    .app-main:has(> .dash) { padding: 18px 16px; }
    .dash-field, .dash-custom, .dash-custom .dash-field { width: 100%; }
    .dash-custom .dash-field { flex-direction: column; align-items: stretch; }
    .dash-field select, .dash-field input[type="date"] { width: 100%; }
    .dash-period { display: flex; }
    .dash-period__option { flex: 1 1 auto; text-align: center; }
}

/* ---------- Role Configuration ---------- */
.alert-info { background: var(--color-info-bg); color: var(--color-info); border: 1px solid var(--color-border); }
.role-matrix { margin-bottom: 18px; }
.role-matrix th, .role-matrix td { vertical-align: middle; }
.role-matrix__action, .role-matrix__cell { text-align: center; width: 13%; }
.role-matrix__cell input[type="checkbox"] { width: 17px; height: 17px; margin: 0; cursor: pointer; accent-color: var(--color-primary); }
.role-matrix__cell input[type="checkbox"]:disabled { cursor: not-allowed; }
.role-matrix__all { display: block; margin: 4px 0 0; font-size: 10.5px; font-weight: 600; text-transform: none; letter-spacing: 0; color: var(--color-text-muted); cursor: pointer; }
.role-matrix__all input { width: auto; margin: 0 3px 0 0; vertical-align: -2px; }
.role-matrix__section th { background: var(--color-bg); font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-text-muted); text-align: left; }
.role-matrix tbody th[scope="row"] { font-weight: 600; text-align: left; }
.role-matrix tbody th[scope="row"] .field-error { display: block; }
.role-matrix__na { color: var(--color-border-strong); }
@media (max-width: 700px) {
    .role-matrix__action { font-size: 10px; }
    .role-matrix__all { display: none; }
}
