/* =========================================================================
   Presentation layer — loaded LAST, after index.css and php-app.css.
   =========================================================================

   WHY A SEPARATE FILE

   index.css is src/index.css copied verbatim from the React build. That was a
   deliberate choice — it made the conversion diffable — but it also froze the
   visual design at whatever the SPA happened to look like, including its two
   real weaknesses:

     1. Mobile. The only breakpoint that touched the shell turned the sidebar
        into a horizontally wrapping strip of ten links, which on a phone ate
        roughly half the viewport before a single figure was visible. There was
        no drawer, no hamburger, no touch-target sizing and no safe-area
        handling for notched screens.

     2. Density and rhythm. Three unrelated card treatments (.panel, .card,
        .card.glass), four KPI families with different paddings, borrowed shadow
        values, and proportional numerals in tables of currency — digits of
        different widths, so columns of money never lined up.

   Rather than editing index.css and losing that verbatim property, this file
   layers over it. Loading last means equal-specificity rules win, so nothing
   here needs !important. Delete this one <link> and the app reverts exactly to
   the old appearance.

   WHAT IS DELIBERATELY NOT HERE

   No web font. A Google Fonts <link> is one line and would look sharper still,
   but it is a third-party request on the critical path, it is a privacy
   consideration for a finance app, and it would be the app's only external
   dependency apart from the Chart.js CDN. The stack below picks the best
   grotesque already installed on each platform.
   ========================================================================= */

/* -------------------------------------------------------------------------
   1. Tokens
   ---------------------------------------------------------------------- */
:root {
  /* Type. -apple-system and Segoe UI Variable are optical-sized faces: they
     render small UI text noticeably better than the static Segoe UI the old
     stack asked for first. */
  --sans: -apple-system, BlinkMacSystemFont, 'Segoe UI Variable Text', 'Segoe UI',
          ui-sans-serif, system-ui, Roboto, 'Helvetica Neue', Arial, sans-serif;
  --mono: ui-monospace, 'SF Mono', 'Cascadia Mono', 'Segoe UI Mono', Menlo, Consolas, monospace;

  /* Surfaces. Three levels, not two: a page background, a card, and a raised
     or inset area inside a card. The old palette collapsed the last two. */
  --bg: #f6f8fb;
  --surface: #ffffff;
  --surface-2: #f2f5f9;
  --surface-3: #e9eef5;
  --surface-blur: rgba(255, 255, 255, 0.78);

  --border: #e3e8ef;
  --border-strong: #cfd7e3;

  --text: #101828;
  --text-2: #344054;
  --text-muted: #667085;
  --text-faint: #98a2b3;

  /* One brand hue, three steps. */
  --primary: #1f5fd8;
  --primary-dark: #1a4fb4;
  --primary-light: #4a83ec;
  --primary-soft: #eef4ff;
  --primary-ring: rgba(31, 95, 216, 0.16);

  --accent: #0d9488;
  --accent-soft: #effcf8;
  --teal: #0d9488;

  --green: #16a34a;
  --green-soft: #edfcf2;
  --red: #d92d20;
  --red-soft: #fef3f2;
  --amber: #d97706;
  --amber-soft: #fffaeb;
  --violet: #6938ef;
  --violet-soft: #f5f3ff;
  --blue: #1f5fd8;
  --grey: #667085;

  /* Sidebar has its own ramp: it is dark in both themes, so it cannot reuse
     the surface tokens. */
  --nav-bg: #0b1220;
  --nav-bg-2: #101a2d;
  --nav-text: #aab7c9;
  --nav-text-strong: #ffffff;
  --nav-hover: rgba(255, 255, 255, 0.06);
  --nav-active: rgba(255, 255, 255, 0.10);
  --nav-border: rgba(255, 255, 255, 0.08);

  /* Elevation as a scale rather than two ad-hoc values. Tight, low-opacity
     shadows read as "premium"; large soft ones read as "template". */
  --elev-1: 0 1px 2px rgba(16, 24, 40, 0.05), 0 1px 3px rgba(16, 24, 40, 0.05);
  --elev-2: 0 2px 4px -1px rgba(16, 24, 40, 0.06), 0 4px 12px -2px rgba(16, 24, 40, 0.08);
  --elev-3: 0 8px 16px -4px rgba(16, 24, 40, 0.08), 0 20px 32px -8px rgba(16, 24, 40, 0.12);
  --shadow: var(--elev-1);
  --shadow-lg: var(--elev-3);

  --r-sm: 8px;
  --r-md: 10px;
  --r-lg: 14px;
  --r-xl: 18px;
  --radius: var(--r-lg);

  /* Header heights are referenced by sticky offsets in several places, so they
     are tokens rather than repeated magic numbers. */
  --topbar-h: 64px;
  --sidebar-w: 264px;
}

[data-theme='dark'] {
  --bg: #080d16;
  --surface: #0f1622;
  --surface-2: #151e2c;
  --surface-3: #1c2635;
  --surface-blur: rgba(15, 22, 34, 0.80);

  --border: #1e2836;
  --border-strong: #2c3849;

  --text: #e8edf5;
  --text-2: #c3ccd9;
  --text-muted: #8d9aad;
  --text-faint: #6b7789;

  /* The old dark theme switched the brand from blue to indigo, so the app
     changed identity with the toggle. Same hue, lifted for contrast on a dark
     surface instead. */
  --primary: #4a8cf7;
  --primary-dark: #3b7ae8;
  --primary-light: #7aa9fa;
  --primary-soft: #12203a;
  --primary-ring: rgba(74, 140, 247, 0.22);

  --accent: #2dd4bf;
  --accent-soft: #0c2b28;

  --green: #34d399;
  --green-soft: #0b2a20;
  --red: #f87171;
  --red-soft: #2c1414;
  --amber: #fbbf24;
  --amber-soft: #2e2109;
  --violet: #a78bfa;
  --violet-soft: #1e1b34;
  --blue: #4a8cf7;
  --grey: #8d9aad;

  --nav-bg: #070c14;
  --nav-bg-2: #0c1420;

  --elev-1: 0 1px 2px rgba(0, 0, 0, 0.5);
  --elev-2: 0 4px 12px rgba(0, 0, 0, 0.45);
  --elev-3: 0 16px 40px rgba(0, 0, 0, 0.55);
}

/* -------------------------------------------------------------------------
   2. Base
   ---------------------------------------------------------------------- */
body {
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.5;
  letter-spacing: -0.006em;
  text-rendering: optimizeLegibility;
  -webkit-text-size-adjust: 100%;
}

/* Headings on a real scale, fluid between phone and desktop so a title never
   wraps to three lines on a 360px screen. */
h1 { font-size: clamp(1.35rem, 1.05rem + 1.1vw, 1.75rem); letter-spacing: -0.022em; line-height: 1.2; }
h2 { font-size: clamp(1.15rem, 0.98rem + 0.6vw, 1.35rem); letter-spacing: -0.018em; }
h3 { font-size: 1.02rem; letter-spacing: -0.012em; }
h4 { font-size: 0.9rem; letter-spacing: -0.006em; }

.muted { color: var(--text-muted); font-size: 0.875rem; }
.hint  { color: var(--text-muted); font-size: 0.8rem; }

/* Every figure in the app is a number in a column of other numbers. Tabular
   numerals give all digits the same advance width, so decimal points line up
   down a table and a value does not jitter as it updates. This one property is
   the single biggest legibility gain in the whole file. */
.table td, .table th,
.stat-value, .kpi-value, .glass-kpi-value, .perf-kpi-value,
.exec-item b, .wp-chip b, .mini b, .wpu-cell b,
.dl dd, .preview-row, .perf-client-meta, .rank-meta, .pp-val, .pp-pct,
.perf-num, .stat-sub, .kpi-sub, .glass-kpi-sub {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* One visible focus treatment everywhere, including for keyboard users on
   elements that never had one (nav links, table rows, cards). */
:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-radius: 4px;
}
.sidebar :focus-visible { outline-color: #fff; }

::selection { background: var(--primary-ring); color: var(--text); }

/* Scrollbars, where the browser lets us. A 14px default gutter inside a card
   looks like a mistake. */
* { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 99px;
  border: 3px solid transparent;
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--text-faint); background-clip: content-box; }

/* Keyboard users land here first; it stays hidden until focused. */
.skip-link {
  position: absolute; top: -100px; left: 12px; z-index: 200;
  background: var(--primary); color: #fff;
  padding: 10px 16px; border-radius: var(--r-md); font-weight: 600; font-size: 0.9rem;
  text-decoration: none; box-shadow: var(--elev-3);
}
.skip-link:focus { top: 12px; }

/* -------------------------------------------------------------------------
   3. Icons
   ---------------------------------------------------------------------- */
.ico {
  flex: none;
  vertical-align: -0.18em;   /* optical baseline against 15px text */
  stroke: currentColor;
}

/* A glyph in a tinted rounded tile — used where a bare 20px stroke would be
   lost in whitespace (empty states, report cards). */
.icon-tile {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: var(--r-md);
  background: var(--primary-soft); color: var(--primary);
}
.icon-tile.lg { width: 64px; height: 64px; border-radius: var(--r-lg); }
.icon-tile.grey  { background: var(--surface-2); color: var(--text-muted); }
.icon-tile.green { background: var(--green-soft); color: var(--green); }
.icon-tile.red   { background: var(--red-soft); color: var(--red); }
.icon-tile.amber { background: var(--amber-soft); color: var(--amber); }

/* -------------------------------------------------------------------------
   4. Shell
   ---------------------------------------------------------------------- */
.app-shell {
  grid-template-columns: var(--sidebar-w) 1fr;
  background: var(--bg);
}

.sidebar {
  background: linear-gradient(180deg, var(--nav-bg-2) 0%, var(--nav-bg) 100%);
  border-right: 1px solid var(--nav-border);
  color: var(--nav-text);
  padding: 18px 12px 14px;
  gap: 4px;
  z-index: 40;
}

.brand {
  display: flex; align-items: center; gap: 11px;
  padding: 4px 10px 16px;
  margin-bottom: 6px;
  border-bottom: 1px solid var(--nav-border);
}
.brand-link { display: flex; align-items: center; gap: 11px; text-decoration: none; min-width: 0; flex: 1; }
.brand svg:first-child { border-radius: 10px; box-shadow: 0 4px 12px rgba(31, 95, 216, 0.35); }
.brand-name { color: #fff; font-size: 1.02rem; font-weight: 700; letter-spacing: -0.015em; }
.brand-sub {
  font-size: 0.68rem; color: var(--text-faint); font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.07em; margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* The nav scrolls independently of the brand and the user footer, so a long
   admin menu never pushes the account block off-screen. */
.nav {
  flex-direction: column; flex-wrap: nowrap;
  gap: 1px; flex: 1; min-height: 0;
  overflow-y: auto; overscroll-behavior: contain;
  padding: 4px 0;
  margin: 0 -4px;
}
.nav::-webkit-scrollbar { width: 6px; }
.nav::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.14); border: 2px solid transparent; }

/* Section headers. Ten flat links read as a list; four labelled groups read as
   an information architecture. */
.nav-group {
  font-size: 0.64rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.1em; color: #5c6b80;
  margin: 14px 0 5px; padding: 0 14px;
}
.nav-group:first-child { margin-top: 2px; }

.nav-item {
  position: relative;
  gap: 11px; padding: 9px 13px; border-radius: var(--r-md);
  color: var(--nav-text); font-size: 0.895rem; font-weight: 500;
  letter-spacing: -0.004em; line-height: 1.35;
  transition: background 0.14s ease, color 0.14s ease;
}
.nav-item .ico { color: #7f8ea3; transition: color 0.14s ease; }
.nav-item:hover { background: var(--nav-hover); color: #e9eef6; }
.nav-item:hover .ico { color: #b9c6d8; }

/* Active state: a tinted row with an accent rail, not a solid blue block. The
   block version dominated the sidebar and fought the brand mark for attention. */
.nav-item.active {
  background: var(--nav-active);
  color: #fff;
  font-weight: 600;
}
.nav-item.active::before {
  content: '';
  position: absolute; left: -4px; top: 50%; transform: translateY(-50%);
  width: 3px; height: 20px; border-radius: 0 3px 3px 0;
  background: var(--primary-light);
}
.nav-item.active .ico { color: var(--primary-light); }
.nav-icon { width: auto; display: inline-flex; align-items: center; }

.sidebar-footer {
  gap: 10px; padding: 12px 8px 0; margin-top: 6px;
  border-top: 1px solid var(--nav-border);
  padding-bottom: env(safe-area-inset-bottom, 0);
}
.avatar {
  width: 36px; height: 36px; flex: none; font-size: 0.85rem; letter-spacing: 0.02em;
  background: linear-gradient(135deg, var(--primary), var(--accent));
  box-shadow: 0 2px 8px rgba(31, 95, 216, 0.35);
}
.avatar.sm { width: 30px; height: 30px; font-size: 0.75rem; border-radius: 9px; }
.who { min-width: 0; }
.who-name {
  font-size: 0.865rem; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.who-role {
  font-size: 0.7rem; color: var(--text-faint); font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.06em;
}

/* -------------------------------------------------------------------------
   5. Topbar
   ---------------------------------------------------------------------- */
.topbar {
  gap: 12px;
  min-height: var(--topbar-h);
  padding: 10px clamp(14px, 2.2vw, 28px);
  background: var(--surface-blur);
  backdrop-filter: saturate(160%) blur(12px);
  -webkit-backdrop-filter: saturate(160%) blur(12px);
  border-bottom: 1px solid var(--border);
  z-index: 30;
  padding-top: max(10px, env(safe-area-inset-top, 0));
}
.topbar-heading { min-width: 0; flex: 1; }
.topbar-title {
  font-size: 0.95rem; font-weight: 650; color: var(--text);
  letter-spacing: -0.012em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.topbar-sub {
  font-size: 0.72rem; color: var(--text-muted); font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.topbar-actions { gap: 6px; }

/* A square, quiet control for icon-only actions. 40px is above the 24px minimum
   for pointer targets and close to the 44px touch guidance without looking
   oversized on a desktop toolbar. */
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; flex: none;
  padding: 0; border: 1px solid transparent; border-radius: var(--r-md);
  background: transparent; color: var(--text-muted);
  cursor: pointer; transition: background 0.14s ease, color 0.14s ease, border-color 0.14s ease;
}
.icon-btn:hover { background: var(--surface-2); color: var(--text); border-color: var(--border); }
.icon-btn:active { background: var(--surface-3); }

/* The account block: avatar plus two lines, collapsing to the avatar alone on
   narrow screens. The old topbar printed a raw email address in muted grey,
   which is both the least useful identifier and the widest. */
.user-chip {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 4px 10px 4px 4px; border-radius: 99px;
  border: 1px solid var(--border); background: var(--surface);
  max-width: 240px;
}
.user-chip-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.user-chip-text b {
  font-size: 0.8rem; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.user-chip-text small {
  font-size: 0.68rem; color: var(--text-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Theme toggle holds both glyphs; CSS shows the one for the *other* theme, so
   the button always depicts what pressing it will do. No JS icon swapping. */
.theme-toggle { font-size: inherit; padding: 0; }
.theme-toggle .ico-sun, .theme-toggle .ico-moon { display: inline-flex; }
[data-theme='light'] .theme-toggle .ico-sun,
[data-theme='dark'] .theme-toggle .ico-moon { display: none; }

/* Hamburger and drawer close button: desktop-hidden by default. */
.nav-toggle, .sidebar-close { display: none; }

.nav-backdrop {
  position: fixed; inset: 0; z-index: 35;
  background: rgba(8, 13, 22, 0.55);
  backdrop-filter: blur(2px);
  border: 0; padding: 0; margin: 0;
  opacity: 0; pointer-events: none;
  transition: opacity 0.2s ease;
}

/* -------------------------------------------------------------------------
   6. Content and page furniture
   ---------------------------------------------------------------------- */
.content {
  padding: clamp(16px, 2.2vw, 28px);
  padding-bottom: max(clamp(16px, 2.2vw, 28px), env(safe-area-inset-bottom, 0));
}
/* Very wide monitors: stop a data table stretching to 3000px, which makes rows
   impossible to track across. */
.page { max-width: 1680px; margin: 0 auto; }

.page-head {
  align-items: center; gap: 14px;
  margin-bottom: 20px; padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
}
.page-head h1 + .muted { margin-top: 4px; }
.page-actions { gap: 8px; flex-wrap: wrap; }

/* -------------------------------------------------------------------------
   7. Controls
   ---------------------------------------------------------------------- */
.btn {
  gap: 7px; border-radius: var(--r-md);
  padding: 9px 15px; min-height: 40px;
  font-size: 0.885rem; font-weight: 600; letter-spacing: -0.004em;
  transition: background 0.14s ease, border-color 0.14s ease, color 0.14s ease, box-shadow 0.14s ease, transform 0.08s ease;
}
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn .ico { margin: 0 -1px; }

.btn-primary {
  background: var(--primary); border-color: var(--primary);
  box-shadow: 0 1px 2px rgba(16, 24, 40, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.14);
}
.btn-primary:hover:not(:disabled) { background: var(--primary-dark); border-color: var(--primary-dark); }
.btn-outline { border-color: var(--border-strong); color: var(--text-2); box-shadow: var(--elev-1); }
.btn-outline:hover { border-color: var(--primary); color: var(--primary); background: var(--primary-soft); }
.btn-ghost { border-color: transparent; }
.btn-ghost:hover { background: var(--surface-2); }
.btn-sm { min-height: 34px; padding: 6px 12px; font-size: 0.82rem; }
.btn-lg { min-height: 46px; padding: 12px 18px; font-size: 0.95rem; }

/* Grouped export buttons read as one control rather than three. */
.export-group { border-color: var(--border-strong); border-radius: var(--r-md); padding: 3px; gap: 3px; background: var(--surface); }
.export-group .btn { min-height: 32px; border-radius: 7px; }
.export-group .btn:hover { background: var(--surface-2); }

.field > span,
.filter-field label {
  font-size: 0.775rem; font-weight: 600; color: var(--text-2);
  text-transform: none; letter-spacing: 0;
}
.field input, .select, .search,
.filter-field select, .filter-field input,
.calls-inputs .field select,
select, textarea {
  min-height: 40px;
  padding: 9px 11px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  background: var(--surface); color: var(--text);
  font-family: inherit; font-size: 0.9rem;
  transition: border-color 0.14s ease, box-shadow 0.14s ease;
  /* 16px on iOS avoids the automatic zoom-on-focus; see the 640px block. */
}
.field input:hover, .select:hover, .search:hover, select:hover { border-color: var(--text-faint); }
.field input:focus, .select:focus, .search:focus,
.filter-field select:focus, .filter-field input:focus,
select:focus, textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3.5px var(--primary-ring);
}
.field input::placeholder, .search::placeholder { color: var(--text-faint); }

/* Native selects get a consistent chevron instead of the platform's own, which
   differs wildly between Windows, macOS and Android. */
select:not([multiple]) {
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23667085' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 32px;
}
[data-theme='dark'] select:not([multiple]) {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238d9aad' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
}

/* A magnifier drawn in CSS, so the search box no longer needs 🔍 in its
   placeholder text — which was also being read aloud by screen readers. */
.search {
  padding-left: 36px;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17' viewBox='0 0 24 24' fill='none' stroke='%2398a2b3' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-4.3-4.3'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 11px center;
}

.filters-bar, form.filters-bar { gap: 10px 12px; }
.filter-field label { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.045em; color: var(--text-muted); }

.alert { border-radius: var(--r-md); padding: 11px 14px; font-size: 0.88rem; font-weight: 500; display: flex; gap: 9px; align-items: flex-start; }
.alert-error { background: var(--red-soft); color: var(--red); border-color: color-mix(in srgb, var(--red) 30%, transparent); }
.alert-info { background: var(--primary-soft); color: var(--primary-dark); border-color: color-mix(in srgb, var(--primary) 26%, transparent); }

/* -------------------------------------------------------------------------
   8. Cards
   ---------------------------------------------------------------------- */
.card, .panel {
  border-radius: var(--r-lg);
  border: 1px solid var(--border);
  background: var(--surface);
  box-shadow: var(--elev-1);
  padding: clamp(14px, 1.6vw, 20px);
  margin-bottom: 16px;
}

/* The glass treatment was a translucent white gradient — invisible against the
   near-white page background, and it made backdrop-filter run on a dozen
   elements per page for no visual gain. Cards are now flat and uniform; depth
   comes from the border and one shadow step. */
.card.glass {
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--elev-1);
  backdrop-filter: none; -webkit-backdrop-filter: none;
}
[data-theme='dark'] .card.glass {
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--elev-1);
}

.card-head, .panel-head {
  gap: 12px; margin-bottom: 14px; padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}
.card-head h3, .panel-head h2, .panel-head h3 { margin: 0; font-size: 0.985rem; font-weight: 650; }

/* -------------------------------------------------------------------------
   9. KPI families
   ---------------------------------------------------------------------- */

/* The dashboard tiles were six saturated gradient blocks in a row — striking in
   a screenshot, exhausting to read, and impossible to scan because every tile
   shouted equally. They are now white cards with a coloured icon, so the
   *numbers* carry the emphasis and colour means something (green = gain, red =
   risk) instead of just marking position. */
.glass-kpi-grid { grid-template-columns: repeat(auto-fit, minmax(214px, 1fr)); gap: 14px; margin-bottom: 20px; }
.glass-kpi {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--elev-1);
  color: var(--text);
  padding: 15px 16px;
  gap: 13px;
  align-items: flex-start;
  animation: none;
  transition: box-shadow 0.16s ease, border-color 0.16s ease, transform 0.16s ease;
}
.glass-kpi:hover { box-shadow: var(--elev-2); border-color: var(--border-strong); transform: translateY(-1px); }
.glass-kpi::after { display: none; }
.glass-kpi-icon {
  width: 40px; height: 40px; border-radius: var(--r-md);
  font-size: inherit;
  background: var(--surface-2); color: var(--text-muted);
}
.glass-kpi-label {
  font-size: 0.775rem; font-weight: 600; color: var(--text-muted); opacity: 1;
  letter-spacing: 0.002em;
}
.glass-kpi-value {
  font-size: clamp(1.22rem, 1.05rem + 0.5vw, 1.45rem);
  font-weight: 700; letter-spacing: -0.028em; margin-top: 3px; color: var(--text);
}
.glass-kpi-sub { font-size: 0.735rem; color: var(--text-muted); opacity: 1; margin-top: 3px; }

/* Tone now colours the icon and a hairline top edge, not the whole tile. */
.glass-kpi.tone-blue,
.glass-kpi.tone-cyan,
.glass-kpi.tone-green,
.glass-kpi.tone-orange,
.glass-kpi.tone-purple,
.glass-kpi.tone-red { background: var(--surface); }
.glass-kpi.tone-blue   .glass-kpi-icon { background: var(--primary-soft); color: var(--primary); }
.glass-kpi.tone-cyan   .glass-kpi-icon { background: var(--accent-soft); color: var(--accent); }
.glass-kpi.tone-green  .glass-kpi-icon { background: var(--green-soft); color: var(--green); }
.glass-kpi.tone-orange .glass-kpi-icon { background: var(--amber-soft); color: var(--amber); }
.glass-kpi.tone-purple .glass-kpi-icon { background: var(--violet-soft); color: var(--violet); }
.glass-kpi.tone-red    .glass-kpi-icon { background: var(--red-soft); color: var(--red); }
.glass-kpi.tone-green  .glass-kpi-value { color: var(--green); }
.glass-kpi.tone-red    .glass-kpi-value { color: var(--red); }

.glass-kpi.skeleton-card { background: var(--surface); }

/* The other three tile families, brought onto the same geometry. */
.kpi, .stat-card, .perf-kpi, .wp-chip {
  border-radius: var(--r-lg);
  border: 1px solid var(--border);
  background: var(--surface);
  box-shadow: var(--elev-1);
  transition: box-shadow 0.16s ease, border-color 0.16s ease, transform 0.16s ease;
}
.kpi:hover, .perf-kpi:hover { transform: translateY(-1px); box-shadow: var(--elev-2); border-color: var(--border-strong); }
.kpi { border-top-width: 2px; padding: 15px 16px; }
.kpi-value, .stat-value { letter-spacing: -0.028em; font-weight: 700; }
.kpi-label, .stat-label { font-size: 0.775rem; color: var(--text-muted); font-weight: 600; }
.stat-card { border-left-width: 3px; }

.perf-kpi { border-left-width: 3px; padding: 15px 16px; }
.perf-kpi-top { gap: 9px; }
.perf-kpi-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: var(--r-sm); flex: none;
  background: var(--surface-2); color: var(--text-muted); font-size: inherit;
}
.perf-kpi.tone-green  .perf-kpi-icon { background: var(--green-soft); color: var(--green); }
.perf-kpi.tone-red    .perf-kpi-icon { background: var(--red-soft); color: var(--red); }
.perf-kpi.tone-blue   .perf-kpi-icon { background: var(--primary-soft); color: var(--primary); }
.perf-kpi.tone-orange .perf-kpi-icon { background: var(--amber-soft); color: var(--amber); }
.perf-kpi-label { font-size: 0.775rem; font-weight: 600; }
.perf-kpi-value { font-size: 1.3rem; letter-spacing: -0.026em; margin-top: 8px; }

.exec-strip { border-radius: var(--r-lg); background: var(--border); }
.exec-item b { letter-spacing: -0.026em; font-weight: 700; }
.wp-chip { border-left-width: 3px; border-radius: var(--r-lg); }
.wp-chip b { letter-spacing: -0.024em; }
.mini { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-md); }
.wpu-cell { border-radius: var(--r-md); }

/* -------------------------------------------------------------------------
   10. Tables
   ---------------------------------------------------------------------- */
.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}

.table { font-size: 0.875rem; }
.table th {
  padding: 9px 12px;
  font-size: 0.7rem; font-weight: 700;
  letter-spacing: 0.055em; color: var(--text-muted);
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.table thead th:first-child { border-top-left-radius: var(--r-sm); border-bottom-left-radius: var(--r-sm); }
.table thead th:last-child  { border-top-right-radius: var(--r-sm); border-bottom-right-radius: var(--r-sm); }
.table td { padding: 11px 12px; color: var(--text-2); border-bottom: 1px solid var(--border); }
.table tbody tr { transition: background 0.1s ease; }
.table tbody tr:hover { background: var(--surface-2); }
.table td .link, .table td a { font-weight: 600; }
.cell-strong { color: var(--text); font-weight: 650; }
.cell-sub { color: var(--text-muted); font-size: 0.775rem; }
.pos { color: var(--green); }
.danger { color: var(--red); }

/* Fading the right edge is the only cue that a table scrolls sideways, and the
   cue has to disappear once you reach the end or it reads as "there is always
   more" and you keep swiping.
 *
 * A mask rather than an overlaid gradient: an overlay needs a positioned
 * ancestor and has to be re-coloured for dark mode, whereas a mask works on
 * whatever is actually behind the table. app.js sets both classes, because CSS
 * cannot tell whether a given table overflows. */
.table-scroll.is-scrollable {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 34px), transparent 100%);
  mask-image: linear-gradient(to right, #000 calc(100% - 34px), transparent 100%);
}
.table-scroll.is-scrollable.at-end {
  -webkit-mask-image: none;
  mask-image: none;
}

/* -------------------------------------------------------------------------
   11. Badges, tags, chips
   ---------------------------------------------------------------------- */
.badge, .tag, .perf-status, .notif-badge {
  display: inline-flex; align-items: center; gap: 5px;
  font-weight: 600; letter-spacing: 0.008em;
  border: 1px solid transparent;
}
.badge {
  padding: 3px 9px; font-size: 0.735rem; border-radius: 7px;
  text-transform: capitalize;
}
.badge-green  { background: var(--green-soft); color: var(--green); border-color: color-mix(in srgb, var(--green) 22%, transparent); }
.badge-red    { background: var(--red-soft); color: var(--red); border-color: color-mix(in srgb, var(--red) 22%, transparent); }
.badge-amber  { background: var(--amber-soft); color: var(--amber); border-color: color-mix(in srgb, var(--amber) 24%, transparent); }
.badge-blue   { background: var(--primary-soft); color: var(--primary); border-color: color-mix(in srgb, var(--primary) 20%, transparent); }
.badge-violet { background: var(--violet-soft); color: var(--violet); border-color: color-mix(in srgb, var(--violet) 20%, transparent); }
.badge-grey   { background: var(--surface-2); color: var(--text-muted); border-color: var(--border); }

.tag { padding: 3px 10px; font-size: 0.735rem; border-radius: 7px; border-color: var(--border); }
.chip { border-radius: 8px; font-weight: 600; }
.chip.active { background: var(--primary); border-color: var(--primary); }
.trust-chip { border-radius: 8px; }

/* -------------------------------------------------------------------------
   12. Lists, empty states, pagination
   ---------------------------------------------------------------------- */
.empty { padding: 34px 20px; color: var(--text-muted); font-size: 0.9rem; }
.empty-state, .perf-empty { padding: 48px 24px; }
.empty-state .empty-icon, .perf-empty-icon { font-size: inherit; margin-bottom: 14px; display: block; }
.empty-state h3, .perf-empty h3 { margin: 0 0 6px; font-size: 1.05rem; }
.empty-state .muted, .perf-empty .muted { max-width: 46ch; margin-inline: auto; }
.empty-state .page-actions { justify-content: center; margin-top: 18px; }

.rank-list li, .pp-legend li, .activity-list li, .notif-list li { border-color: var(--border); }
.rank-list li { border-radius: var(--r-sm); padding: 9px 10px; border-bottom: 1px solid var(--border); }
.rank-list li:last-child { border-bottom: none; }
.pp-legend li { border-radius: var(--r-md); }
.pp-legend li:hover { transform: none; background: var(--surface-2); border-color: var(--border-strong); }
.notif-badge { padding: 2px 8px; font-size: 0.66rem; border-radius: 6px; text-transform: uppercase; }

.perf-client { border-radius: var(--r-md); border-color: var(--border); transition: border-color 0.14s ease, background 0.14s ease; }
.perf-client:hover { border-color: var(--border-strong); }
.perf-client.active { border-color: var(--primary); background: var(--primary-soft); box-shadow: inset 3px 0 0 var(--primary); }
.perf-code { letter-spacing: 0.04em; }

.report-card, a.report-card {
  border-radius: var(--r-lg); padding: 18px 14px; gap: 10px;
  border-color: var(--border); box-shadow: var(--elev-1);
  font-size: 0.87rem; font-weight: 600;
}
.report-card:hover { transform: translateY(-2px); box-shadow: var(--elev-2); border-color: var(--primary); }
.report-icon { font-size: inherit; }
.report-card .icon-tile { width: 38px; height: 38px; }
.report-card.active { background: var(--primary-soft); border-color: var(--primary); box-shadow: inset 0 0 0 1px var(--primary); }
.report-card.active .icon-tile { background: var(--primary); color: #fff; }

.pager { gap: 6px; padding-top: 14px; border-top: 1px solid var(--border); margin-top: 4px; }

.modal { border-radius: var(--r-xl); box-shadow: var(--elev-3); padding: 20px 22px; }
.modal-head { padding-bottom: 12px; border-bottom: 1px solid var(--border); }

.dl > div { border-bottom-style: solid; border-color: var(--border); }
.dl dt { color: var(--text-muted); font-size: 0.85rem; }
.dl dd { font-weight: 600; letter-spacing: -0.008em; }

.perf-score { border-radius: var(--r-lg); }
.perf-num { letter-spacing: -0.03em; }

/* -------------------------------------------------------------------------
   13. Auth pages
   ---------------------------------------------------------------------- */
.auth-page { grid-template-columns: 1.1fr 1fr; }
.auth-hero { background: linear-gradient(155deg, #070d18 0%, #0f1d38 48%, #08333f 100%); padding: clamp(32px, 5vw, 64px); }
.auth-hero-inner { max-width: 480px; }
.auth-hero h1 {
  font-size: clamp(1.9rem, 1.3rem + 2.2vw, 2.65rem);
  letter-spacing: -0.03em; line-height: 1.12; margin: 28px 0 14px;
}
.auth-lead { color: #b6c2d4; font-size: clamp(0.95rem, 0.9rem + 0.2vw, 1.06rem); }
.auth-features { gap: 13px; margin-top: 32px; }
.auth-features li { font-size: 0.95rem; color: #dbe3ee; align-items: flex-start; }
.tick {
  width: 22px; height: 22px; border-radius: 6px; margin-top: 1px;
  background: rgba(45, 212, 191, 0.16); color: #5eead4;
}
.trust-row { gap: 8px; margin-top: 32px; }
.trust-chip {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 0.75rem; padding: 6px 11px; color: #c3cedd;
}
.auth-card { max-width: 400px; }
.auth-card h2 { color: var(--text); font-size: clamp(1.35rem, 1.15rem + 0.7vw, 1.6rem); }
.auth-card-brand { margin-bottom: 26px; }
.brand-word.sm { color: var(--text); }
.auth-form-wrap { padding: clamp(24px, 4vw, 48px); }
.auth-switch { margin-top: 18px; color: var(--text-muted); }

/* -------------------------------------------------------------------------
   14. Charts
   ---------------------------------------------------------------------- */
.chart-grid { gap: 16px; }
.chart-box { margin-top: 2px; }

/* -------------------------------------------------------------------------
   14b. Client access — credentials, uploads, password meter
   ---------------------------------------------------------------------- */

/* Checkbox rows. A label wrapping the input so the text is part of the hit
   target, which matters most on a phone. */
.check {
  display: flex; align-items: flex-start; gap: 9px;
  margin: 4px 0 14px; font-size: 0.88rem; color: var(--text-2);
  cursor: pointer;
}
.check input[type='checkbox'] {
  width: 18px; height: 18px; margin: 1px 0 0; flex: none;
  accent-color: var(--primary); cursor: pointer;
}

.access-meta { grid-template-columns: 1fr 1fr; display: grid; gap: 10px 24px; margin-bottom: 18px; }
.access-meta code, .table code, .cell-sub code {
  font-family: var(--mono); font-size: 0.85em;
  background: var(--surface-2); border: 1px solid var(--border);
  padding: 1px 6px; border-radius: 5px;
}

/* The one place a plaintext password is ever rendered. Deliberately loud: it is
   shown once and cannot be recovered, so it must not be mistaken for a field
   the user can come back to. */
.reveal-card { border-color: var(--amber); box-shadow: 0 0 0 3px var(--amber-soft); }
.reveal-value {
  display: flex; align-items: center; gap: 12px;
  margin: 12px 0; padding: 14px 16px;
  background: var(--surface-2); border: 1px dashed var(--border-strong); border-radius: var(--r-md);
}
.reveal-value code {
  font-family: var(--mono); font-size: clamp(1.05rem, 0.9rem + 0.7vw, 1.4rem);
  font-weight: 700; letter-spacing: 0.06em;
  /* Selectable in one gesture — this gets copied, not read. */
  user-select: all;
}

.reset-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; align-items: start; }
.reset-grid > form { padding: 16px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--surface-2); }
.reset-grid h4 { margin: 0 0 6px; font-size: 0.92rem; }
.reset-grid .muted { margin: 0 0 12px; }
.reset-grid .form-actions { margin-top: 12px; }

/* ---- document slots ---- */
.doc-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-bottom: 6px; }
.doc-slot { border: 1px solid var(--border); border-radius: var(--r-md); padding: 15px; background: var(--surface-2); }
.doc-slot-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.doc-slot-head h4 { margin: 0; font-size: 0.9rem; }

.doc-current { display: flex; gap: 13px; margin-bottom: 13px; align-items: flex-start; }
.doc-thumb {
  width: 74px; height: 74px; object-fit: cover; flex: none;
  border-radius: var(--r-sm); border: 1px solid var(--border-strong); background: var(--surface);
  display: block;
}
.doc-file {
  width: 74px; height: 74px; flex: none;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  border-radius: var(--r-sm); border: 1px solid var(--border-strong); background: var(--surface);
  color: var(--red); text-decoration: none;
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.05em;
}
.doc-file:hover, .doc-thumb:hover { border-color: var(--primary); }
.doc-meta { min-width: 0; }
.doc-actions { margin-top: 5px; }

/* A styled label wrapping a real file input: the input keeps its native
   keyboard and screen-reader behaviour, and is only visually replaced. Hiding
   it with display:none would take it out of the tab order entirely. */
.doc-drop { display: block; cursor: pointer; }
.doc-drop input[type='file'] {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.doc-drop-inner {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 13px; border: 1.5px dashed var(--border-strong); border-radius: var(--r-md);
  background: var(--surface); color: var(--text-muted);
  font-size: 0.85rem; font-weight: 600;
  transition: border-color 0.14s ease, color 0.14s ease, background 0.14s ease;
}
.doc-drop:hover .doc-drop-inner { border-color: var(--primary); color: var(--primary); background: var(--primary-soft); }
/* :focus-within, because the focus lands on the visually-hidden input. Without
   this a keyboard user cannot tell where they are. */
.doc-drop:focus-within .doc-drop-inner {
  border-color: var(--primary); color: var(--primary);
  box-shadow: 0 0 0 3.5px var(--primary-ring);
}

.doc-preview:empty { display: none; }
.doc-chip {
  display: flex; align-items: center; gap: 10px; margin-top: 9px;
  padding: 8px 10px; border: 1px solid var(--border-strong); border-radius: var(--r-md);
  background: var(--surface);
}
.doc-chip.invalid { border-color: var(--red); background: var(--red-soft); }
.doc-chip-thumb { width: 36px; height: 36px; object-fit: cover; border-radius: 6px; flex: none; }
.doc-chip-ext {
  width: 36px; height: 36px; flex: none; border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  background: var(--red-soft); color: var(--red);
  font-size: 0.62rem; font-weight: 800; letter-spacing: 0.04em;
}
.doc-chip-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.3; }
.doc-chip-text b { font-size: 0.82rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doc-chip-text small { font-size: 0.72rem; color: var(--text-muted); }
.doc-chip.invalid .doc-chip-text small { color: var(--red); font-weight: 600; }
.doc-chip-remove {
  margin-left: auto; flex: none;
  width: 28px; height: 28px; border: 0; border-radius: 7px;
  background: transparent; color: var(--text-muted);
  font-size: 1.25rem; line-height: 1; cursor: pointer;
}
.doc-chip-remove:hover { background: var(--red-soft); color: var(--red); }

.doc-remove-row { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); }

/* ---- password strength ---- */
.pw-meter:empty { display: none; }
.pw-meter { margin: -6px 0 14px; }
.pw-bar { display: block; height: 4px; border-radius: 99px; background: var(--surface-3); overflow: hidden; }
.pw-bar i { display: block; height: 100%; border-radius: 99px; background: var(--red); transition: width 0.18s ease, background 0.18s ease; }
.pw-meter.level-fair   .pw-bar i { background: var(--amber); }
.pw-meter.level-good   .pw-bar i { background: var(--primary); }
.pw-meter.level-strong .pw-bar i { background: var(--green); }
.pw-rules { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 7px; }
.pw-rule { font-size: 0.74rem; font-weight: 600; color: var(--text-faint); }
.pw-rule.ok { color: var(--green); }

/* -------------------------------------------------------------------------
   15. Responsive
   ----------------------------------------------------------------------
   Breakpoints, and why each one exists:

     1400px  wide desktop — a little more sidebar, wider gutters
     1200px  laptop — narrow the sidebar before the content gets squeezed
     1023px  tablet & phone — the sidebar becomes an off-canvas drawer
      760px  small tablet / large phone — single-column grids
      560px  phone — condensed topbar, stacked toolbars, 16px inputs
   ---------------------------------------------------------------------- */

@media (min-width: 1400px) {
  :root { --sidebar-w: 276px; }
}

@media (max-width: 1200px) {
  :root { --sidebar-w: 230px; }
  .nav-item { padding: 8px 11px; font-size: 0.865rem; }
  .chart-grid { grid-template-columns: 1fr; }
  .chart-grid .col-2 { grid-column: span 1; }
}

/* ---- the drawer ------------------------------------------------------- */
@media (max-width: 1023px) {
  .app-shell { grid-template-columns: 1fr; }

  /* index.css turns the sidebar into a static wrapping row below 900px. All of
     that is undone here: it becomes a fixed off-canvas panel instead. */
  .sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    width: min(84vw, 310px);
    height: 100%;
    flex-direction: column;
    flex-wrap: nowrap;
    padding: 16px 12px 12px;
    transform: translateX(-100%);
    transition: transform 0.24s cubic-bezier(0.4, 0, 0.2, 1);
    box-shadow: none;
    will-change: transform;
    padding-top: max(16px, env(safe-area-inset-top, 0));
  }
  .nav { flex-direction: column; flex-wrap: nowrap; }
  .sidebar-footer { border-top: 1px solid var(--nav-border); }

  body.nav-open .sidebar { transform: none; box-shadow: var(--elev-3); }
  body.nav-open .nav-backdrop { opacity: 1; pointer-events: auto; }
  /* Locking the body is what stops the page behind the drawer scrolling under
     a finger drag on iOS. */
  body.nav-open { overflow: hidden; }

  .nav-toggle { display: inline-flex; }
  .sidebar-close { display: inline-flex; margin-left: auto; color: var(--nav-text); }
  .sidebar-close:hover { background: var(--nav-hover); color: #fff; border-color: transparent; }

  .topbar { position: sticky; top: 0; }
}

@media (max-width: 760px) {
  .detail-grid, .form-layout, .grid-2, .perf-layout,
  .detail-cols, .pp-wrap, .wpu-inputs, .mini-grid,
  .doc-grid, .reset-grid, .access-meta { grid-template-columns: 1fr; }
  .glass-kpi-grid, .kpi-grid, .perf-kpi-grid, .stat-grid { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
  .glass-kpi { padding: 13px; gap: 11px; }
  .glass-kpi-icon { width: 34px; height: 34px; }
  .glass-kpi-value { font-size: 1.16rem; }
  .exec-strip { grid-template-columns: 1fr 1fr; }
  .report-cards { grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); }
  .preview, .perf-list { position: static; }
  .perf-client-list { max-height: none; }

  .page-head { flex-direction: column; align-items: stretch; }
  .page-actions { width: 100%; }
  .page-actions .btn { flex: 1 1 auto; }

  /* Wide financial tables: pin the first column (always the client or the date)
     so a row stays identifiable while the figures scroll under it. */
  .table-scroll td:first-child,
  .table-scroll th:first-child {
    position: sticky; left: 0; z-index: 1;
    background: var(--surface);
    box-shadow: 1px 0 0 var(--border);
  }
  .table-scroll th:first-child { background: var(--surface-2); }
  .table tbody tr:hover td:first-child { background: var(--surface-2); }
}

@media (max-width: 560px) {
  .topbar { padding: 8px 12px; gap: 8px; }
  .topbar-sub { display: none; }
  .topbar-user { display: none; }
  .user-chip { padding: 3px; border: 0; background: transparent; }
  .user-chip-text { display: none; }
  .icon-btn { width: 38px; height: 38px; }

  .content { padding: 12px; }
  .card, .panel { padding: 14px; border-radius: 12px; }
  .card-head { margin-bottom: 12px; padding-bottom: 10px; }
  .table-scroll { margin: 0 -14px; padding: 0 14px; }

  /* iOS zooms the whole page in when a focused input is under 16px. Bumping the
     font size is the only reliable way to stop it, and it has to be here rather
     than globally or desktop controls look oversized. */
  .field input, .select, .search, select, textarea,
  .filter-field select, .filter-field input { font-size: 16px; min-height: 44px; }

  .btn { min-height: 44px; }
  .filters-bar > *, form.filters-bar > * { flex: 1 1 100%; min-width: 0; }
  .filter-field.grow { min-width: 0; }
  .glass-kpi-grid, .kpi-grid, .perf-kpi-grid, .stat-grid { grid-template-columns: 1fr 1fr; }
  .exec-strip { grid-template-columns: 1fr; }
  .wp-summary { grid-template-columns: 1fr 1fr; }
  .report-actions, .calls-actions, .wpu-actions, .form-actions { width: 100%; }
  .report-actions .btn { flex: 1 1 auto; }
  .dl > div { flex-direction: column; gap: 2px; }
  .dl dd { text-align: left; }
  .auth-form-wrap { padding: 20px 16px; }
  .modal { padding: 16px; border-radius: 14px; }
}

@media (max-width: 380px) {
  .glass-kpi-grid, .kpi-grid, .perf-kpi-grid, .stat-grid, .wp-summary { grid-template-columns: 1fr; }
}

/* -------------------------------------------------------------------------
   16. Preferences
   ---------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

@media (prefers-contrast: more) {
  :root { --border: #b5bece; --border-strong: #8f9aad; --text-muted: #4a5567; }
  [data-theme='dark'] { --border: #3a4658; --border-strong: #55637a; --text-muted: #a9b5c6; }
}

/* Chrome added by this file that has no meaning on paper. print.css already
   hides the sidebar and topbar; these are the new elements. */
@media print {
  .skip-link, .nav-backdrop, .nav-toggle, .sidebar-close, .user-chip, .icon-btn { display: none !important; }
  .page { max-width: none; }
  .icon-tile { border: none !important; }
}
