/* ==========================================================================
   Design system — hand authored, no build step, no external CSS dependency.
   Drop-in: <link rel="stylesheet" href="/assets/app.css">

   Direction handling uses CSS logical properties (margin-inline, inset-inline,
   border-start-*) throughout, so RTL and LTR share one stylesheet instead of
   maintaining a mirrored copy. Set dir="rtl" or dir="ltr" on <html> and every
   component flips correctly.

   Contents
   01. Tokens
   02. Reset and base
   03. Typography
   04. App shell
   05. Sidebar and navigation
   06. Cards and surfaces
   07. Statistics
   08. Buttons
   09. Badges and pills
   10. Tables and data lists
   11. Forms and switches
   12. Alerts
   13. Conversation bubbles
   14. Meters and bars
   15. Tabs and pagination
   16. Empty states
   17. Utilities
   18. Dark theme
   19. Print and motion preferences
   ========================================================================== */

/* == 01. Tokens =========================================================== */

:root {
    /* Neutral ramp. Slightly blue-tinted greys read as "designed" rather than
       muddy, and keep text comfortable over long sessions. */
    --c-bg: #f7f8fa;
    --c-bg-subtle: #eef0f4;
    --c-surface: #ffffff;
    --c-surface-2: #fbfcfd;
    --c-surface-hover: #f4f6f8;
    --c-border: #e4e7ec;
    --c-border-strong: #d3d8e0;

    --c-text: #1a1f2b;
    --c-text-soft: #5a6478;
    --c-text-muted: #667085;
    --c-text-inverse: #ffffff;

    /* Brand: a calm indigo-blue. Used for primary actions and active nav. */
    --c-brand: #3b5bdb;
    --c-brand-hover: #324cc0;
    --c-brand-soft: #edf1fe;
    --c-brand-border: #c7d3fa;
    --c-brand-text: #2f47a8;

    /* Semantic */
    --c-ok: #0f9b6c;
    --c-ok-text: #0a6b4b;
    --c-ok-soft: #e7f7f1;
    --c-ok-border: #b6e5d3;

    --c-warn: #b7791f;
    --c-warn-text: #7a4f0f;
    --c-warn-soft: #fdf6e6;
    --c-warn-border: #f0dcae;

    --c-danger: #d1414b;
    --c-danger-text: #9c2f37;
    --c-danger-soft: #fdeded;
    --c-danger-border: #f5c2c5;

    --c-info: #2a7fb8;
    --c-info-text: #1e5f8c;
    --c-info-soft: #eaf5fb;
    --c-info-border: #b8dcef;

    --c-accent: #7c5cd6;
    --c-accent-soft: #f3effc;
    --c-accent-border: #d9cdf5;

    /* Radii */
    --r-sm: 6px;
    --r-md: 10px;
    --r-lg: 14px;
    --r-xl: 20px;
    --r-full: 999px;

    /* Elevation. Kept shallow: a soft admin UI should feel flat and calm,
       with shadow used to separate layers, not to decorate. */
    --sh-xs: 0 1px 2px rgba(16, 24, 40, .04);
    --sh-sm: 0 1px 3px rgba(16, 24, 40, .06), 0 1px 2px rgba(16, 24, 40, .04);
    --sh-md: 0 4px 12px rgba(16, 24, 40, .07), 0 2px 4px rgba(16, 24, 40, .04);
    --sh-lg: 0 12px 32px rgba(16, 24, 40, .10), 0 4px 8px rgba(16, 24, 40, .04);

    /* Spacing scale */
    --s-1: 4px;
    --s-2: 8px;
    --s-3: 12px;
    --s-4: 16px;
    --s-5: 20px;
    --s-6: 24px;
    --s-8: 32px;
    --s-10: 40px;
    --s-12: 48px;

    /* Layout */
    --sidebar-w: 264px;
    --topbar-h: 60px;
    --bottombar-h: 62px;
    --content-max: 1400px;

    --transition: 160ms cubic-bezier(.4, 0, .2, 1);

    /* Arabic first, then Latin, then system. Cairo and Inter are loaded as
       webfonts in the layout; the fallbacks are deliberately real fonts that
       exist on Windows, macOS and Android so the page never renders in a
       default serif while the webfont loads. */
    --font-ar: 'Cairo', 'Segoe UI', 'Geeza Pro', 'Noto Sans Arabic', 'Tahoma', system-ui, sans-serif;
    --font-en: 'Inter', -apple-system, 'Segoe UI', Roboto, system-ui, sans-serif;
    --font-mono: 'SFMono-Regular', ui-monospace, 'Cascadia Mono', Menlo, Consolas, monospace;

    /* Type scale. Component typography is expressed through these tokens so a
       density or accessibility adjustment remains consistent everywhere. */
    --fs-3xs: 10px;
    --fs-2xs: 10.5px;
    --fs-xs: 11px;
    --fs-xs-plus: 11.5px;
    --fs-sm: 12px;
    --fs-sm-plus: 12.5px;
    --fs-md: 13px;
    --fs-md-plus: 13.5px;
    --fs-body: 14px;
    --fs-body-plus: 14.5px;
    --fs-lg: 15px;
    --fs-xl: 16px;
    --fs-2xl: 17px;
    --fs-title: 22px;
    --fs-display: 24px;
    --fs-stat: 26px;
    --fs-hero: 30px;
}

/* == 02. Reset and base =================================================== */

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

* { margin: 0; }

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
}

body {
    font-family: var(--font-en);
    font-size: var(--fs-body);
    line-height: 1.6;
    color: var(--c-text);
    background: var(--c-bg);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    min-height: 100vh;
    min-height: 100dvh;
}

[dir="rtl"] body { font-family: var(--font-ar); }

img, svg, video { display: block; max-width: 100%; }
[hidden] { display: none !important; }

button, input, select, textarea { font: inherit; color: inherit; }

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

a { color: var(--c-brand); text-decoration: none; }
a:hover { text-decoration: underline; }

ul, ol { padding-inline-start: 1.25em; }

/* Visible focus for keyboard users only. A form-heavy admin panel is used
   with the keyboard constantly, so this matters more than usual. */
:focus-visible {
    outline: 2px solid var(--c-brand);
    outline-offset: 2px;
    border-radius: var(--r-sm);
}
:focus:not(:focus-visible) { outline: none; }

::selection { background: var(--c-brand-soft); color: var(--c-brand-text); }

/* Thin scrollbars so inner scroll areas do not shout. */
* { scrollbar-width: thin; scrollbar-color: var(--c-border-strong) transparent; }
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: var(--c-border-strong); border-radius: var(--r-full); }
*::-webkit-scrollbar-thumb:hover { background: var(--c-text-muted); }

/* == 03. Typography ======================================================= */

h1, h2, h3, h4 { line-height: 1.3; font-weight: 700; color: var(--c-text); }

h1 { font-size: var(--fs-title); letter-spacing: -.01em; }
h2 { font-size: var(--fs-2xl); }
h3 { font-size: var(--fs-lg); }
h4 { font-size: var(--fs-md); }

.page-title { font-size: var(--fs-title); font-weight: 700; letter-spacing: -.01em; }
.page-lead {
    color: var(--c-text-soft);
    font-size: var(--fs-md-plus);
    max-width: 68ch;
    margin-block-start: var(--s-2);
}

.eyebrow {
    font-size: var(--fs-xs);
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--c-text-muted);
}
[dir="rtl"] .eyebrow,
[dir="rtl"] .nav-label,
[dir="rtl"] .table thead th {
    /* Uppercasing and positive letter-spacing are Latin treatments: on Arabic
       they either do nothing or visibly split connected glyphs. */
    letter-spacing: normal;
    text-transform: none;
}

.mono { font-family: var(--font-mono); font-size: .92em; }

/* Numbers, ids and tokens always read left-to-right, even inside Arabic. */
.ltr { direction: ltr; unicode-bidi: isolate; text-align: start; }

.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.clamp-2, .clamp-3 {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.clamp-2 { -webkit-line-clamp: 2; }
.clamp-3 { -webkit-line-clamp: 3; }

/* == 04. App shell ======================================================== */

.shell { min-height: 100vh; min-height: 100dvh; }

.shell-main {
    /* Sidebar is fixed, so the content is offset by its width on desktop.
       Logical padding means this becomes padding-right under RTL for free. */
    padding-inline-start: 0;
    padding-block-end: calc(var(--bottombar-h) + var(--s-6) + env(safe-area-inset-bottom, 0px));
    transition: padding var(--transition);
}

.content {
    max-width: var(--content-max);
    margin-inline: auto;
    padding: var(--s-4);
}

.page-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--s-3);
    margin-block-end: var(--s-5);
}

.page-head-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
}

/* == 05. Sidebar and navigation =========================================== */

/* --- mobile top bar --- */
.topbar {
    position: sticky;
    top: 0;
    z-index: 40;
    height: var(--topbar-h);
    display: flex;
    align-items: center;
    gap: var(--s-3);
    padding-inline: var(--s-4);
    background: color-mix(in srgb, var(--c-surface) 88%, transparent);
    backdrop-filter: saturate(180%) blur(12px);
    -webkit-backdrop-filter: saturate(180%) blur(12px);
    border-block-end: 1px solid var(--c-border);
}

.topbar-spacer { flex: 1; }

.brand {
    display: flex;
    align-items: center;
    gap: var(--s-2);
    font-weight: 700;
    font-size: var(--fs-lg);
    color: var(--c-text);
}
.brand:hover { text-decoration: none; }

.brand-mark {
    width: 30px;
    height: 30px;
    flex: none;
    border-radius: 9px;
    background: linear-gradient(135deg, var(--c-brand) 0%, var(--c-accent) 100%);
    color: #fff;
    display: grid;
    place-items: center;
    font-size: var(--fs-body);
    font-weight: 800;
    box-shadow: var(--sh-sm);
}

.icon-btn {
    width: 36px;
    height: 36px;
    flex: none;
    display: grid;
    place-items: center;
    border-radius: var(--r-md);
    color: var(--c-text-soft);
    border: 1px solid transparent;
    transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.icon-btn:hover { background: var(--c-surface-hover); color: var(--c-text); border-color: var(--c-border); }
.icon-btn svg { width: 18px; height: 18px; }

/* --- sidebar --- */
.sidebar {
    position: fixed;
    inset-block: 0;
    inset-inline-start: 0;
    z-index: 60;
    width: var(--sidebar-w);
    display: flex;
    flex-direction: column;
    background: var(--c-surface);
    border-inline-end: 1px solid var(--c-border);
    /* Off-canvas by default; revealed by the drawer toggle or at >= lg. */
    transform: translateX(-100%);
    transition: transform var(--transition);
}
[dir="rtl"] .sidebar { transform: translateX(100%); }

.sidebar.is-open { transform: translateX(0); }

.sidebar-head {
    height: var(--topbar-h);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-2);
    padding-inline: var(--s-4);
    border-block-end: 1px solid var(--c-border);
    flex: none;
}

.sidebar-body {
    flex: 1;
    overflow-y: auto;
    padding: var(--s-3);
}

.sidebar-foot {
    flex: none;
    padding: var(--s-3);
    border-block-start: 1px solid var(--c-border);
}

.nav-group + .nav-group { margin-block-start: var(--s-5); }

.nav-label {
    font-size: var(--fs-2xs);
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--c-text-muted);
    padding-inline: var(--s-3);
    margin-block-end: var(--s-2);
}

.nav-link {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    padding: 9px var(--s-3);
    border-radius: var(--r-md);
    color: var(--c-text-soft);
    font-size: var(--fs-md-plus);
    font-weight: 500;
    transition: background var(--transition), color var(--transition);
    position: relative;
}
.nav-link:hover { background: var(--c-surface-hover); color: var(--c-text); text-decoration: none; }
.nav-link + .nav-link { margin-block-start: 2px; }

.nav-link svg { width: 18px; height: 18px; flex: none; opacity: .8; }

.nav-link.is-active {
    background: var(--c-brand-soft);
    color: var(--c-brand-text);
    font-weight: 600;
}
.nav-link.is-active svg { opacity: 1; }

/* Active marker on the inline start edge, flips automatically. */
.nav-link.is-active::before {
    content: '';
    position: absolute;
    inset-inline-start: 0;
    inset-block: 20%;
    width: 3px;
    border-radius: var(--r-full);
    background: var(--c-brand);
}

.nav-count {
    margin-inline-start: auto;
    font-size: var(--fs-xs);
    font-weight: 700;
    min-width: 20px;
    height: 20px;
    padding-inline: 6px;
    border-radius: var(--r-full);
    display: grid;
    place-items: center;
    background: #c91c32;
    color: #fff;
    flex-shrink: 0;
    line-height: 1;
}
.nav-link.is-active .nav-count, .nav-count.is-alert { background: #c91c32; color: #fff; }
.nav-count.is-new { outline: 2px solid #c91c3255; outline-offset: 2px; }
.nav-link.has-notification { font-weight: 700; }
.bottombar-link { position: relative; }
.bottombar-link .nav-count { position: absolute; top: 2px; inset-inline-end: 12%; min-width: 18px; height: 18px; font-size: 10px; }
.tab .nav-count { display: inline-grid; vertical-align: middle; margin-inline-start: 6px; }
.position-feedback { position: fixed; z-index: 1100; bottom: 80px; inset-inline-end: 20px; max-width: min(520px, calc(100vw - 40px)); display: flex; align-items: start; gap: 12px; padding: 12px 16px; color: var(--c-text); background: var(--c-surface, #fff); border: 1px solid var(--c-border); border-radius: 12px; box-shadow: 0 4px 24px #0002; font-size: var(--fs-sm); white-space: pre-line; max-height: 35vh; overflow: auto; }
.position-feedback[role="alert"] { border-color: var(--c-danger); }

/* --- user block --- */
.user-row {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    padding: var(--s-2);
    border-radius: var(--r-md);
}

.avatar {
    width: 34px;
    height: 34px;
    flex: none;
    border-radius: var(--r-full);
    object-fit: cover;
    background: var(--c-bg-subtle);
    display: grid;
    place-items: center;
    font-weight: 700;
    font-size: var(--fs-md);
    color: var(--c-text-soft);
}
.avatar-sm { width: 26px; height: 26px; font-size: var(--fs-xs); }
.avatar-lg { width: 44px; height: 44px; font-size: var(--fs-xl); }
.avatar-sq { border-radius: 9px; }

.user-meta { min-width: 0; flex: 1; }
.user-name { font-size: var(--fs-md); font-weight: 600; }
.user-sub { font-size: var(--fs-xs-plus); color: var(--c-text-muted); }

/* --- drawer scrim --- */
.scrim {
    position: fixed;
    inset: 0;
    z-index: 50;
    background: rgba(16, 24, 40, .45);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--transition);
}
.scrim.is-open { opacity: 1; pointer-events: auto; }

/* --- mobile bottom bar --- */
/* Five primary destinations, thumb-reachable. This is the only navigation on
   phones, so it must always be present rather than hidden behind a menu. */
.bottombar {
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    z-index: 45;
    height: calc(var(--bottombar-h) + env(safe-area-inset-bottom));
    padding-block-end: env(safe-area-inset-bottom);
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    background: color-mix(in srgb, var(--c-surface) 92%, transparent);
    backdrop-filter: saturate(180%) blur(12px);
    -webkit-backdrop-filter: saturate(180%) blur(12px);
    border-block-start: 1px solid var(--c-border);
}

.bottombar-link {
    appearance: none;
    border: 0;
    background: transparent;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    font-size: var(--fs-2xs);
    font-weight: 600;
    color: var(--c-text-muted);
    padding-block: 6px;
}
.bottombar-link:hover { text-decoration: none; }
.bottombar-link svg { width: 21px; height: 21px; }
.bottombar-link.is-active { color: var(--c-brand); }

/* == 06. Cards and surfaces =============================================== */

.card {
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    box-shadow: var(--sh-xs);
}

.card-pad { padding: var(--s-4); }

.card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-3);
    padding: var(--s-3) var(--s-4);
    border-block-end: 1px solid var(--c-border);
}
.card-head h2, .card-head h3 { font-size: var(--fs-body); }

.card-body { padding: var(--s-4); }

.card-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-3);
    flex-wrap: wrap;
    padding: var(--s-3) var(--s-4);
    border-block-start: 1px solid var(--c-border);
    background: var(--c-surface-2);
    border-end-start-radius: var(--r-lg);
    border-end-end-radius: var(--r-lg);
}

.card-hover { transition: box-shadow var(--transition), border-color var(--transition), transform var(--transition); }
.card-hover:hover { box-shadow: var(--sh-md); border-color: var(--c-border-strong); }

.divider { height: 1px; background: var(--c-border); border: 0; margin-block: var(--s-4); }

/* == 07. Statistics ======================================================= */

#campaign-diagnostics { scroll-margin-top: 84px; }
#campaign-diagnostics bdi { overflow-wrap: anywhere; }

.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: var(--s-3);
}

.stat {
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    padding: var(--s-4);
    box-shadow: var(--sh-xs);
    display: flex;
    flex-direction: column;
    gap: var(--s-2);
    transition: box-shadow var(--transition), transform var(--transition);
}
.stat:hover { box-shadow: var(--sh-sm); }

.stat-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-2);
}

.stat-label {
    font-size: var(--fs-sm);
    font-weight: 500;
    color: var(--c-text-soft);
    line-height: 1.35;
}

.stat-icon {
    width: 30px;
    height: 30px;
    flex: none;
    border-radius: 9px;
    display: grid;
    place-items: center;
    background: var(--c-bg-subtle);
    color: var(--c-text-soft);
}
.stat-icon svg { width: 16px; height: 16px; }

.stat-value {
    font-size: var(--fs-stat);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
}

.stat-note { font-size: var(--fs-xs-plus); color: var(--c-text-muted); }

/* Tone variants tint only the icon, keeping the number readable. */
.stat--ok .stat-icon { background: var(--c-ok-soft); color: var(--c-ok); }
.stat--ok .stat-value { color: var(--c-ok); }
.stat--warn .stat-icon { background: var(--c-warn-soft); color: var(--c-warn); }
.stat--warn .stat-value { color: var(--c-warn); }
.stat--danger .stat-icon { background: var(--c-danger-soft); color: var(--c-danger); }
.stat--danger .stat-value { color: var(--c-danger); }
.stat--info .stat-icon { background: var(--c-info-soft); color: var(--c-info); }
.stat--info .stat-value { color: var(--c-info); }
.stat--accent .stat-icon { background: var(--c-accent-soft); color: var(--c-accent); }
.stat--accent .stat-value { color: var(--c-accent); }
.stat--brand .stat-icon { background: var(--c-brand-soft); color: var(--c-brand); }

/* == 08. Buttons ========================================================== */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--s-2);
    padding: 8px 14px;
    border-radius: var(--r-md);
    border: 1px solid var(--c-border-strong);
    background: var(--c-surface);
    color: var(--c-text);
    font-size: var(--fs-md);
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
    transition: background var(--transition), border-color var(--transition), color var(--transition), box-shadow var(--transition), transform var(--transition);
    box-shadow: var(--sh-xs);
}
.btn:hover { background: var(--c-surface-hover); text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn svg { width: 16px; height: 16px; flex: none; }
.btn[disabled], .btn.is-disabled { opacity: .55; pointer-events: none; }

.btn--primary {
    background: var(--c-brand);
    border-color: var(--c-brand);
    color: var(--c-text-inverse);
}
.btn--primary:hover { background: var(--c-brand-hover); border-color: var(--c-brand-hover); }

.btn--meta {
    background: #1877f2;
    border-color: #1877f2;
    color: #fff;
}
.btn--meta:hover { background: #1568d8; border-color: #1568d8; }

.btn--danger { color: var(--c-danger-text); border-color: var(--c-danger-border); background: var(--c-surface); }
.btn--danger:hover { background: var(--c-danger-soft); }

.btn--danger-solid { background: var(--c-danger); border-color: var(--c-danger); color: #fff; }
.btn--danger-solid:hover { background: #b8353e; border-color: #b8353e; }

.btn--ok { color: var(--c-ok-text); border-color: var(--c-ok-border); }
.btn--ok:hover { background: var(--c-ok-soft); }

.btn--ok-solid { background: var(--c-ok-text); border-color: var(--c-ok-text); color: #fff; }
.btn--ok-solid:hover { background: #07583e; border-color: #07583e; }

.btn--warn { color: var(--c-warn-text); border-color: var(--c-warn-border); }
.btn--warn:hover { background: var(--c-warn-soft); }

.btn--ghost { border-color: transparent; box-shadow: none; background: transparent; color: var(--c-text-soft); }
.btn--ghost:hover { background: var(--c-surface-hover); color: var(--c-text); }

.btn--sm, .btn--small { min-height: 36px; padding: 5px 10px; font-size: var(--fs-sm); border-radius: var(--r-sm); }
.btn--lg { padding: 11px 20px; font-size: var(--fs-body); }
.btn--block { width: 100%; }

.btn-group { display: inline-flex; flex-wrap: wrap; gap: var(--s-2); }

/* == 09. Badges and pills ================================================= */

.badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 8px;
    border-radius: var(--r-full);
    border: 1px solid var(--c-border);
    background: var(--c-bg-subtle);
    color: var(--c-text-soft);
    font-size: var(--fs-xs-plus);
    font-weight: 600;
    line-height: 1.6;
    white-space: nowrap;
}

.badge--ok { background: var(--c-ok-soft); border-color: var(--c-ok-border); color: var(--c-ok-text); }
.badge--warn { background: var(--c-warn-soft); border-color: var(--c-warn-border); color: var(--c-warn-text); }
.badge--danger { background: var(--c-danger-soft); border-color: var(--c-danger-border); color: var(--c-danger-text); }
.badge--info { background: var(--c-info-soft); border-color: var(--c-info-border); color: var(--c-info-text); }
.badge--accent { background: var(--c-accent-soft); border-color: var(--c-accent-border); color: var(--c-accent); }
.badge--brand { background: var(--c-brand-soft); border-color: var(--c-brand-border); color: var(--c-brand-text); }

/* Status dot, for at-a-glance health without reading the label. */
.dot {
    width: 7px;
    height: 7px;
    border-radius: var(--r-full);
    flex: none;
    background: var(--c-text-muted);
}
.dot--ok { background: var(--c-ok); }
.dot--warn { background: var(--c-warn); }
.dot--danger { background: var(--c-danger); }
.dot--live {
    background: var(--c-ok);
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--c-ok) 60%, transparent);
    animation: pulse 2s infinite;
}

@keyframes pulse {
    70% { box-shadow: 0 0 0 6px transparent; }
    100% { box-shadow: 0 0 0 0 transparent; }
}

/* == 10. Tables and data lists ============================================ */

.table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

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

.table thead th {
    text-align: start;
    font-size: var(--fs-xs);
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--c-text-muted);
    background: var(--c-surface-2);
    padding: 10px var(--s-3);
    border-block-end: 1px solid var(--c-border);
    white-space: nowrap;
    position: sticky;
    top: 0;
    z-index: 1;
}

.table tbody td {
    padding: 11px var(--s-3);
    border-block-end: 1px solid var(--c-border);
    vertical-align: middle;
}

.table tbody tr:last-child td { border-block-end: 0; }
.table tbody tr { transition: background var(--transition); }
.table tbody tr:hover { background: var(--c-surface-hover); }

.table .num { font-variant-numeric: tabular-nums; text-align: end; }
.table .center { text-align: center; }
.table .top td, .table td.top { vertical-align: top; }
.table .nowrap { white-space: nowrap; }

.cell-title { font-weight: 600; }
.cell-sub { font-size: var(--fs-xs-plus); color: var(--c-text-muted); margin-block-start: 2px; }

.cell-stack { display: flex; align-items: center; gap: var(--s-3); min-width: 0; }

/* Key/value list, used as the mobile replacement for a wide table row. */
.kv { display: grid; gap: var(--s-2); }
.kv-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s-3);
    font-size: var(--fs-sm-plus);
}
.kv-key { color: var(--c-text-muted); flex: none; }
.kv-val { text-align: end; min-width: 0; }

/* Mobile card list. Hidden on wide screens where the table is better. */
.record-list { display: grid; gap: var(--s-3); min-width: 0; }

.record {
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-md);
    padding: var(--s-3);
    box-shadow: var(--sh-xs);
    min-width: 0;
    max-width: 100%;
}
.record-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--s-2);
    margin-block-end: var(--s-2);
    min-width: 0;
    max-width: 100%;
}
.record-head > :first-child { min-width: 0; flex: 1 1 12rem; }
.record-head > .badge { flex: 0 0 auto; max-width: 100%; }

.dashboard-attention .cell-title {
    white-space: normal;
    overflow-wrap: anywhere;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
}

/* == 11. Forms and switches =============================================== */

.field { display: block; }
.field + .field { margin-block-start: var(--s-3); }

/* Responsive data-entry forms. Some newer screens used `form-grid` before it
   had a definition, leaving native labels and inputs in one unstyled line. */
.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr));
    gap: var(--s-4);
    align-items: end;
    min-width: 0;
}
.form-grid > .field { min-width: 0; margin-block-start: 0; }
.form-grid > .span-2 { grid-column: span 2; }
.form-grid > .form-note,
.form-grid > .form-actions { grid-column: 1 / -1; }
.form-actions { display: flex; flex-wrap: wrap; gap: var(--s-2); justify-content: flex-start; }

.label {
    display: block;
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--c-text-soft);
    margin-block-end: 5px;
}

.hint { font-size: var(--fs-xs-plus); color: var(--c-text-muted); margin-block-start: 5px; }

/* Contextual help is available by mouse, keyboard and touch. The explanation
   is rendered from aria-label so no extra overlay library is needed. */
.help-anchor { display: inline-flex; align-items: center; gap: .25rem; min-width: 0; max-width: 100%; flex-wrap: wrap; }
.help-anchor--stat { display: block; position: relative; }
.help-anchor--stat > .stat { height: 100%; }
.help-anchor--stat .stat-note { padding-inline-end: 34px; }
.help-anchor--stat > .help-tip { position: absolute; inset-inline-end: 12px; bottom: 12px; margin: 0; }
.order-actions { min-width: 0; max-width: 100%; }
.order-actions form { max-width: 100%; }
.order-actions .btn { max-width: 100%; white-space: normal; }
.help-tip {
    position: relative; display: inline-grid; place-items: center;
    width: 28px; height: 28px; margin-inline-start: 6px; padding: 0;
    border: 1px solid var(--c-border); border-radius: 50%;
    background: var(--c-surface); color: var(--c-brand); font: 700 12px/1 sans-serif;
    cursor: help; vertical-align: middle; flex: 0 0 auto;
}
.help-tip:hover, .help-tip.is-open { border-color: var(--c-brand); }
.help-tip:focus-visible { border-color: var(--c-brand); outline: 2px solid var(--c-brand); outline-offset: 2px; }
/*
 * Fixed, not absolute.
 *
 * An absolutely positioned bubble is clipped by the nearest ancestor that
 * scrolls or hides its overflow - and this app is full of them: log tables
 * scroll sideways, cards and rows round their corners. The same explanation
 * therefore appeared as a cut dark sliver on one screen and as nothing at all
 * on another, which reads as "the help button is broken".
 *
 * The coordinates come from the layout script, which measures the question
 * mark on hover and writes --tip-l with either --tip-b (room above, the usual
 * case) or --tip-t (near the top of the window). Anchoring by the bottom edge
 * means the bubble never has to be measured before it is placed.
 *
 * The fallbacks keep it usable if the script has not run yet.
 */
.help-tip::after {
    content: attr(data-tooltip); position: fixed; z-index: 80;
    inset-inline: auto;
    left: var(--tip-l, 50vw);
    top: var(--tip-t, auto);
    bottom: var(--tip-b, auto);
    transform: translateX(-50%);
    width: min(430px, 86vw); max-height: min(65vh, 520px); overflow-y: auto;
    padding: 12px 14px; border: 1px solid var(--c-border);
    border-radius: 9px; background: var(--c-text); color: var(--c-surface);
    font: 500 12px/1.75 var(--font-ar); text-align: start;
    white-space: pre-line; box-shadow: var(--sh-md); opacity: 0; visibility: hidden;
    pointer-events: none; transition: opacity .15s ease;
}
.help-tip:hover::after, .help-tip:focus-visible::after, .help-tip.is-open::after { opacity: 1; visibility: visible; pointer-events: auto; }

/* Tables that carry data-label become readable records on narrow phones
   without duplicating sensitive billing values into a second DOM tree. */
@media (max-width: 767px) {
    .responsive-table { overflow: visible; }
    .responsive-table table,
    .responsive-table tbody,
    .responsive-table tr,
    .responsive-table td { display: block; width: 100%; }
    .responsive-table thead { display: none; }
    .responsive-table tr {
        border: 1px solid var(--c-border);
        border-radius: 10px;
        margin-block-end: var(--s-3);
        overflow: hidden;
    }
    .responsive-table td {
        display: grid;
        grid-template-columns: minmax(7rem, 40%) 1fr;
        gap: var(--s-2);
        align-items: start;
        border: 0;
        border-block-end: 1px solid var(--c-border);
        white-space: normal;
    }
    .responsive-table td:last-child { border-block-end: 0; }
    .responsive-table td:not([data-label]) { display: block; }
    .responsive-table td[data-label]::before {
        content: attr(data-label);
        color: var(--c-text-muted);
        font-size: var(--fs-xs);
        font-weight: 700;
    }
    .responsive-table td[colspan] { display: block; }
    .responsive-table td[colspan]::before { content: none; }
}
.analytics-filters { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px; align-items: end; }
.period-pills { display: flex; flex-wrap: wrap; gap: 7px; }
.chip--active { border-color: var(--c-brand); color: var(--c-brand); background: var(--c-brand-soft); }
.stat-trend { margin-top: 7px; font-size: var(--fs-xs); color: var(--c-text-muted); }
.stat-trend.is-up { color: var(--c-ok); }
.stat-trend.is-down { color: var(--c-danger); }
.analytics-reset summary { cursor: pointer; }
.lab-details summary { cursor: pointer; color: var(--c-brand); }
.lab-result-list { display: grid; gap: 7px; }
.lab-result-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 9px; align-items: start; padding: 9px; border: 1px solid var(--c-border); border-radius: var(--r-sm); background: var(--c-surface-2); font-size: var(--fs-sm); }
@media (max-width: 640px) { .lab-result-row { grid-template-columns: auto minmax(0, 1fr); } .lab-result-row > :last-child { grid-column: 2; } }

.input, .select, .textarea {
    width: 100%;
    padding: 8px 11px;
    border: 1px solid var(--c-border-strong);
    border-radius: var(--r-md);
    background: var(--c-surface);
    font-size: var(--fs-md);
    color: var(--c-text);
    transition: border-color var(--transition), box-shadow var(--transition);
}
.input:hover, .select:hover, .textarea:hover { border-color: var(--c-text-muted); }
.input:focus, .select:focus, .textarea:focus {
    outline: none;
    border-color: var(--c-brand);
    box-shadow: 0 0 0 3px var(--c-brand-soft);
}
.input::placeholder, .textarea::placeholder { color: var(--c-text-muted); }

.textarea { resize: vertical; min-height: 76px; line-height: 1.6; }

.select {
    appearance: none;
    padding-inline-end: 30px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238b95a8' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-size: 15px;
    background-position: right 10px center;
}
[dir="rtl"] .select { background-position: left 10px center; }

.filter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--s-3);
    padding: var(--s-3);
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    box-shadow: var(--sh-xs);
}
.filter-bar .field { min-width: 140px; flex: 1 1 140px; margin: 0; }
.filter-bar .btn { flex: none; }

/* Checkbox and radio, restyled without losing native behaviour. */
.check {
    appearance: none;
    width: 24px;
    height: 24px;
    flex: none;
    border: 1.5px solid var(--c-border-strong);
    border-radius: 5px;
    background: var(--c-surface);
    display: grid;
    place-content: center;
    transition: background var(--transition), border-color var(--transition);
}
.check:hover { border-color: var(--c-brand); }
.check:checked { background: var(--c-brand); border-color: var(--c-brand); }
.check:checked::after {
    content: '';
    width: 9px;
    height: 5px;
    border: 2px solid #fff;
    border-top: 0;
    border-inline-end: 0;
    transform: rotate(-45deg) translateY(-1px);
}

.check-row {
    display: flex;
    align-items: center;
    gap: var(--s-2);
    font-size: var(--fs-sm-plus);
    cursor: pointer;
    min-height: 44px;
    padding-block: 8px;
}

/* Switch. Used for the many on/off toggles across pages and channels. */
.switch {
    appearance: none;
    width: 38px;
    height: 22px;
    flex: none;
    border-radius: var(--r-full);
    background: var(--c-border-strong);
    position: relative;
    cursor: pointer;
    transition: background var(--transition);
}
.switch::after {
    content: '';
    position: absolute;
    top: 3px;
    inset-inline-start: 3px;
    width: 16px;
    height: 16px;
    border-radius: var(--r-full);
    background: #fff;
    box-shadow: var(--sh-sm);
    transition: transform var(--transition);
}
.switch:checked { background: var(--c-ok); }
.switch:checked::after { transform: translateX(16px); }
[dir="rtl"] .switch:checked::after { transform: translateX(-16px); }
.switch[disabled] { opacity: .45; cursor: not-allowed; }

/* Submit-on-click toggle rendered as a button, for progressive enhancement
   free forms. Looks like a switch, behaves like a form submit. */
.toggle-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--s-2);
    padding: 4px 9px 4px 5px;
    border-radius: var(--r-full);
    border: 1px solid var(--c-border);
    background: var(--c-bg-subtle);
    color: var(--c-text-soft);
    font-size: var(--fs-xs-plus);
    font-weight: 600;
    transition: background var(--transition), border-color var(--transition), color var(--transition);
    min-height: 36px;
}
.toggle-btn::before {
    content: '';
    width: 8px;
    height: 8px;
    border-radius: var(--r-full);
    background: var(--c-text-muted);
    flex: none;
    margin-inline-start: 3px;
}
.toggle-btn:hover { border-color: var(--c-border-strong); }
.toggle-btn.is-on {
    background: var(--c-ok-soft);
    border-color: var(--c-ok-border);
    color: var(--c-ok-text);
}
.toggle-btn.is-on::before { background: var(--c-ok); }
.toggle-btn.is-accent.is-on {
    background: var(--c-accent-soft);
    border-color: var(--c-accent-border);
    color: var(--c-accent);
}
.toggle-btn.is-accent.is-on::before { background: var(--c-accent); }
.toggle-btn[disabled] { opacity: .5; }

/* == 12. Alerts =========================================================== */

.alert {
    display: flex;
    align-items: flex-start;
    gap: var(--s-3);
    padding: var(--s-3) var(--s-4);
    border-radius: var(--r-md);
    border: 1px solid var(--c-border);
    background: var(--c-surface);
    font-size: var(--fs-md);
    box-shadow: var(--sh-xs);
}
.alert + .alert { margin-block-start: var(--s-2); }
.alert svg { width: 18px; height: 18px; flex: none; margin-block-start: 1px; }

.alert--ok { background: var(--c-ok-soft); border-color: var(--c-ok-border); color: var(--c-ok-text); }
.alert--warn { background: var(--c-warn-soft); border-color: var(--c-warn-border); color: var(--c-warn-text); }
.alert--danger { background: var(--c-danger-soft); border-color: var(--c-danger-border); color: var(--c-danger-text); }
.alert--info { background: var(--c-info-soft); border-color: var(--c-info-border); color: var(--c-info-text); }

.alert-stack { margin-block-end: var(--s-4); }

/* == 13. Conversation bubbles ============================================= */

.thread {
    display: flex;
    flex-direction: column;
    gap: var(--s-3);
    max-height: 30rem;
    overflow-y: auto;
    padding-inline-end: var(--s-1);
}

.bubble-row { display: flex; }
.bubble-row.is-in { justify-content: flex-start; }
.bubble-row.is-out { justify-content: flex-end; }

.bubble {
    max-width: min(78%, 520px);
    padding: 9px var(--s-3);
    border-radius: var(--r-lg);
    font-size: var(--fs-md);
    line-height: 1.65;
    border: 1px solid transparent;
}

.bubble-row.is-in .bubble {
    background: var(--c-bg-subtle);
    border-color: var(--c-border);
    border-start-start-radius: var(--r-sm);
}
.bubble-row.is-out .bubble {
    background: var(--c-brand-soft);
    border-color: var(--c-brand-border);
    color: var(--c-brand-text);
    border-start-end-radius: var(--r-sm);
}

.bubble-text { white-space: pre-wrap; overflow-wrap: anywhere; }

.bubble-meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
    margin-block-start: 5px;
    font-size: var(--fs-2xs);
    color: var(--c-text-muted);
    opacity: .9;
}

/* Decision trail entries beside the transcript. */
.trace { display: flex; flex-direction: column; gap: var(--s-3); max-height: 30rem; overflow-y: auto; }

.trace-item {
    border: 1px solid var(--c-border);
    border-radius: var(--r-md);
    padding: var(--s-3);
    background: var(--c-surface-2);
    font-size: var(--fs-sm-plus);
}
.trace-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-2);
    margin-block-end: var(--s-2);
}
.trace-line { color: var(--c-text-soft); }
.trace-line + .trace-line { margin-block-start: 3px; }
.trace-line--muted { color: var(--c-text-muted); }
.trace-line--error { color: var(--c-danger); }

/* == 14. Meters and bars ================================================== */

/* Window countdown. A bar communicates "running out" faster than a number. */
.meter {
    height: 5px;
    border-radius: var(--r-full);
    background: var(--c-bg-subtle);
    overflow: hidden;
}
.meter-fill {
    height: 100%;
    border-radius: var(--r-full);
    background: var(--c-ok);
    transition: width var(--transition);
}
.meter-fill--warn { background: var(--c-warn); }
.meter-fill--danger { background: var(--c-danger); }
.meter-fill--empty { background: var(--c-border-strong); }

/* Horizontal distribution bars for the "rule vs AI" breakdown. */
.bar-list { display: grid; gap: var(--s-3); }
.bar-item { display: grid; gap: 5px; }
.bar-top {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s-2);
    font-size: var(--fs-sm-plus);
}
.bar-value { font-weight: 700; font-variant-numeric: tabular-nums; }
.bar-track { height: 7px; border-radius: var(--r-full); background: var(--c-bg-subtle); overflow: hidden; }
.bar-fill { height: 100%; border-radius: var(--r-full); background: var(--c-brand); }
.bar-fill--accent { background: var(--c-accent); }
.bar-fill--ok { background: var(--c-ok); }
.bar-fill--warn { background: var(--c-warn); }
.bar-fill--muted { background: var(--c-border-strong); }

/* == 15. Tabs and pagination ============================================== */

.tabs {
    display: flex;
    gap: var(--s-1);
    padding: 3px;
    background: var(--c-bg-subtle);
    border-radius: var(--r-md);
    overflow-x: auto;
    width: fit-content;
    max-width: 100%;
}

.tab {
    padding: 6px 13px;
    border-radius: var(--r-sm);
    font-size: var(--fs-sm-plus);
    font-weight: 600;
    color: var(--c-text-soft);
    white-space: nowrap;
    transition: background var(--transition), color var(--transition);
}
.tab:hover { color: var(--c-text); text-decoration: none; }
.tab.is-active { background: var(--c-surface); color: var(--c-text); box-shadow: var(--sh-xs); }

/* Paginator. Markup comes from resources/views/vendor/pagination/custom.blade.php */
.pagination-wrap { margin-block-start: var(--s-4); }

.pager {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-3);
}

.pager-info { font-size: var(--fs-sm-plus); color: var(--c-text-muted); }

.pager-links { display: flex; align-items: center; gap: var(--s-1); }
.pager-numbers { display: none; align-items: center; gap: var(--s-1); }

.pager-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 34px;
    height: 34px;
    padding-inline: 10px;
    font-size: var(--fs-sm-plus);
    font-weight: 600;
    border: 1px solid var(--c-border-strong);
    border-radius: var(--r-md);
    background: var(--c-surface);
    color: var(--c-text-soft);
    transition: background var(--transition), border-color var(--transition), color var(--transition);
}
.pager-btn:hover { background: var(--c-surface-hover); color: var(--c-text); text-decoration: none; }
.pager-btn.is-current {
    background: var(--c-brand);
    border-color: var(--c-brand);
    color: var(--c-text-inverse);
}
.pager-btn.is-disabled { opacity: .45; pointer-events: none; }

/* The chevron icon points inline-end by default, so "previous" is flipped.
   Under RTL the whole axis inverts, which is what these two rules encode. */
.pager-btn svg { transform: rotate(180deg); }
[dir="rtl"] .pager-btn svg { transform: rotate(0deg); }
.pager-next svg { transform: rotate(0deg); }
[dir="rtl"] .pager-next svg { transform: rotate(180deg); }

.pager-gap { padding-inline: 6px; color: var(--c-text-muted); font-size: var(--fs-sm-plus); }

@media (min-width: 560px) {
    .pager-numbers { display: flex; }
}

/* == 16. Empty states ===================================================== */

.empty {
    padding: var(--s-10) var(--s-4);
    text-align: center;
}
.empty-icon {
    width: 46px;
    height: 46px;
    margin-inline: auto;
    margin-block-end: var(--s-3);
    border-radius: var(--r-lg);
    display: grid;
    place-items: center;
    background: var(--c-bg-subtle);
    color: var(--c-text-muted);
}
.empty-icon svg { width: 22px; height: 22px; }
.empty-title { font-size: var(--fs-body); font-weight: 600; }
.empty-text {
    font-size: var(--fs-sm-plus);
    color: var(--c-text-muted);
    margin-block-start: var(--s-2);
    max-width: 44ch;
    margin-inline: auto;
}
.empty-actions { margin-block-start: var(--s-4); }

/* == 15a. Rule list ======================================================= */

.rule-list { display: grid; gap: var(--s-3); }

/* Page answer-source settings are intentionally an accordion. A workspace can
   have many Pages, but operators only edit one at a time; keeping every form
   expanded made the most important setting feel like an endless document. */
.page-settings {
    min-width: 0;
    overflow: clip;
    border: 1px solid var(--c-border);
    border-radius: var(--r-md);
    background: var(--c-surface-2);
    transition: border-color var(--transition), box-shadow var(--transition), background var(--transition);
}
.page-settings[open] {
    border-color: var(--c-brand-border);
    background: var(--c-surface);
    box-shadow: var(--shadow-sm);
}
.page-settings-summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-4);
    min-width: 0;
    padding: var(--s-4);
    cursor: pointer;
    list-style: none;
    user-select: none;
}
.page-settings-summary::-webkit-details-marker { display: none; }
.page-settings-summary::after {
    content: '\203A';
    flex: 0 0 auto;
    color: var(--c-text-muted);
    font-size: var(--fs-display);
    line-height: 1;
    transition: transform var(--transition), color var(--transition);
}
[dir="rtl"] .page-settings-summary::after { transform: rotate(180deg); }
.page-settings[open] > .page-settings-summary::after {
    color: var(--c-brand);
    transform: rotate(90deg);
}
[dir="rtl"] .page-settings[open] > .page-settings-summary::after { transform: rotate(90deg); }
.page-settings-title {
    display: grid;
    gap: 3px;
    min-width: 0;
}
.page-settings-title strong,
.page-settings-title .cell-sub { overflow-wrap: anywhere; }
.page-settings-status {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: var(--s-2);
    margin-inline-start: auto;
}
.page-settings-body {
    min-width: 0;
    padding: var(--s-4);
    border-block-start: 1px solid var(--c-border);
}
.page-settings-toolbar {
    align-items: center;
    padding-block-end: var(--s-3);
    margin-block-end: var(--s-3);
    border-block-end: 1px solid var(--c-border);
}

@media (max-width: 640px) {
    .page-settings-summary {
        align-items: flex-start;
        flex-wrap: wrap;
        gap: var(--s-2);
        padding: var(--s-3);
    }
    .page-settings-status {
        order: 3;
        width: 100%;
        justify-content: flex-start;
        margin-inline-start: 0;
    }
    .page-settings-body { padding: var(--s-3); }
}

.rule {
    border: 1px solid var(--c-border);
    border-radius: var(--r-md);
    padding: var(--s-3);
    background: var(--c-surface-2);
    /* Enabled rules carry a coloured start edge, so a glance down the list
       shows what is actually live. */
    border-inline-start: 3px solid var(--c-border-strong);
    transition: border-color var(--transition), background var(--transition);
}
.rule.is-on {
    background: var(--c-surface);
    border-inline-start-color: var(--c-ok);
}

.rule-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--s-3);
    flex-wrap: wrap;
}

.rule-reply {
    margin-block-start: var(--s-2);
    font-size: var(--fs-sm-plus);
    color: var(--c-text-soft);
    background: var(--c-bg-subtle);
    border-radius: var(--r-sm);
    padding: 7px var(--s-3);
}

.rule-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-3);
    flex-wrap: wrap;
    margin-block-start: var(--s-3);
    padding-block-start: var(--s-2);
    border-block-start: 1px solid var(--c-border);
}

.chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    margin-block-start: var(--s-2);
}

.chip {
    font-size: var(--fs-xs-plus);
    font-family: var(--font-mono);
    padding: 2px 7px;
    border-radius: var(--r-sm);
    background: var(--c-brand-soft);
    color: var(--c-brand-text);
    border: 1px solid var(--c-brand-border);
}
.chip--muted { background: var(--c-bg-subtle); color: var(--c-text-muted); border-color: var(--c-border); }

/* Two-up form rows that collapse on phones. */
.field-row { display: grid; grid-template-columns: 1fr; gap: var(--s-3); }
.field-row .field { margin: 0; }
.field-row + .field, .field + .field-row { margin-block-start: var(--s-3); }

.check-grid { display: grid; grid-template-columns: 1fr; gap: 2px; }

@media (min-width: 560px) {
    .field-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .check-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* == 15b. Page cards (pages & channels screen) ============================ */

/* One card per Facebook page. Cards rather than a wide table because each page
   carries five channel toggles plus controls, which no phone-width table can
   show without horizontal scrolling. */
.page-cards {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s-4);
}

.page-card {
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    padding: var(--s-4);
    background: var(--c-surface-2);
    transition: border-color var(--transition), background var(--transition), box-shadow var(--transition);
}
.page-card.is-active {
    background: var(--c-surface);
    border-color: var(--c-brand-border);
    box-shadow: var(--sh-sm);
}

.page-card-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--s-3);
    flex-wrap: wrap;
}

.page-card-health {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-4);
    margin-block-start: var(--s-4);
    padding-block: var(--s-3);
    border-block: 1px solid var(--c-border);
}

.health-item { display: flex; align-items: center; gap: var(--s-2); }
.health-key { font-size: var(--fs-xs-plus); color: var(--c-text-muted); }

.page-card-section { margin-block-start: var(--s-4); }

.chan-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s-2);
}

.chan {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-2);
    padding: 7px var(--s-3);
    border: 1px solid var(--c-border);
    border-radius: var(--r-md);
    background: var(--c-surface);
    transition: border-color var(--transition), background var(--transition);
}
.chan.is-on { border-color: var(--c-ok-border); background: var(--c-ok-soft); }
.chan.is-unavailable { opacity: .6; }

.chan-name {
    display: flex;
    align-items: center;
    gap: var(--s-2);
    font-size: var(--fs-sm-plus);
    font-weight: 600;
    min-width: 0;
}
.chan-name svg { flex: none; opacity: .65; }
.chan.is-on .chan-name { color: var(--c-ok); }
.chan.is-on .chan-name svg { opacity: 1; }

.page-card-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s-2);
    margin-block-start: var(--s-4);
    padding-block-start: var(--s-3);
    border-block-start: 1px solid var(--c-border);
}

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

@media (min-width: 1280px) {
    .page-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .chan-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 1600px) {
    .page-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .chan-grid { grid-template-columns: 1fr; }
}

/* == 16b. Auth screen ===================================================== */

.auth {
    min-height: 100vh;
    min-height: 100dvh;
    display: grid;
    grid-template-columns: 1fr;
}

.auth-aside { display: none; }

.auth-main {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: var(--s-6) var(--s-4);
}

.auth-box {
    width: 100%;
    max-width: 400px;
    margin-inline: auto;
}

.auth-brand {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    margin-block-end: var(--s-8);
}
.auth-brand .brand-mark { width: 38px; height: 38px; font-size: var(--fs-2xl); border-radius: 11px; }
.auth-brand-name { font-size: var(--fs-xl); font-weight: 700; }
.auth-brand-sub { font-size: var(--fs-sm); color: var(--c-text-muted); }

.auth-title { font-size: var(--fs-display); font-weight: 700; letter-spacing: -.02em; }
.auth-sub { color: var(--c-text-soft); font-size: var(--fs-md-plus); margin-block-start: var(--s-2); }

.auth-form { margin-block-start: var(--s-6); }
.auth-form .field + .field { margin-block-start: var(--s-4); }
.auth-form .input { padding: 10px 12px; font-size: var(--fs-body); }

.auth-foot {
    margin-block-start: var(--s-6);
    padding-block-start: var(--s-4);
    border-block-start: 1px solid var(--c-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-3);
    flex-wrap: wrap;
}

@media (min-width: 900px) {
    .auth { grid-template-columns: 1fr 1fr; }

    /* Brand panel. Only shown where there is room for it to be an asset rather
       than a wall the user has to scroll past. */
    .auth-aside {
        display: flex;
        flex-direction: column;
        justify-content: space-between;
        padding: var(--s-12) var(--s-10);
        color: #fff;
        background:
            radial-gradient(1200px 600px at 20% 10%, rgba(255, 255, 255, .16), transparent 60%),
            linear-gradient(150deg, #3b5bdb 0%, #4b48c9 45%, #7c5cd6 100%);
        position: relative;
        overflow: hidden;
    }

    .auth-aside::after {
        content: '';
        position: absolute;
        inset-inline-end: -120px;
        bottom: -160px;
        width: 420px;
        height: 420px;
        border-radius: 50%;
        background: rgba(255, 255, 255, .07);
    }

    .auth-aside-title {
        font-size: var(--fs-hero);
        font-weight: 700;
        line-height: 1.35;
        letter-spacing: -.02em;
        max-width: 22ch;
    }

    .auth-aside-text {
        margin-block-start: var(--s-4);
        font-size: var(--fs-body-plus);
        line-height: 1.75;
        color: rgba(255, 255, 255, .82);
        max-width: 44ch;
    }

    .auth-points { margin-block-start: var(--s-8); display: grid; gap: var(--s-4); }
    .auth-point { display: flex; align-items: flex-start; gap: var(--s-3); font-size: var(--fs-md-plus); }
    .auth-point svg { flex: none; margin-block-start: 2px; opacity: .9; }
    .auth-point-title { font-weight: 600; }
    .auth-point-text { color: rgba(255, 255, 255, .72); font-size: var(--fs-sm-plus); margin-block-start: 2px; }

    .auth-aside .brand-mark { background: rgba(255, 255, 255, .18); box-shadow: none; }
    .auth-note { font-size: var(--fs-sm); color: rgba(255, 255, 255, .6); position: relative; z-index: 1; }

    .auth-main { padding: var(--s-12) var(--s-10); }
}

/* == 17. Utilities ======================================================== */

.grid { display: grid; gap: var(--s-4); }
.grid-2 { grid-template-columns: 1fr; }
.grid-3 { grid-template-columns: 1fr; }
.grid-sidebar { grid-template-columns: 1fr; }

.flex { display: flex; }
.flex-col { display: flex; flex-direction: column; }
.items-center { align-items: center; }
.items-start { align-items: flex-start; }
.items-end { align-items: flex-end; }
.justify-between { justify-content: space-between; }
.justify-end { justify-content: flex-end; }
.wrap { flex-wrap: wrap; }
.flex-1 { flex: 1; min-width: 0; }
.gap-1 { gap: var(--s-1); }
.gap-2 { gap: var(--s-2); }
.gap-3 { gap: var(--s-3); }
.gap-4 { gap: var(--s-4); }

.mt-2 { margin-block-start: var(--s-2); }
.mt-3 { margin-block-start: var(--s-3); }
.mt-4 { margin-block-start: var(--s-4); }
.mt-5 { margin-block-start: var(--s-5); }
.mt-1 { margin-block-start: var(--s-1); }
.mb-0 { margin-block-end: 0; }
.mb-1 { margin-block-end: var(--s-1); }
.mb-2 { margin-block-end: var(--s-2); }
.mb-3 { margin-block-end: var(--s-3); }
.mb-4 { margin-block-end: var(--s-4); }
.mb-5 { margin-block-end: var(--s-5); }

.text-soft { color: var(--c-text-soft); }
.text-muted { color: var(--c-text-muted); }
.text-ok, .text-success { color: var(--c-ok-text); }
.text-warn { color: var(--c-warn-text); }
.text-danger { color: var(--c-danger-text); }
.text-accent { color: var(--c-accent); }
.text-brand { color: var(--c-brand); }
.text-xs { font-size: var(--fs-xs-plus); }
.text-sm { font-size: var(--fs-sm-plus); }
.text-end { text-align: end; }
.text-center { text-align: center; }
.bold { font-weight: 700; }
.semibold { font-weight: 600; }
.tnum { font-variant-numeric: tabular-nums; }

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

.scroll-y { overflow-y: auto; }
.flex-wrap { flex-wrap: wrap; }
.py-2 { padding-block: var(--s-2); }
.px-2 { padding-inline: var(--s-2); }
.inline-block { display: inline-block; }
.d-block { display: block; }
.field-error { color: var(--c-danger-text); font-size: var(--fs-xs-plus); margin-block-start: 5px; }
[aria-invalid="true"] { border-color: var(--c-danger-border) !important; box-shadow: 0 0 0 2px var(--c-danger-soft); }
form.is-submitting { cursor: progress; }
form.is-submitting button[type="submit"]:not([data-no-loading])::after,
form.is-submitting input[type="submit"]:not([data-no-loading])::after {
    content: '';
    display: inline-block;
    inline-size: .75em;
    block-size: .75em;
    margin-inline-start: .45em;
    border: 2px solid currentColor;
    border-inline-end-color: transparent;
    border-radius: 50%;
    animation: submitting-spin .7s linear infinite;
    vertical-align: -.08em;
}
@keyframes submitting-spin { to { transform: rotate(360deg); } }
.notice { display: flex; gap: var(--s-2); padding: var(--s-3); border: 1px solid var(--c-info-border); border-radius: var(--r-md); background: var(--c-info-soft); color: var(--c-info-text); }
.notice--ok { border-color: var(--c-ok-border); background: var(--c-ok-soft); color: var(--c-ok-text); }
.notice--warn, .alert-warning { border-color: var(--c-warn-border); background: var(--c-warn-soft); color: var(--c-warn-text); }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--s-3); }

/* Progressive-enhancement helper: forms that only exist to be submitted by a
   button elsewhere in the document. */
.form-inline { display: contents; }
.inline-form { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }

/* == 18. Responsive ======================================================= */

/* --- >= 480px : roomier phones --- */
@media (min-width: 480px) {
    .content { padding: var(--s-5); }
    .stat-grid { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
}

/* --- >= 768px : tablets. Tables become viable. --- */
@media (min-width: 768px) {
    body { font-size: var(--fs-body); }
    .content { padding: var(--s-6); }
    h1, .page-title { font-size: var(--fs-display); }

    .grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .md-only { display: initial; }
    .md-hidden { display: none !important; }

    /* Wide tables replace the mobile record cards. */
    .table-view { display: block; }
    .card-view { display: none; }
}

/* --- >= 1024px : sidebar becomes permanent, no drawer --- */
@media (min-width: 1024px) {
    .sidebar {
        transform: translateX(0) !important;
        box-shadow: none;
    }
    .shell-main {
        padding-inline-start: var(--sidebar-w);
        padding-block-end: var(--s-8);
    }
    .topbar { display: none; }
    .bottombar { display: none; }
    .scrim { display: none !important; }
    .sidebar-close { display: none; }

    .grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .grid-sidebar { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }

    .lg-hidden { display: none !important; }
}

/* --- >= 1280px --- */
@media (min-width: 1280px) {
    .content { padding: var(--s-8) var(--s-6); }
    .stat-grid { grid-template-columns: repeat(auto-fit, minmax(176px, 1fr)); }
}

/* --- >= 1600px : wide monitors get a wider column, not endless whitespace --- */
@media (min-width: 1600px) {
    :root { --content-max: 1560px; }
}

/* Mobile defaults for the table/card swap, declared last so the 768px rule
   above wins on larger screens. */
@media (max-width: 767.98px) {
    .table-view { display: none; }
    .card-view { display: block; }
    .page-head-actions { width: 100%; }
    .page-head-actions .btn { flex: 1 1 auto; }
    .filter-bar .btn { width: 100%; }
}

/* == 19. Dark theme ======================================================= */

/* Opt-in via data-theme="dark" on <html>, which the layout persists in
   localStorage. Automatic preference is honoured only when the user has not
   chosen explicitly. */
:root[data-theme="dark"] {
    --c-bg: #0f1219;
    --c-bg-subtle: #1a1f2b;
    --c-surface: #161b24;
    --c-surface-2: #1a2029;
    --c-surface-hover: #1f252f;
    --c-border: #262d3a;
    --c-border-strong: #37404f;

    --c-text: #e8ebf0;
    --c-text-soft: #a3adbe;
    --c-text-muted: #98a2b3;
    --c-text-inverse: #0f1219;

    --c-brand: #6b86ec;
    --c-brand-hover: #7d95ef;
    --c-brand-soft: #1e2542;
    --c-brand-border: #33406e;
    --c-brand-text: #a8b8f5;

    --c-ok: #34c48f;
    --c-ok-text: #7fe0b8;
    --c-ok-soft: #12291f;
    --c-ok-border: #1f4736;

    --c-warn: #e0a13a;
    --c-warn-text: #f0cd8c;
    --c-warn-soft: #2a2113;
    --c-warn-border: #4a3a1c;

    --c-danger: #f0656f;
    --c-danger-text: #f7a3a9;
    --c-danger-soft: #2c1719;
    --c-danger-border: #4d2528;

    --c-info: #4fa8dd;
    --c-info-text: #9dd3f2;
    --c-info-soft: #12242e;
    --c-info-border: #1e3f52;

    --c-accent: #a98cf0;
    --c-accent-soft: #221b34;
    --c-accent-border: #3b2f59;

    --sh-xs: 0 1px 2px rgba(0, 0, 0, .25);
    --sh-sm: 0 1px 3px rgba(0, 0, 0, .35);
    --sh-md: 0 4px 12px rgba(0, 0, 0, .40);
    --sh-lg: 0 12px 32px rgba(0, 0, 0, .50);
}

:root[data-theme="dark"] .alert--ok { color: #7fe0b8; }
:root[data-theme="dark"] .alert--warn { color: #f0cd8c; }
:root[data-theme="dark"] .alert--danger { color: #f7a3a9; }
:root[data-theme="dark"] .alert--info { color: #9dd3f2; }
:root[data-theme="dark"] .btn--primary,
:root[data-theme="dark"] .btn--ok-solid,
:root[data-theme="dark"] .btn--danger-solid { color: #0f1219; }
:root[data-theme="dark"] .nav-link.is-active .nav-count { background: #c91c32; color: #fff; }
:root[data-theme="dark"] .switch::after { background: #e8ebf0; }
:root[data-theme="dark"] .check:checked::after { border-color: #0f1219; }
:root[data-theme="dark"] .brand-mark { color: #0f1219; }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        color-scheme: dark;
    }
}

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

/* == 19b. Collapsible panels and shared page furniture ====================
   Several screens open with a block that is configured once and then rarely
   read again - source switches, an add form, a long explainer - and those
   blocks were pushing the actual working content below the fold. Folding them
   costs one click on the rare day they are needed and buys the whole screen
   on every other day.

   Built on <details>, so the open state is the browser's own: no JavaScript,
   and the content is still in the DOM (and still found by Ctrl+F) when shut.
   ========================================================================== */

.panel {
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    box-shadow: var(--sh-xs);
    /*
     * Deliberately NOT overflow:hidden.
     *
     * The help bubble (.help-tip::after) is absolutely positioned above its
     * icon and reaches outside whatever contains it. A clipping ancestor turns
     * it into a cropped dark rectangle with no readable text - which is exactly
     * what happened here. The corners are rounded on the children instead, so
     * the panel still looks clipped without actually clipping anything.
     */
}

.panel-head {
    display: flex;
    flex-direction: column;
    gap: 2px;
    border-start-start-radius: var(--r-lg);
    border-start-end-radius: var(--r-lg);
    padding: var(--s-4);
    cursor: pointer;
    list-style: none;
    transition: background var(--transition);
}
.panel-head::-webkit-details-marker { display: none; }
.panel-head:hover { background: var(--c-surface-hover); }

.panel-title {
    display: flex;
    align-items: center;
    gap: var(--s-2);
    font-weight: 600;
    font-size: var(--fs-body);
}
/* A chevron that turns, so "closed" and "open" are legible without reading. */
.panel-title::after {
    content: '';
    width: 7px;
    height: 7px;
    margin-inline-start: auto;
    border-inline-end: 2px solid var(--c-text-muted);
    border-block-end: 2px solid var(--c-text-muted);
    transform: rotate(45deg);
    transition: transform var(--transition);
}
details[open] > .panel-head .panel-title::after { transform: rotate(-135deg); }

.panel-sub { font-size: var(--fs-xs-plus); color: var(--c-text-muted); }

.panel-body {
    padding: var(--s-4);
    border-block-start: 1px solid var(--c-border);
    border-end-start-radius: var(--r-lg);
    border-end-end-radius: var(--r-lg);
}

/* Action bar above a selectable list. Sits on its own surface so the buttons
   never read as belonging to the first row beneath them. */
.bulk-bar {
    display: flex;
    align-items: center;
    gap: var(--s-2);
    flex-wrap: wrap;
    background: var(--c-surface-2);
    border: 1px solid var(--c-border);
    border-radius: var(--r-md);
    padding: var(--s-2) var(--s-3);
}
.bulk-sep { width: 1px; align-self: stretch; background: var(--c-border); margin-inline: var(--s-1); }

/* Maintenance diagnostics are key/value data, not running prose. The old
   markup borrowed installer-only classes, so on the authenticated layout every
   label touched its value and long model ids made the card look broken. */
.maintenance-list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--s-3);
}
.maintenance-row {
    min-width: 0;
    display: grid;
    grid-template-columns: minmax(8rem, .85fr) minmax(0, 1.15fr);
    align-items: start;
    gap: var(--s-3);
    padding: var(--s-3);
    border: 1px solid var(--c-border);
    border-radius: var(--r-md);
    background: var(--c-surface-2);
}
.maintenance-row--wide { grid-column: 1 / -1; }
.maintenance-row.is-bad { border-color: var(--c-danger-border); background: var(--c-danger-soft); }
.maintenance-label { min-width: 0; font-weight: 650; color: var(--c-text); }
.maintenance-value {
    min-width: 0;
    color: var(--c-text-soft);
    overflow-wrap: anywhere;
    word-break: break-word;
}
.maintenance-value.ltr { text-align: left; }
.maintenance-probe { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }

@media (max-width: 820px) {
    .maintenance-list { grid-template-columns: minmax(0, 1fr); }
    .maintenance-row--wide { grid-column: auto; }
}

@media (max-width: 520px) {
    .maintenance-row { grid-template-columns: minmax(0, 1fr); gap: var(--s-1); }
    .maintenance-probe { align-items: stretch; }
    .maintenance-probe .btn { width: 100%; }
}

/* Separates groups of fields inside one long form without spending a card. */
.group-title {
    font-size: var(--fs-xs);
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--c-text-muted);
    margin-block: var(--s-4) var(--s-2);
}

/* A stat tile that is also a filter link. */
a.stat { text-decoration: none; color: inherit; }
a.stat:hover { box-shadow: var(--sh-md); border-color: var(--c-border-strong); }

/* The base chip is monospaced because it usually holds an id. This one holds
   words - an alternative product name, a tag - and must read as prose. */
.chip--label {
    font-family: inherit;
    background: var(--c-bg-subtle);
    color: var(--c-text-soft);
    border-color: var(--c-border);
}
.chip--warn { background: var(--c-warn-soft); color: var(--c-warn); border-color: var(--c-warn-border); font-family: inherit; }

/* == 20. Motion and print ================================================= */

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

@media print {
    .sidebar, .topbar, .bottombar, .scrim, .page-head-actions, .filter-bar, .pagination-wrap { display: none !important; }
    .shell-main { padding: 0 !important; }
    .card, .stat { box-shadow: none; border-color: #ccc; }
    body { background: #fff; }
}

/* ---- containment: content must never push the frame ---------------------
   A flex or grid child defaults to min-width:auto, which means it refuses to
   shrink below its content. One long row - a bulk bar with six buttons, a wide
   filter strip - was therefore able to widen the whole document and shove the
   sidebar off the screen at mid widths, which is what "the page is broken"
   actually looked like.
   Letting these boxes shrink keeps the frame fixed; anything genuinely too
   wide scrolls inside its own card instead of taking the page with it. */
.shell-main, .shell-main > *, .card, .card-body, .rule, .stat { min-width: 0; }
.card-body > .flex.wrap, .filter-bar { max-width: 100%; }

/* The same rule, extended to the row and panel components added later. A grid
   or flex child still defaults to min-width:auto, so one long badge or one
   unbreakable id inside a row was enough to widen the document and slide the
   frame out from under the sidebar. Named explicitly rather than with a
   universal selector, which would also stop tables and pre blocks from
   scrolling inside their own box - the behaviour we actually want there. */
.panel, .panel-body, .bulk-bar,
.prod, .prod-row, .prod-body,
.src, .src-row, .src-body,
.camp, .camp-row, .camp-body,
.ci-row, .ci-head, .ci-body { min-width: 0; }

/* Nothing may render wider than the frame. A row that genuinely cannot fit
   scrolls inside itself; it does not take the page with it. */
.shell-main { overflow-x: clip; }

/* ---- narrow screens: an overflow safety net -----------------------------
   The layout is mobile-first everywhere else, so this is not a second design.
   It answers one specific cause: filter rows and bulk-action bars carry an
   inline min-width so their fields stay readable side by side on a desktop.
   Below this width those minimums are wider than the phone itself, and a row
   that cannot shrink pushes the entire page sideways - which is what makes a
   screen feel broken rather than cramped.
   An inline style can only be answered with !important, and it is confined to
   this block so the desktop layout is untouched. */
@media (max-width: 640px) {
    .btn, .btn--sm, .btn--small, .icon-btn, .toggle-btn { min-height: 44px; }
    .icon-btn { min-width: 44px; }
    .field[style] { min-width: 0 !important; width: 100%; }

    /* Rows that were columns of controls become a stack. */
    .rule-head, .rule-foot { flex-direction: column; align-items: stretch; gap: 8px; }
    .rule-head > .flex, .rule-foot > form { width: 100%; }

    /* Order numbers, ids and tracking codes carry no spaces to break at, so
       a single token was enough to widen the whole page. */
    .semibold, .cell-sub, .chip, .badge, .empty-text { overflow-wrap: anywhere; }

    /* Tabs and tables scroll rather than squash: a squashed table is
       unreadable, a scrolling one is merely narrow. */
    .tabs, .table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
    .record-list { overflow: visible; }

    .form-grid { grid-template-columns: minmax(0, 1fr); }
    .form-grid > .span-2 { grid-column: auto; }
    .form-actions .btn { width: 100%; }

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

    /* The help bubble is fixed at 430px; on a 360px phone it hung off the
       edge, taking its own explanation with it. */
    .help-tip::after { width: min(92vw, 430px); }

    /* Bulk bars hold five or six buttons. Wrapped, they need breathing room
       or they read as one grey mass. */
    .flex.wrap { row-gap: 10px; }
}
