/* ============================================================
   UI v6 — doc-10 design-system enforcement layer.
   Loaded AFTER premium.css + theme-v5.css. Everything here is
   expressed in tokens (tokens.css) only. This layer:
   - paints body explicitly + token mesh (doc §1.6)
   - aligns buttons/inputs/badges/tabs/pagination to doc spec
     (38px, real ghost edge, one focus ring — doc §2.4/§3.4)
   - makes content cards SOLID (glass only on topbar, sidebar,
     stat cards, modals, dropdowns, toasts — doc §2.5)
   - page shell: breadcrumb + collapsible icon-rail sidebar,
     active item = 3px brand bar + brand-soft (doc §3.5)
   - tables: solid surface-3 head, hover-only-bg, mobile cards
     (doc §3.3); ticket toggle pills compact one-line
   - fixes widget buttons (.pm-action: Shortcuts/MarketConnect),
     orders date-input clipping, sidebar text clipping
   ============================================================ */

/* ---------- body: explicit background in both themes (doc §1.6) ---------- */
html body { background-color: var(--surface-0); }
/* theme-v5 sets a `background:` shorthand on html[data-theme] body (higher
   specificity) which resets the colour layer — restate image + colour here
   at equal specificity, later in the cascade. */
html[data-theme] body, html:not([data-theme]) body { background-image: var(--mesh); background-color: var(--surface-0); }
html[data-theme] body::before, html:not([data-theme]) body::before { background: var(--mesh); }
/* v8: second fixed aurora layer — wide flowing wave ribbons behind
   everything (same paint contract as body::before: fixed, z -1). */
html body::after {
  content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background: var(--wave);
}
body { font-size: var(--fs-md); line-height: var(--lh-base); }

/* ---------- universal focus ring (doc §2.1/Part 6 #12) ---------- */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, [tabindex]:focus-visible {
  outline: none; box-shadow: var(--ring);
}

/* ---------- links: contrast-tuned brand text ---------- */
/* LAYOUT-REPAIR 2026-10-24: the exclusion list used to be ten separate
   :not(.x) clauses, whose specificities SUM — the rule out-ranked every
   component link style inside content (measured: .cfg-link.active text
   at 1.3:1 in light, utility-button anchors .text-white overridden to
   brand-text on their own gradient at ~1.1:1). One merged :not(list)
   contributes its specificity only once, and component classes that
   carry their own colour scheme are excluded outright. */
.pm-content a:not(.pm-btn, .pm-action, .pm-badge, .pm-page, .pm-tab, .pm-ftab, .pm-tab-active, .pm-kpi, .pm-qa, .pm-stat, .cfg-link, .sup-cat, .akl-btn) { color: var(--brand-text); }
/* .text-white is an explicit author intent (white on a coloured
   button/pill) — it must survive the generic content-link colour. */
.pm-content a.text-white { color: var(--brand-ink); }
.pm-link { color: var(--brand-text); }

/* ============================================================
   BUTTONS — doc §2.4 (38px, six variants, real ghost edge)
   .btn* are the doc component names; .pm-btn* are the existing
   hooks — both resolve to the same spec.
   ============================================================ */
.btn, .pm-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  height: 38px; min-height: 38px; padding: 0 var(--s-4);
  border-radius: var(--r-md);
  /* Base (variant-less) buttons get an explicit on-token surface — without
     this, theme-v5's legacy beige gradient bled through (seen on the client
     profile: "Generate Due Invoices" / "Create Add Funds Invoice"). */
  background: var(--surface-2); color: var(--text-1);
  font-size: var(--fs-md); font-weight: 600; line-height: var(--lh-tight);
  border: 1px solid var(--btn-edge); cursor: pointer; text-decoration: none;
  transition: background var(--fast) var(--ease), border-color var(--fast) var(--ease),
              color var(--fast) var(--ease), box-shadow var(--fast) var(--ease),
              transform var(--fast) var(--ease);
  white-space: nowrap;
}
.btn:focus-visible, .pm-btn:focus-visible { outline: none; box-shadow: var(--ring); }
.btn:active, .pm-btn:active { transform: translateY(1px) !important; }
.btn[disabled], .pm-btn[disabled] { opacity: .5; pointer-events: none; }
.btn--primary, .pm-btn-primary {
  background: var(--grad-brand); color: var(--brand-ink); box-shadow: var(--shadow-brand);
}
.btn--primary:hover, .pm-btn-primary:hover { filter: brightness(1.06); box-shadow: var(--shadow-brand-lg); transform: none; }
.btn--ghost, .pm-btn-ghost {
  background: var(--surface-1); color: var(--text-2); border-color: var(--btn-edge);
}
.btn--ghost:hover, .pm-btn-ghost:hover { background: var(--surface-3); color: var(--text-1); border-color: var(--btn-edge); transform: none; box-shadow: none; }
.pm-btn-secondary {
  background: var(--surface-1); color: var(--brand-text); border-color: var(--btn-edge);
}
.pm-btn-secondary:hover { background: var(--brand-soft); color: var(--brand-text); border-color: var(--btn-edge); transform: none; box-shadow: none; }
.btn--danger, .pm-btn-danger { background: var(--grad-danger); color: var(--brand-ink); box-shadow: var(--shadow-bad); }
.btn--danger:hover, .pm-btn-danger:hover { filter: brightness(1.06); transform: none; }
.btn--success, .pm-btn-success { background: var(--grad-success); color: var(--brand-ink); box-shadow: var(--shadow-ok); }
.btn--success:hover, .pm-btn-success:hover { filter: brightness(1.06); transform: none; }
.pm-btn-warning { background: var(--grad-warning); color: var(--brand-ink); box-shadow: var(--shadow-warn); }
.pm-btn-warning:hover { filter: brightness(1.06); transform: none; }
.btn--quiet { background: transparent; color: var(--text-2); }
.btn--quiet:hover { background: var(--surface-3); color: var(--text-1); }
.pm-btn-sm { height: 32px; min-height: 32px; padding: 0 var(--s-3); font-size: var(--fs-sm); border-radius: var(--r-sm); }
.pm-btn-xs { height: 26px; min-height: 26px; padding: 0 var(--s-2); font-size: var(--fs-xs); border-radius: var(--r-sm); }
.pm-btn-lg { height: 44px; min-height: 44px; padding: 0 var(--s-5); font-size: var(--fs-lg); }

/* icon-only buttons: 38px hit area (doc §2.4) */
.pm-icon-btn {
  width: 38px; height: 38px; min-width: 38px; display: inline-grid; place-items: center;
  border-radius: var(--r-md); background: var(--surface-1); color: var(--text-2);
  border: 1px solid var(--btn-edge); cursor: pointer;
}
.pm-icon-btn:hover { background: var(--surface-3); color: var(--text-1); }

/* ---------- widget / module action buttons (user feedback #1/#2):
   Shortcuts, MarketConnect, service actions — token ghost style,
   readable in BOTH themes, never white-with-pale-text ---------- */
.pm-action {
  background: var(--surface-1); border: 1px solid var(--btn-edge); color: var(--text-2);
  min-height: 38px; padding: var(--s-2) var(--s-4); border-radius: var(--r-md);
  font-size: var(--fs-md); font-weight: 600; box-shadow: none;
}
.pm-action:hover { background: var(--surface-3); color: var(--text-1); border-color: var(--btn-edge); transform: none; box-shadow: none; }
.pm-action.pm-action-danger:hover { border-color: var(--bad); color: var(--bad); }
.pm-action:active { transform: translateY(1px); }

/* ============================================================
   CARDS — solid content surfaces (glass scoped per doc §2.5)
   ============================================================ */
.pm-card {
  background: var(--card-bg);
  -webkit-backdrop-filter: none; backdrop-filter: none;
  border: 1px solid var(--stroke); border-radius: var(--r-lg);
  box-shadow: var(--shadow-1), inset 0 1px 0 var(--card-sheen);
}
.pm-card:hover { transform: none; box-shadow: var(--shadow-2), inset 0 1px 0 var(--card-sheen); }
.pm-card::after { display: none; }
.pm-card-head { background: transparent; border-bottom: 1px solid var(--stroke); }
.pm-side-filter, .pm-tabs {
  background: var(--surface-1);
  -webkit-backdrop-filter: none; backdrop-filter: none;
  border: 1px solid var(--stroke); box-shadow: var(--shadow-1);
}
.pm-footer { background: var(--surface-1); border-top: 1px solid var(--stroke); }

/* glass stays ONLY on: topbar, sidebar, stat cards, modals, dropdowns, toasts */
.pm-topbar {
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(140%);
  backdrop-filter: blur(var(--glass-blur)) saturate(140%);
  border-bottom: 1px solid var(--glass-stroke); box-shadow: var(--glass-shadow);
}
.pm-modal, .pm-toast, .pm-auth-card {
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(140%);
  backdrop-filter: blur(var(--glass-blur)) saturate(140%);
  border: 1px solid var(--glass-stroke); box-shadow: var(--glass-shadow);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pm-topbar, .pm-glass { background: var(--surface-2); }
  .pm-modal, .pm-toast, .pm-auth-card { background: var(--surface-2); }
  .pm-sidebar { background: var(--grad-side); }
  .pm-stat { background: var(--surface-1); }
}

/* ============================================================
   PAGE SHELL — breadcrumb + collapsible sidebar (doc §3.5)
   ============================================================ */
.pm-crumbs {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-2);
  font-size: var(--fs-sm); color: var(--text-3);
  margin: 0 0 var(--s-3); padding: 0;
}
.pm-crumbs a { color: var(--brand-text); text-decoration: none; font-weight: 600; }
.pm-crumbs a:hover { text-decoration: underline; }
.pm-crumbs .pm-crumb-sep { color: var(--text-3); user-select: none; }
.pm-crumbs .pm-crumb-cur { color: var(--text-2); font-weight: 600; }

.pm-rail-toggle {
  width: 38px; height: 38px; min-width: 38px; display: inline-grid; place-items: center;
  border-radius: var(--r-md); background: var(--surface-1); color: var(--text-2);
  border: 1px solid var(--btn-edge); cursor: pointer; flex-shrink: 0;
}
.pm-rail-toggle:hover { background: var(--surface-3); color: var(--text-1); }
.pm-rail-toggle svg { width: 18px; height: 18px; }
@media (max-width: 900px) { .pm-rail-toggle { display: none; } }

/* sidebar: prevent ANY text clipping (user feedback #3) */
.pm-sidebar { overflow-x: hidden; }
.pm-nav { overflow-x: hidden; }
.pm-nav a { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.pm-nav a.pm-active {
  background: var(--brand-soft); color: var(--ink-on-dark); font-weight: 700;
  /* v7: the old `inset 3px 0 0` box-shadow rendered as a bright crescent
     blob on the pill's rounded left corner (visible in v7 screenshots);
     a real border follows the radius cleanly. */
  border-left: 3px solid var(--brand-hi);
  box-shadow: none;
}
.pm-nav a.pm-active:hover { transform: none; }

/* collapsed icon rail (desktop only; state in localStorage) */
@media (min-width: 901px) {
  html.pm-rail .pm-sidebar { width: 76px; transition: width var(--base) var(--ease); }
  html.pm-rail .pm-brand { justify-content: center; padding-left: 0; padding-right: 0; }
  html.pm-rail .pm-brand > div:last-child,
  html.pm-rail .pm-nav-label,
  html.pm-rail .pm-side-foot { display: none; }
  html.pm-rail .pm-nav a { justify-content: center; font-size: 0; gap: 0; padding-left: 0; padding-right: 0; }
  html.pm-rail .pm-nav a svg { width: 20px; height: 20px; }
  .pm-sidebar { transition: width var(--base) var(--ease); }
}

/* ============================================================
   TABLES — doc §3.3 (solid head, hover-only-bg, tabular nums)
   ============================================================ */
.pm-table thead th {
  background: var(--surface-3);
  -webkit-backdrop-filter: none; backdrop-filter: none;
  color: var(--text-3); font-size: var(--fs-xs); letter-spacing: var(--tracking-caps);
  text-transform: uppercase; padding: 10px 14px; border-bottom: 1px solid var(--stroke-strong);
}
.pm-table tbody td { padding: 10px 14px; border-bottom: 1px solid var(--stroke); font-variant-numeric: tabular-nums; }
.pm-table tbody tr { transition: background-color 120ms var(--ease); }
.pm-table tbody tr:hover { background: var(--surface-3); box-shadow: none; }
.pm-table-striped tbody tr:nth-child(even) { background: transparent; }
.pm-table-striped tbody tr:nth-child(even):hover { background: var(--surface-3); }
.pm-table td.pm-num, .pm-table th.pm-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.pm-table .pm-nowrap { white-space: nowrap; }

/* badges: token tones + scale size (doc §3.3) */
.pm-badge { font-size: var(--fs-xs); border: 1px solid transparent; }

/* filter tabs / pills — one system (doc §3.3 + feedback #4) */
.pm-filter-tabs { background: var(--surface-3); border: 1px solid var(--stroke); }
.pm-ftab {
  display: inline-flex; align-items: center; gap: var(--s-2);
  height: 38px; padding: 0 var(--s-4); border-radius: 999px;
  background: var(--surface-1); border: 1px solid var(--stroke-strong);
  color: var(--text-2); font-size: var(--fs-sm); font-weight: 600; line-height: var(--lh-tight);
  box-shadow: none; white-space: nowrap;
}
.pm-ftab:hover { background: var(--surface-3); color: var(--text-1); border-color: var(--btn-edge); transform: none; box-shadow: none; }
.pm-ftab.active, .pm-ftab.pm-ftab-active { background: var(--grad-brand); color: var(--brand-ink) !important; border-color: transparent; box-shadow: var(--shadow-brand); }
.pm-ftab .pm-ftab-count, .pm-ftab-count {
  background: var(--brand-soft); color: var(--brand-text);
  font-size: var(--fs-xs); min-width: 1.35rem; padding: .08rem .42rem; border-radius: 999px;
}
.pm-ftab.active .pm-ftab-count, .pm-ftab.pm-ftab-active .pm-ftab-count { background: var(--aw-24); color: var(--brand-ink); }
.pm-content .pm-filter-tabs a.pm-ftab { color: var(--text-2); }
.pm-content .pm-filter-tabs a.pm-ftab:hover { color: var(--text-1); }
.pm-content .pm-filter-tabs a.pm-ftab.active { color: var(--brand-ink); }

/* ticket status toggle pills — compact ONE LINE (feedback #4):
   check dot + label + count kabhi stack nahi honge */
.pm-toggle-pill {
  flex-direction: row; align-items: center; gap: var(--s-2);
  height: 38px; padding: 0 var(--s-3); line-height: var(--lh-tight);
}
.pm-toggle-pill .pm-pill-check { width: 16px; height: 16px; flex: none; }
.pm-toggle-pill:has(> input[type="checkbox"]:checked) {
  background: var(--grad-brand); color: var(--brand-ink) !important; border-color: transparent;
  box-shadow: var(--shadow-brand);
}

/* tabs */
.pm-tabs a.pm-tab-active { background: var(--grad-brand); color: var(--brand-ink); box-shadow: var(--shadow-brand); }
.pm-tabs-line a.pm-tab-active { color: var(--brand-text); border-bottom-color: var(--brand); }
.pm-content .pm-tabs a.pm-tab-active { color: var(--brand-ink); }
.pm-content .pm-tabs-line a.pm-tab-active { color: var(--brand-text); }
.pm-content .pm-tabs-line a:hover, .pm-content .pm-tabs a:hover { color: var(--brand-text); }
/* v7 fix: hover rule above has the same specificity as the active-tab rule
   and comes later — without this guard the active tab's text turned
   brand-blue on hover (blue on blue). Active stays brand-ink, always. */
.pm-content .pm-tabs a.pm-tab-active:hover { color: var(--brand-ink); }

/* pagination */
.pm-page { background: var(--surface-1); border: 1px solid var(--stroke-strong); color: var(--text-2); font-size: var(--fs-sm); }
.pm-page:hover { border-color: var(--btn-edge); color: var(--text-1); transform: none; }
.pm-page.pm-active { background: var(--grad-brand); color: var(--brand-ink); border-color: transparent; box-shadow: var(--shadow-brand); }
span.pm-page.pm-disabled { color: var(--text-4); background: var(--surface-3); }

/* ============================================================
   FORMS — doc §3.4 (38px fields, label above, one ring)
   ============================================================ */
.pm-input, .pm-select {
  height: 38px; padding: 0 var(--s-3);
  font-size: var(--fs-md); color: var(--text-1);
  background: var(--surface-1); border: 1px solid var(--stroke-strong); border-radius: var(--r-md);
}
textarea.pm-input { height: auto; min-height: 76px; padding: var(--s-2) var(--s-3); line-height: var(--lh-base); }
.pm-input:focus, .pm-select:focus, .pm-search:focus {
  outline: none; border-color: var(--brand); box-shadow: var(--ring);
}
.pm-field label { font-size: var(--fs-sm); color: var(--text-2); font-weight: 600; }
.pm-help { font-size: var(--fs-xs); color: var(--text-3); }
.pm-input.pm-invalid { border-color: var(--bad); }
.pm-field .pm-error { font-size: var(--fs-xs); color: var(--bad); margin-top: var(--s-1); }
.pm-search { height: 38px; background: var(--surface-1); border: 1px solid var(--stroke-strong); color: var(--text-1); font-size: var(--fs-md); }
.pm-input::placeholder, .pm-search::placeholder, textarea.pm-input::placeholder { color: var(--text-3); }
input[type="checkbox"], input[type="radio"] { accent-color: var(--brand); }

/* date inputs clipped fix (feedback #5): Chromium date control
   needs ~170px; filter labels grow to fit, text never clipped */
.pm-input[type="date"], .pm-input[type="datetime-local"] { min-width: 168px; }
.pm-input[type="date"]::-webkit-datetime-edit { padding: 0; }
form label:has(> input[type="date"]), form label:has(> input[type="datetime-local"]) { min-width: 184px !important; }

/* ============================================================
   STAT CARDS + COUNTERS (doc §3.1)
   ============================================================ */
.pm-stat { border-radius: var(--r-lg); }
.pm-stat-val { font-size: var(--fs-2xl); font-variant-numeric: tabular-nums; line-height: var(--lh-tight); }
.pm-stat-label { font-size: var(--fs-sm); }
[data-counter] { font-variant-numeric: tabular-nums; }

/* ============================================================
   CHARTS (Chart.js — tokens read at runtime in ui.js)
   ============================================================ */
.pm-chart-box { position: relative; width: 100%; height: 260px; }
.pm-chart-box.sm { height: 200px; }
.pm-chart-box canvas { max-width: 100%; }

/* v7 fix — dashboard cards: fill the grid-row height instead of leaving
   dead space under short content (Orders-by-Status donut stretched to
   the System Overview card's height with an empty lower half). */
.pm-card-fill { display: flex; flex-direction: column; }
.pm-card-fill > .pm-card-body { flex: 1; display: flex; flex-direction: column; }
.pm-card-fill .pm-chart-grow { flex: 1; height: auto; min-height: 210px; }
.pm-card-center > .pm-card-body { justify-content: center; }
/* per-status counts under the donut — dot colors mirror the chart palette
   order in ui.js/dashboard JS: brand, ok, warn, bad, info, deep */
.pm-dstat {
  list-style: none; margin: var(--s-4) 0 0; padding: var(--s-3) 0 0;
  border-top: 1px solid var(--stroke);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: var(--s-2) var(--s-4);
}
.pm-dstat li { display: flex; align-items: center; gap: var(--s-2); font-size: var(--fs-sm); color: var(--text-2); min-width: 0; }
.pm-dstat-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }
.pm-dstat-num { margin-left: auto; font-weight: 700; color: var(--text-1); font-variant-numeric: tabular-nums; }

/* ============================================================
   MODALS / TOASTS — doc Part 4 motion values
   ============================================================ */
@keyframes pm-v5-modalPop {
  from { opacity: 0; transform: scale(.97) translateY(6px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}
.pm-modal { animation: pm-v5-modalPop var(--base) var(--ease); border-radius: var(--r-lg); }
.pm-toasts { top: auto; bottom: var(--s-4); right: var(--s-4); }
.pm-toast { border-radius: var(--r-md); font-size: var(--fs-md); }
.pm-toast:hover::after { animation-play-state: paused; }

/* page entrance: fade up 8px / 220ms (doc Part 4) */
@keyframes pm-v6-fade-up {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: no-preference) {
  .pm-content { animation: pm-v6-fade-up var(--base) var(--ease) backwards; }
  .pm-table tbody tr { animation: none; }
  .pm-stats > *:nth-child(n+7) { animation-delay: 0s; }
}

/* ============================================================
   MOBILE — table rows become cards (doc §3.3), 360px safe
   ============================================================ */
@media (max-width: 767px) {
  .pm-table-cards { display: block; }
  .pm-table-cards thead { display: none; }
  .pm-table-cards tbody { display: block; }
  .pm-table-cards tbody tr {
    display: block; padding: var(--s-3) var(--s-4);
    border-bottom: 1px solid var(--stroke);
  }
  .pm-table-cards tbody td {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: var(--s-4); border-bottom: none; padding: var(--s-1) 0; text-align: right;
  }
  .pm-table-cards tbody td::before {
    content: attr(data-label); flex: none; text-align: left;
    font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase;
    letter-spacing: var(--tracking-caps); color: var(--text-3);
  }
  .pm-table-cards tbody td:not([data-label])::before { content: none; }
  .pm-table-cards tbody td.pm-num { text-align: right; }
}
@media (max-width: 480px) {
  .pm-content { padding: var(--s-4); }
  .pm-topbar { padding: var(--s-2) var(--s-3); }
  .pm-stats { grid-template-columns: 1fr 1fr; }
  .pm-btn, .btn { padding: 0 var(--s-3); }
}

/* empty state (doc §3.3) */
.pm-empty { font-size: var(--fs-md); color: var(--text-3); }
.pm-empty h3 { font-size: var(--fs-lg); color: var(--text-1); }
.pm-empty .pm-btn { margin-top: var(--s-3); }

/* alerts: token status tones */
.pm-alert { font-size: var(--fs-md); border-radius: var(--r-md); }
.pm-alert-error { background: var(--b-bad-bg); border-color: var(--abd-40); color: var(--b-bad-fg); }
.pm-alert-success { background: var(--b-ok-bg); border-color: var(--ao-40); color: var(--b-ok-fg); }
.pm-alert-warn { background: var(--b-warn-bg); border-color: var(--awn-45); color: var(--b-warn-fg); }
.pm-alert-info { background: var(--b-info-bg); border-color: var(--ain-35); color: var(--b-info-fg); }

/* auto-labelled cells with an empty header (checkbox/select column) show no label */
@media (max-width: 767px) {
  .pm-table-cards td[data-label=""]::before { display: none; }
  .pm-table-cards td[data-label=""] { padding-left: 14px; }
}

/* Dates / ids in tables must never wrap mid-value (clients list "Created") */
.pm-nowrap, td.pm-nowrap { white-space: nowrap; }

/* ---------- specificity trumps over theme-v5 glass rules ----------
   theme-v5 styles ghost buttons / .pm-action under html[data-theme="dark"]
   with translucent-white glass (aw-05). The doc-10 spec wants SOLID token
   surfaces + real borders; these selectors out-rank v5 in both themes. */
html[data-theme] .pm-btn.pm-btn-ghost, html[data-theme] .btn.btn--ghost {
  background: var(--surface-1); color: var(--text-2); border-color: var(--btn-edge);
  box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none;
}
html[data-theme] .pm-btn.pm-btn-ghost:hover, html[data-theme] .btn.btn--ghost:hover {
  background: var(--surface-3); color: var(--text-1); border-color: var(--btn-edge); box-shadow: none;
}
html[data-theme] .pm-btn.pm-btn-secondary { background: var(--surface-1); color: var(--brand-text); border-color: var(--btn-edge); box-shadow: none; }
html[data-theme] .pm-action.pm-action {
  background: var(--surface-1); color: var(--text-1); border: 1px solid var(--btn-edge);
  box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none;
}
html[data-theme] .pm-action.pm-action:hover { background: var(--surface-3); color: var(--text-1); border-color: var(--btn-edge); box-shadow: none; }
/* Warning buttons: dark text on amber (white on --warn measures 2.2:1) */
.btn--warning, .pm-btn-warning { background: var(--grad-warning); color: var(--on-warn); box-shadow: var(--shadow-warn); }
.btn--warning:hover, .pm-btn-warning:hover { filter: brightness(1.05); transform: none; }
/* Form controls inherit the type system — kills the UA-default 13.3333px
   input font and any browser-default control styling drift. */
input, select, textarea, button { font: inherit; }

/* Filter/status pills: SOLID token surface (v5's translucent glass chip is
   not allowed on content controls); inactive label = text-2 (≥4.5:1 both
   themes), active stays on the brand gradient. */
html[data-theme] .pm-ftab.pm-ftab {
  background: var(--surface-2); color: var(--text-2); border: 1px solid var(--btn-edge);
  box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none;
}
html[data-theme] .pm-ftab.pm-ftab:hover { background: var(--surface-3); color: var(--text-1); }
html[data-theme] .pm-ftab.pm-ftab.active, html[data-theme] .pm-ftab.pm-ftab[aria-pressed="true"],
html[data-theme] .pm-ftab.pm-ftab.pm-ftab-active, html[data-theme] .pm-content .pm-ftab.pm-ftab.pm-ftab-active {
  background: var(--grad-brand); color: var(--brand-ink); border-color: transparent;
}

/* ---------- Tailwind utility compat layer ----------
   Gap-built blades use Tailwind palette utilities (text-gray-500, bg-white…).
   Map the common ones onto the token system so those pages follow the same
   dark/light design language instead of raw Tailwind colors. */
html[data-theme] .text-gray-400, html[data-theme] .text-gray-500, html[data-theme] .text-gray-600 { color: var(--text-3); }
html[data-theme] .text-gray-700 { color: var(--text-2); }
html[data-theme] .text-gray-800, html[data-theme] .text-gray-900 { color: var(--text-1); }
html[data-theme] .text-red-600, html[data-theme] .text-red-700, html[data-theme] .text-red-800 { color: var(--bad-text); }
html[data-theme] .text-green-600, html[data-theme] .text-green-700, html[data-theme] .text-green-800 { color: var(--ok-text); }
html[data-theme] .text-blue-600, html[data-theme] .text-blue-700 { color: var(--brand-text); }
html[data-theme] .bg-white { background-color: var(--surface-1); }
html[data-theme] .bg-gray-50, html[data-theme] .bg-gray-100 { background-color: var(--surface-2); }
html[data-theme] .bg-gray-200 { background-color: var(--surface-3); }
html[data-theme] .border-gray-200, html[data-theme] .border-gray-300 { border-color: var(--stroke); }

/* v7: structural Tailwind compat — gap-built blades also use Tailwind
   LAYOUT utilities (grid / md:grid-cols-* / gap-* / flex helpers) that no
   stylesheet implemented, so card grids collapsed into one full-width
   stacked column (store home categories, catalogue/report grids…).
   Map the common layout utilities to plain CSS on the 4px token grid. */
.grid { display: grid; }
.grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); }
.grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (min-width: 768px) {
  .md\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .md\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .md\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .md\:grid-cols-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .lg\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .lg\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .lg\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.gap-1 { gap: var(--s-1); } .gap-2 { gap: var(--s-2); } .gap-3 { gap: var(--s-3); }
.gap-4 { gap: var(--s-4); } .gap-5 { gap: 20px; } .gap-6 { gap: var(--s-5); }
.flex { display: flex; } .inline-flex { display: inline-flex; }
.items-center { align-items: center; } .items-start { align-items: flex-start; }
.justify-between { justify-content: space-between; } .justify-center { justify-content: center; }
.justify-end { justify-content: flex-end; } .flex-wrap { flex-wrap: wrap; }
.w-full { width: 100%; } .text-center { text-align: center; }
.text-left { text-align: left; } .text-right { text-align: right; }
.space-y-3 > * + * { margin-top: var(--s-3); }
.space-x-1 > * + * { margin-left: var(--s-1); }

/* v7: Tailwind colour/spacing compat, second wave — 94 uses of
   bg-indigo-600 alone (primary buttons on gap-built pages, e.g. the
   product editor's "Save Details") rendered as bare transparent text
   because only palette text/bg-gray utilities were mapped. Map the
   solid button colours onto token gradients and add the spacing /
   radius / size utilities those blades were authored against.
   Verified: no element combines pm-btn with px-/py-/text-* classes,
   so these cannot override the pm button spec. */
.bg-indigo-600, .bg-indigo-700, .bg-blue-600 { background: var(--grad-brand); color: var(--brand-ink); }
.bg-green-600, .bg-green-700 { background: var(--grad-success); color: var(--brand-ink); }
.bg-red-600, .bg-red-700 { background: var(--grad-danger); color: var(--brand-ink); }
.bg-amber-700 { background: var(--grad-warning); color: var(--brand-ink); }
.bg-gray-700 { background: var(--btn-gray-7); color: var(--brand-ink); }
.bg-gray-600 { background: var(--btn-gray-6); color: var(--brand-ink); }
.bg-indigo-50 { background: var(--brand-soft); } .bg-red-50, .bg-red-100 { background: var(--bad-soft); }
.bg-green-50, .bg-green-100 { background: var(--ok-soft); } .bg-amber-50, .bg-amber-100, .bg-yellow-50, .bg-yellow-100 { background: var(--warn-soft); }
/* LAYOUT-REPAIR 2026-10-24 — compat wave 3: utilities the blades use that
   wave 1/2 never mapped. Without a mapping they fall back to the Tailwind
   CDN at runtime (theme-blind raw palette) or to nothing where the CDN
   is unreachable — measured white-on-transparent buttons at 1.0:1
   (bg-emerald-600 actions) and theme-mixed text. All rules carry the
   html[data-theme] prefix so they out-rank CDN utilities in both themes. */
html[data-theme] .bg-emerald-600, html[data-theme] .bg-emerald-700 { background: var(--grad-success); color: var(--brand-ink); }
html[data-theme] .bg-amber-600 { background: var(--grad-warning); color: var(--brand-ink); }
html[data-theme] .bg-gray-800 { background: var(--btn-gray-7); color: var(--brand-ink); }
html[data-theme] .bg-gray-900 { background: var(--ink-950); color: var(--brand-ink); }
html[data-theme] .bg-black { background: var(--ink-950); }
html[data-theme] .text-gray-200, html[data-theme] .text-gray-300 { color: var(--text-3); }
html[data-theme] .text-amber-600, html[data-theme] .text-amber-700, html[data-theme] .text-amber-800, html[data-theme] .text-amber-900, html[data-theme] .text-yellow-800 { color: var(--warn-deep); }
html[data-theme] .text-red-500 { color: var(--bad-text); }
html[data-theme] .text-green-400 { color: var(--ok-text); }
html[data-theme] .text-indigo-500 { color: var(--brand-text); }
html[data-theme] .text-indigo-900 { color: var(--text-1); }
html[data-theme] .text-black { color: var(--text-1); }
html[data-theme] .border-gray-400, html[data-theme] .border-gray-600, html[data-theme] .border-black { border-color: var(--stroke-strong); }
html[data-theme] .border-blue-300, html[data-theme] .border-blue-700, html[data-theme] .border-blue-800, html[data-theme] .border-indigo-200, html[data-theme] .border-indigo-300 { border-color: var(--brand-soft); }
html[data-theme] .border-indigo-600 { border-color: var(--brand); }
html[data-theme] .border-red-200, html[data-theme] .border-red-300 { border-color: var(--bad-soft); }
html[data-theme] .border-green-200 { border-color: var(--ok-soft); }
html[data-theme] .border-amber-200, html[data-theme] .border-amber-300, html[data-theme] .border-amber-400 { border-color: var(--warn-soft); }
html[data-theme] .border-white { border-color: var(--glass-stroke); }
.text-white { color: var(--brand-ink); }
.border { border: 1px solid var(--stroke); }
.rounded { border-radius: var(--r-sm); } .rounded-lg { border-radius: var(--r-md); }
.rounded-xl { border-radius: var(--r-lg); } .rounded-full { border-radius: 999px; }
.px-1 { padding-left: var(--s-1); padding-right: var(--s-1); } .px-2 { padding-left: var(--s-2); padding-right: var(--s-2); }
.px-3 { padding-left: var(--s-3); padding-right: var(--s-3); } .px-4 { padding-left: var(--s-4); padding-right: var(--s-4); }
.px-5 { padding-left: 20px; padding-right: 20px; }
.py-1 { padding-top: var(--s-1); padding-bottom: var(--s-1); } .py-2 { padding-top: var(--s-2); padding-bottom: var(--s-2); }
.py-3 { padding-top: var(--s-3); padding-bottom: var(--s-3); } .py-4 { padding-top: var(--s-4); padding-bottom: var(--s-4); }
.py-6 { padding-top: var(--s-5); padding-bottom: var(--s-5); }
.p-2 { padding: var(--s-2); } .p-3 { padding: var(--s-3); } .p-4 { padding: var(--s-4); }
.p-5 { padding: 20px; } .p-6 { padding: var(--s-5); }
.mt-1 { margin-top: var(--s-1); } .mt-2 { margin-top: var(--s-2); } .mt-3 { margin-top: var(--s-3); }
.mt-4 { margin-top: var(--s-4); } .mt-5 { margin-top: 20px; } .mt-6 { margin-top: var(--s-5); }
.mb-1 { margin-bottom: var(--s-1); } .mb-2 { margin-bottom: var(--s-2); } .mb-3 { margin-bottom: var(--s-3); }
.mb-4 { margin-bottom: var(--s-4); } .mb-5 { margin-bottom: 20px; } .mb-6 { margin-bottom: var(--s-5); }
.mr-1 { margin-right: var(--s-1); } .mr-2 { margin-right: var(--s-2); } .ml-2 { margin-left: var(--s-2); }
.text-xs { font-size: var(--fs-xs); } .text-sm { font-size: var(--fs-sm); }
.text-lg { font-size: var(--fs-lg); } .text-xl { font-size: var(--fs-xl); }
.font-medium { font-weight: 500; } .font-semibold { font-weight: 600; } .font-bold { font-weight: 700; }

/* v7: store hero subtext was `color: var(--ab-35)` (brand blue at 35%
   alpha) on the deep hero gradient — effectively invisible in dark.
   The hero is deep in BOTH themes, so its copy uses the light alpha
   scale, like the hero heading. */
.pm-hero p { color: var(--as-82); }

/* v7: bare form controls — some gap-built pages (Automation Settings
   is the visible case) use plain <input>/<fieldset> with only Tailwind
   spacing classes, so inputs rendered as flat UA grey bars and the
   fieldset sections had no border, radius or surface at all. Give
   class-less controls the pm-input look and fieldsets a card finish.
   Classed controls (.pm-input/.pm-select) are excluded and keep their
   own spec; checkboxes/radios/files keep native affordance. */
.pm-content input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="color"]):not(.pm-input),
.pm-content textarea:not(.pm-input),
.pm-content select:not(.pm-select) {
  background: var(--surface-2); color: var(--text-1);
  border: 1px solid var(--stroke-strong); border-radius: var(--r-sm);
  padding: .45rem .6rem; font: inherit; font-size: var(--fs-sm);
}
.pm-content fieldset {
  border: 1px solid var(--stroke); border-radius: var(--r-md);
  padding: var(--s-4); background: var(--surface-2); min-width: 0;
}
.pm-content fieldset > legend {
  font-weight: 700; color: var(--text-1); font-size: var(--fs-sm);
  padding: 0 var(--s-2);
}

/* Bare/native <button> elements (legacy + gap markup with only text
   utilities) must not keep the UA dark buttonface (#6B6B6B under
   color-scheme: dark) — that gray box was crushing danger-link contrast.
   Classed buttons (.pm-btn, Tailwind bg-*) out-rank this element rule. */
button { background-color: transparent; border: none; }
/* Pill label colour, final word (out-ranks premium .pm-content chains and
   theme-v5's --text-4 rule): inactive filter tabs read as text-2. */
html[data-theme] .pm-content .pm-ftab.pm-ftab {
  color: var(--text-2); background: var(--surface-2); border-color: var(--btn-edge);
}
html[data-theme] .pm-content .pm-ftab.pm-ftab:hover { color: var(--text-1); background: var(--surface-3); }

/* Filter-tab pills inside .pm-filter-tabs: theme-v5 paints these with
   --text-4 (#637A99 dark = 3.66:1) via a (0,4,2) selector. Same-shape rule
   here, later in the cascade, restores the spec colour. */
html[data-theme] .pm-content .pm-filter-tabs a.pm-ftab {
  color: var(--text-2); background: var(--surface-2); border-color: var(--btn-edge);
}
html[data-theme] .pm-content .pm-filter-tabs a.pm-ftab:hover { color: var(--text-1); background: var(--surface-3); }
html[data-theme] .pm-content .pm-filter-tabs a.pm-ftab.active {
  background: var(--grad-brand); color: var(--brand-ink); border-color: transparent;
}

/* ============================================================
   BRAND LOGO — user-supplied Webyne logo (2026-10-22 test pass)
   The artwork carries navy text, so it always sits on a white
   plate: the plate colour is a deliberate brand-lockup exception
   (identical in both themes, like a printed logo), everything
   else uses tokens. Aspect ratio is never distorted (height set,
   width auto).
   ============================================================ */
.pm-brand-logo {
  display: inline-flex; align-items: center; flex: none;
  background: #fff; border: 1px solid var(--stroke);
  border-radius: 10px; padding: 5px 9px;
  box-shadow: var(--glass-shadow);
}
.pm-brand-logo img { height: 34px; width: auto; display: block; }
.pm-brand-logo-lg { padding: 8px 14px; border-radius: 14px; }
.pm-brand-logo-lg img { height: 54px; }
.pm-auth-logo { display: flex; justify-content: center; margin-bottom: 1.1rem; }
@media (min-width: 901px) {
  html.pm-rail .pm-brand-logo { padding: 3px 4px; border-radius: 8px; }
  html.pm-rail .pm-brand-logo img { height: 19px; }
}

/* v7: invoice-detail mass actions — the action forms used Tailwind
   utility classes (px-2/border/inline) that no stylesheet implements,
   so they rendered as a bare vertical text list. Real design-system
   pills in a wrapping row instead (blade: admin/billing/invoice). */
.pm-mass-actions { display: flex; flex-wrap: wrap; gap: var(--s-2); align-items: center; margin-bottom: var(--s-4); }
.pm-mass-label { flex-basis: 100%; font-size: var(--fs-sm); font-weight: 600; color: var(--text-2); }
.pm-inline-form { display: inline-flex; margin: 0; }

/* ============================================================
   THEME TOGGLE TRANSITION (v7 fix, from animation-worker report)
   The theme colours are custom properties; tokens.css now registers
   them via @property as <color>, so they can interpolate. Animating
   the registered properties on :root makes every var() consumer
   (body, cards, tables, inputs…) fade together when data-theme
   flips; the surface rule below adds ordinary background/color/
   border transitions as a second layer for elements whose colours
   are set directly. Scoped to major surfaces only — a blanket *
   transition would fight hover/animation transitions elsewhere.
   ============================================================ */
:root {
  transition:
    --surface-0 .25s var(--ease), --surface-1 .25s var(--ease),
    --surface-2 .25s var(--ease), --surface-3 .25s var(--ease),
    --glass-bg .25s var(--ease), --glass-stroke .25s var(--ease),
    --text-1 .25s var(--ease), --text-2 .25s var(--ease),
    --text-3 .25s var(--ease), --text-4 .25s var(--ease),
    --stroke .25s var(--ease), --stroke-strong .25s var(--ease),
    --brand-soft .25s var(--ease), --brand-text .25s var(--ease),
    --btn-edge .25s var(--ease), --scroll-thumb .25s var(--ease),
    --bad-text .25s var(--ease), --ok-text .25s var(--ease),
    --b-ok-bg .25s var(--ease), --b-ok-fg .25s var(--ease),
    --b-warn-bg .25s var(--ease), --b-warn-fg .25s var(--ease),
    --b-bad-bg .25s var(--ease), --b-bad-fg .25s var(--ease),
    --b-info-bg .25s var(--ease), --b-info-fg .25s var(--ease),
    --b-mut-bg .25s var(--ease), --b-mut-fg .25s var(--ease),
    --b-purp-bg .25s var(--ease), --b-purp-fg .25s var(--ease),
    --b-orng-bg .25s var(--ease), --b-orng-fg .25s var(--ease),
    --b-teal-bg .25s var(--ease), --b-teal-fg .25s var(--ease);
}
body, .pm-card, .pm-card-head, .pm-topbar, .pm-header, .pm-tabs,
.pm-input, .pm-select, .pm-search, .pm-ftab, .pm-table, .pm-modal,
.pm-toast, .pm-auth-card, .pm-footer, .pm-filter-tabs, .pm-glass {
  transition: background-color .25s var(--ease), color .25s var(--ease),
    border-color .25s var(--ease);
}
@media (prefers-reduced-motion: reduce) {
  :root { transition: none; }
  body, .pm-card, .pm-card-head, .pm-topbar, .pm-header, .pm-tabs,
  .pm-input, .pm-select, .pm-search, .pm-ftab, .pm-table, .pm-modal,
  .pm-toast, .pm-auth-card, .pm-footer, .pm-filter-tabs, .pm-glass {
    transition: none;
  }
}
.block { display: block; } .w-40 { width: 10rem; }

/* ============================================================
   v8 — HEADER: user menu + notification bell + topbar polish
   ============================================================ */
@keyframes pm-menu-in {
  from { opacity: 0; transform: translateY(-4px) scale(.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.pm-menu-wrap { position: relative; display: inline-flex; }
button.pm-avatar {
  border: none; cursor: pointer; font: inherit;
  transition: transform var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
button.pm-avatar:hover { transform: translateY(-1px); }
button.pm-avatar:focus-visible { outline: none; box-shadow: var(--ring); }
.pm-bell-btn {
  position: relative; width: 38px; height: 38px; min-width: 38px; display: inline-grid; place-items: center;
  border-radius: 999px; background: var(--surface-1); color: var(--text-2);
  border: 1px solid var(--btn-edge); cursor: pointer; font: inherit;
  transition: background-color var(--fast) var(--ease), color var(--fast) var(--ease);
}
.pm-bell-btn:hover { background: var(--surface-3); color: var(--text-1); }
.pm-bell-btn:focus-visible { outline: none; box-shadow: var(--ring); }
.pm-bell-btn svg { width: 18px; height: 18px; }
.pm-bell-badge {
  position: absolute; top: -4px; right: -4px; min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: 999px; background: var(--grad-danger); color: var(--brand-ink);
  font-size: 10px; font-weight: 700; line-height: 18px; text-align: center;
  border: 2px solid var(--surface-1); box-sizing: content-box;
}
.pm-menu-pop {
  position: absolute; right: 0; top: calc(100% + 10px); z-index: 90;
  width: 250px; padding: var(--s-2);
  /* glass tint layered over the solid surface: menus stay on-language
     but fully readable — raw --glass-bg alone let dashboard content
     bleed through (v8 screenshot check). */
  background: linear-gradient(var(--glass-bg), var(--glass-bg)), var(--surface-1);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(140%);
  backdrop-filter: blur(var(--glass-blur)) saturate(140%);
  border: 1px solid var(--glass-stroke); border-radius: var(--r-lg);
  box-shadow: var(--glass-shadow);
  animation: pm-menu-in .16s var(--ease);
}
.pm-menu-pop[hidden] { display: none; }
.pm-menu-pop--wide { width: 348px; max-width: min(348px, calc(100vw - 24px)); }
.pm-menu-head {
  padding: var(--s-2) var(--s-3) var(--s-3); margin-bottom: var(--s-1);
  border-bottom: 1px solid var(--stroke);
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s-2);
}
.pm-menu-name { font-weight: 700; color: var(--text-1); font-size: var(--fs-md); line-height: var(--lh-tight); }
.pm-menu-sub { color: var(--text-3); font-size: var(--fs-xs); margin-top: 2px; word-break: break-all; }
.pm-menu-item {
  display: flex; align-items: center; gap: var(--s-2);
  padding: var(--s-2) var(--s-3); border-radius: var(--r-md);
  color: var(--text-1) !important; font-size: var(--fs-sm); font-weight: 600;
  text-decoration: none !important; cursor: pointer;
}
.pm-menu-item:hover { background: var(--surface-3); }
.pm-menu-item svg { width: 16px; height: 16px; flex: none; color: var(--text-3); }
.pm-menu-item--danger { color: var(--bad-text) !important; }
.pm-menu-item--danger svg { color: var(--bad-text); }
.pm-menu-foot {
  margin-top: var(--s-1); padding: var(--s-2) var(--s-3) var(--s-1);
  border-top: 1px solid var(--stroke);
}
.pm-menu-action {
  background: none; border: none; padding: 0; cursor: pointer; font: inherit;
  color: var(--brand-text); font-size: var(--fs-xs); font-weight: 700;
}
.pm-menu-action:hover { text-decoration: underline; }

/* notification rows inside the bell dropdown */
.pm-notif-list { max-height: 380px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.pm-notif-item {
  display: flex; gap: var(--s-3); padding: var(--s-2) var(--s-3); border-radius: var(--r-md);
  text-decoration: none !important; color: var(--text-1) !important; align-items: flex-start;
}
.pm-notif-item:hover { background: var(--surface-3); }
.pm-notif-item.is-unread { background: var(--brand-soft); }
.pm-notif-item.is-unread:hover { background: var(--brand-soft); filter: brightness(1.03); }
.pm-notif-ic {
  width: 32px; height: 32px; min-width: 32px; border-radius: 999px; display: grid; place-items: center;
  background: var(--surface-3); color: var(--brand-text);
}
.pm-notif-ic svg { width: 16px; height: 16px; }
.pm-notif-item.is-unread .pm-notif-ic { background: var(--grad-brand); color: var(--brand-ink); }
.pm-notif-main { min-width: 0; flex: 1; }
.pm-notif-title { font-size: var(--fs-sm); font-weight: 700; color: var(--text-1); line-height: var(--lh-tight); }
.pm-notif-body { font-size: var(--fs-xs); color: var(--text-2); margin-top: 1px; line-height: 1.45; }
.pm-notif-time { font-size: var(--fs-xs); color: var(--text-3); white-space: nowrap; margin-top: 1px; }
.pm-notif-empty { padding: var(--s-4) var(--s-3); text-align: center; color: var(--text-3); font-size: var(--fs-sm); }

/* topbar / sidebar-brand alignment: the floating sidebar carries a .8rem
   top margin that the main column lacked, so the two header rules sat
   14px apart and the brand block (83px) vs topbar (81px) heights differed.
   One shared height + the same top offset puts both lines on one level. */
@media (min-width: 901px) {
  .pm-main { margin-top: .8rem; }
  .pm-topbar { height: 82px; box-sizing: border-box; }
  .pm-brand { height: 82px; box-sizing: border-box; padding-top: 0; padding-bottom: 0; }
}
/* mobile: search gets its own full-width row instead of squeezing/cramping
   the actions row (the bar wrapped to ~176px in three uneven rows). */
@media (max-width: 720px) {
  .pm-topbar { gap: var(--s-2); padding: var(--s-2) var(--s-3); }
  .pm-page-sub { display: none; }
  .pm-top-actions { flex-wrap: wrap; row-gap: var(--s-2); justify-content: flex-end; }
  .pm-top-actions form { order: 9; flex: 1 1 100%; }
  .pm-top-actions .pm-search { width: 100%; }
}

/* v8.1 — tools grid menu, menu-item buttons, full-page notification rows */
.pm-icon-btn {
  width: 38px; height: 38px; min-width: 38px; display: inline-grid; place-items: center;
  border-radius: 999px; background: var(--surface-1); color: var(--text-2);
  border: 1px solid var(--btn-edge); cursor: pointer; font: inherit;
  transition: background-color var(--fast) var(--ease), color var(--fast) var(--ease);
}
.pm-icon-btn:hover { background: var(--surface-3); color: var(--text-1); }
.pm-icon-btn:focus-visible { outline: none; box-shadow: var(--ring); }
.pm-icon-btn svg { width: 18px; height: 18px; }
button.pm-menu-item {
  width: 100%; background: none; border: none; text-align: left; font: inherit;
}
.pm-menu-pop--grid { width: 308px; max-width: calc(100vw - 24px); }
.pm-tools-head {
  padding: var(--s-2) var(--s-3) var(--s-2); font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: var(--tracking-caps); text-transform: uppercase; color: var(--text-3);
}
.pm-tools-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s-1); }
.pm-tool-item {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s-2);
  padding: var(--s-3) var(--s-1); border-radius: var(--r-md); text-align: center;
  color: var(--text-1) !important; text-decoration: none !important;
  font-size: var(--fs-xs); font-weight: 600; line-height: 1.3;
}
.pm-tool-item:hover { background: var(--surface-3); }
.pm-tool-item svg { width: 22px; height: 22px; color: var(--brand-text); }
.pm-notif-row { display: flex; align-items: center; gap: var(--s-2); border-radius: var(--r-md); padding-right: var(--s-2); }
.pm-notif-row .pm-notif-item { flex: 1; min-width: 0; }
.pm-notif-row.is-unread { background: var(--brand-soft); }
.pm-notif-row.is-unread .pm-notif-ic { background: var(--grad-brand); color: var(--brand-ink); }
.pm-notif-del {
  width: 30px; height: 30px; display: grid; place-items: center; border-radius: var(--r-md);
  background: none; border: 1px solid transparent; color: var(--text-3); cursor: pointer; font: inherit;
}
.pm-notif-del:hover { color: var(--bad-text); background: var(--surface-3); }
.pm-notif-del svg { width: 15px; height: 15px; }

/* ===== v9.1 Fix 5: unified filter band + Advanced Filter toggle ===== */
.pm-filter-sep{width:1px;align-self:stretch;background:var(--glass-brd);margin:.15rem .2rem;flex:none}
.pm-ftab-static{cursor:default}
.pm-adv{margin-bottom:1rem}
.pm-adv-btn{display:inline-flex;align-items:center;gap:.45rem}
.pm-adv-btn svg{width:15px;height:15px;flex:none}
.pm-adv-btn .pm-adv-chev{transition:transform .3s ease}
.pm-adv-btn[aria-expanded="true"] .pm-adv-chev{transform:rotate(180deg)}
.pm-adv-btn.has-filters{border-color:var(--brand);color:var(--brand);background:color-mix(in srgb,var(--brand) 8%,transparent)}
.pm-adv-badge{min-width:18px;height:18px;padding:0 5px;border-radius:999px;background:var(--grad-brand);color:var(--brand-ink);font-size:11px;font-weight:700;line-height:1;display:inline-flex;align-items:center;justify-content:center}
.pm-adv-panel{display:grid;grid-template-rows:0fr;opacity:0;margin-top:0;transition:grid-template-rows .38s cubic-bezier(.22,.68,.32,1),opacity .28s ease,margin-top .38s cubic-bezier(.22,.68,.32,1)}
.pm-adv-panel.open{grid-template-rows:1fr;opacity:1;margin-top:.9rem}
.pm-adv-inner{overflow:hidden;min-height:0}
@media (prefers-reduced-motion: reduce){.pm-adv-panel,.pm-adv-btn .pm-adv-chev{transition:none}}

/* ===== v10 Fix 6: sidebar polish — clean inset active pill, rail animation, tooltips ===== */
/* Active item: NO edge-hugging border sliver. The pill itself is the indicator:
   a clearly visible brand tint + inner ring, with a small rounded accent bar
   INSIDE the pill's own padding (never at the sidebar's outer edge). Border
   stays 1px transparent like inactive items, so geometry never shifts. */
.pm-nav a.pm-active {
  border: 1px solid transparent;
  background: color-mix(in srgb, var(--brand) 24%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--brand) 40%, transparent);
}
.pm-nav a.pm-active::before {
  content: ''; position: absolute; left: 6px; top: 50%; transform: translateY(-50%);
  width: 3px; height: 16px; border-radius: 999px; background: var(--brand-hi); pointer-events: none;
}
@media (min-width: 901px) {
  html.pm-rail .pm-nav a.pm-active::before { display: none; }
  /* Collapse/expand timing: on collapse the label vanishes instantly, then the
     rail shrinks; on expand the width animates first and the label returns
     only after the width is (mostly) there — no mid-animation text clipping. */
  html.pm-rail .pm-nav a { transition: background-color .25s var(--ease), color .25s var(--ease), box-shadow .25s var(--ease), transform .25s var(--ease), font-size .01s linear 0s; }
  html:not(.pm-rail) .pm-nav a { transition: background-color .25s var(--ease), color .25s var(--ease), box-shadow .25s var(--ease), transform .25s var(--ease), font-size .01s linear .22s; }
}
/* Rail-mode hover tooltip (JS-positioned, ui.js v10) */
.pm-rail-tip {
  position: fixed; z-index: 300; pointer-events: none; white-space: nowrap;
  background: var(--brand); color: var(--brand-ink);
  border-radius: 8px; padding: .35rem .65rem;
  font-size: var(--fs-sm); font-weight: 600; letter-spacing: .01em;
  box-shadow: 0 10px 24px -8px var(--ai-35);
  opacity: 0; transform: translateY(-50%); transition: opacity .15s ease;
}
.pm-rail-tip.show { opacity: 1; }

/* ===== v11 Fix 6 (attractive sidebar) + Fix 7 (page animation, responsive, mobile app feel) ===== */
/* --- Sidebar: premium drawer treatment (blue/navy tokens only) --- */
.pm-brand { background: radial-gradient(130% 160% at 12% 0%, color-mix(in srgb, var(--brand) 17%, transparent), transparent 55%); }
.pm-nav { gap: 3px; scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--brand-hi) 45%, transparent) transparent; }
.pm-nav a { flex: none; } /* overflow:hidden links would otherwise be crushed below content height by the column flex (rail chips overlapped) */
.pm-nav::-webkit-scrollbar { width: 5px; }
.pm-nav::-webkit-scrollbar-track { background: transparent; }
.pm-nav::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--brand-hi) 38%, transparent); border-radius: 999px; }
.pm-nav::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--brand-hi) 60%, transparent); }
.pm-nav-label { display: flex; align-items: center; gap: .65rem; }
.pm-nav-label::after { content: ''; flex: 1; height: 1px; background: linear-gradient(90deg, var(--am-16, rgba(255,255,255,.14)), transparent); }
/* icon chips */
.pm-nav a svg {
  box-sizing: content-box;
  width: 17px; height: 17px; padding: 5px; border-radius: 9px; flex: none;
  background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.05); opacity: 1;
  transition: transform .3s cubic-bezier(.34,1.56,.64,1), background-color .25s ease, border-color .25s ease;
}
.pm-nav a:hover svg { background: rgba(255,255,255,.11); border-color: rgba(255,255,255,.12); }
@media (hover:hover) { .pm-nav a:hover { transform: translateX(2px); } }
/* ACTIVE = raised full gradient pill (v7: blue -> indigo -> violet, both
   stops deep enough for bold white text), soft glow — the brightest
   element of the sidebar; cleanly inset, no edge bar needed. */
.pm-nav a.pm-active {
  background: var(--grad-brand);
  color: var(--brand-ink); font-weight: 700; border: 1px solid transparent;
  box-shadow: 0 16px 36px -10px color-mix(in srgb, var(--brand) 85%, transparent),
              0 0 28px -6px color-mix(in srgb, var(--c-violet) 60%, transparent),
              inset 0 1px 0 rgba(255,255,255,.32),
              inset 0 0 0 1px color-mix(in srgb, var(--brand-hi) 45%, transparent);
}
.pm-nav a.pm-active::before { display: none; }
.pm-nav a.pm-active svg { background: rgba(255,255,255,.18); border-color: rgba(255,255,255,.25); }
.pm-nav a.pm-active:hover { transform: none; }
@media (min-width: 901px) {
  html.pm-rail .pm-nav a { border-radius: 13px; }
  html.pm-rail .pm-nav a.pm-active { box-shadow: 0 10px 22px -8px color-mix(in srgb, var(--brand) 75%, transparent), inset 0 1px 0 rgba(255,255,255,.28); }
}

/* --- Page-open animation: fade-up + stagger, transform/opacity only --- */
@keyframes pm-rise { from { opacity: 0; transform: translateY(9px); } to { opacity: 1; transform: translateY(0); } }
@keyframes pm-fade { from { opacity: 0; } to { opacity: 1; } }
.pm-content > * { animation: pm-rise .5s var(--ease) backwards; }
.pm-content > *:nth-child(2) { animation-delay: .05s; }
.pm-content > *:nth-child(3) { animation-delay: .1s; }
.pm-content > *:nth-child(4) { animation-delay: .15s; }
.pm-content > *:nth-child(5) { animation-delay: .2s; }
.pm-content > *:nth-child(n+6) { animation-delay: .25s; }
.pm-store-wrap > * { animation: pm-rise .5s var(--ease) backwards; }
.pm-store-wrap > *:nth-child(2) { animation-delay: .06s; }
.pm-store-wrap > *:nth-child(3) { animation-delay: .12s; }
.pm-store-wrap > *:nth-child(n+4) { animation-delay: .18s; }
.pm-auth-card { animation: pm-rise .55s var(--ease) backwards; }
.pm-table tbody tr:nth-child(-n+15) { animation: pm-fade .4s var(--ease) backwards; }
.pm-table tbody tr:nth-child(2) { animation-delay: .03s; }
.pm-table tbody tr:nth-child(3) { animation-delay: .06s; }
.pm-table tbody tr:nth-child(4) { animation-delay: .09s; }
.pm-table tbody tr:nth-child(5) { animation-delay: .12s; }
.pm-table tbody tr:nth-child(n+6) { animation-delay: .15s; }
@media print { .pm-content > *, .pm-store-wrap > *, .pm-auth-card, .pm-table tbody tr { animation: none !important; } }

/* --- Mobile app feel: bottom navigation bar (admin + client) --- */
.pm-bottombar { display: none; }
.pm-drawer-x { display: none; }
@media (max-width: 900px) {
  .pm-bottombar {
    display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
    background: var(--glass-bg); -webkit-backdrop-filter: blur(18px) saturate(150%); backdrop-filter: blur(18px) saturate(150%);
    border-top: 1px solid var(--glass-brd); box-shadow: 0 -14px 34px -18px var(--ai-35);
    padding: .35rem .25rem calc(.35rem + env(safe-area-inset-bottom));
  }
  .pm-bottombar a, .pm-bottombar button {
    flex: 1 1 0; min-height: 52px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
    padding: .3rem 0; border: 0; border-radius: 13px; background: none; cursor: pointer;
    color: var(--text-3); font-size: 10.5px; font-weight: 600; letter-spacing: .01em; text-decoration: none;
    -webkit-tap-highlight-color: transparent; transition: background-color .2s ease, color .2s ease;
  }
  .pm-bottombar svg { width: 21px; height: 21px; }
  .pm-bottombar a.active { color: var(--brand-text); background: var(--brand-soft); }
  .pm-bottombar a:active, .pm-bottombar button:active { background: var(--brand-soft); }
  .pm-content { padding-bottom: calc(86px + env(safe-area-inset-bottom)); }
  /* drawer: softer slide + fading overlay + close button */
  .pm-sidebar { transition: transform .34s cubic-bezier(.22,.68,.32,1); }
  .pm-overlay { display: block; position: fixed; inset: 0; background: var(--ai-50); z-index: 35; opacity: 0; visibility: hidden; transition: opacity .3s ease, visibility 0s linear .3s; }
  body.pm-nav-open .pm-overlay { opacity: 1; visibility: visible; transition: opacity .3s ease; }
  .pm-drawer-x {
    display: grid; place-items: center; position: absolute; top: .9rem; right: .9rem; z-index: 5;
    width: 36px; height: 36px; border-radius: 10px; border: 1px solid rgba(255,255,255,.14);
    background: rgba(255,255,255,.06); color: var(--brand-ink); cursor: pointer;
  }
  .pm-drawer-x svg { width: 17px; height: 17px; }
  /* touch targets */
  .pm-btn-sm { min-height: 38px; }
  .pm-nav a { padding-top: .72rem; padding-bottom: .72rem; }
  .pm-icon-btn { width: 42px; height: 42px; }
  .pm-ftab { min-height: 38px; }
}
@media (prefers-reduced-motion: reduce) {
  .pm-content > *, .pm-store-wrap > *, .pm-auth-card, .pm-table tbody tr { animation: none !important; }
  .pm-sidebar, .pm-overlay { transition: none !important; }
}

/* ===== v11.1 Fix 7: responsive completions ===== */
/* Tailwind compat completion — utilities store/gap blades use that the local
   compat layer never defined (the CDN is a runtime dependency; these make the
   pages render identically without it). Values match Tailwind defaults. */
.flex-col { flex-direction: column; } .flex-1 { flex: 1 1 0%; } .flex-shrink-0 { flex-shrink: 0; }
.w-56 { width: 14rem; } .hidden { display: none; } .font-normal { font-weight: 400; }
.text-2xl { font-size: 1.5rem; line-height: 2rem; } .shadow-sm { box-shadow: 0 1px 2px 0 rgba(0,0,0,.06); }
.list-disc { list-style-type: disc; } .uppercase { text-transform: uppercase; } .tracking-wide { letter-spacing: .025em; }
.underline { text-decoration: underline; } .max-w-md { max-width: 28rem; } .mx-auto { margin-left: auto; margin-right: auto; }
.min-w-full { min-width: 100%; } .ml-5 { margin-left: 20px; } .mr-4 { margin-right: var(--s-4); }
.px-8 { padding-left: 32px; padding-right: 32px; }
.text-indigo-600, .text-indigo-700 { color: var(--brand-text); }
@media (min-width: 768px) { .md\:block { display: block; } .md\:col-span-4 { grid-column: span 4 / span 4; } }
@media (min-width: 1280px) { .xl\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

@media (max-width: 900px) {
  /* client-area list pages: sidebar filter stacks above the list (was crushing
     the table into a narrow right column at phone widths) */
  .pm-content > .flex.gap-6 { flex-wrap: wrap; }
  .pm-content > .flex.gap-6 > aside { width: 100%; flex: none; }
  .pm-content > .flex.gap-6 > *:not(aside) { flex: 1 1 100%; min-width: 0; }
  .pm-side-filter .pm-filter-tabs--vertical { flex-direction: row; flex-wrap: wrap; }
  .pm-side-filter .pm-filter-tabs--vertical .pm-ftab { width: auto; flex: 1 1 auto; justify-content: center; }
}
@media (max-width: 760px) {
  /* store header: brand row + links row (links were clipped off-screen) */
  .pm-store-nav > div { flex-wrap: wrap; padding: .7rem 1rem !important; row-gap: .55rem; }
  .pm-store-nav > div > div { flex: 1 1 100%; flex-wrap: wrap; gap: .9rem; row-gap: .35rem; }
  .pm-store-wrap { padding: 1.4rem 1rem 4rem !important; }
}
@media (max-width: 767px) { .pm-table.pm-table-cards td { overflow-wrap: anywhere; } }

/* ============================================================
   v12 — EXPANDABLE SIDEBAR GROUPS (KAAM 2)
   Same v11 visual language (gradient active pill, icon chips,
   section typography, tokens only). Only the nav STRUCTURE is
   new: Dashboard stays a direct link on top; every other
   destination lives inside a collapsible .pm-nav-group whose
   header is a button (icon chip + label + chevron). Open state
   animates max-height/opacity and persists in localStorage
   (pm-nav-groups-v1, driven from ui.js v12). In rail mode the
   sub-list is replaced by a fixed flyout panel (.pm-nav-flyout).
   ============================================================ */
.pm-nav-dash { flex: none; }
.pm-nav-dash span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pm-nav-group { display: flex; flex-direction: column; gap: 2px; flex: none; }
.pm-nav-ghead {
  display: flex; align-items: center; gap: .7rem; width: 100%;
  padding: .6rem .75rem; border-radius: .7rem; border: 1px solid transparent;
  background: none; color: var(--side-text);
  font-family: inherit; font-size: var(--fs-sm); font-weight: 600; line-height: var(--lh-tight);
  cursor: pointer; text-align: left;
  transition: background-color .25s var(--ease), color .25s var(--ease);
}
.pm-nav-ghead:hover { background: var(--am-08); color: var(--brand-ink); }
.pm-nav-ghead svg.pm-gicon {
  box-sizing: content-box;
  width: 17px; height: 17px; padding: 5px; border-radius: 9px; flex: none;
  background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.05);
  transition: transform .3s cubic-bezier(.34,1.56,.64,1), background-color .25s ease, border-color .25s ease;
}
.pm-nav-ghead:hover svg.pm-gicon { background: rgba(255,255,255,.11); border-color: rgba(255,255,255,.12); }
.pm-nav-glabel { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pm-nav-chev { width: 15px; height: 15px; flex: none; opacity: .6; transition: transform .32s var(--ease), opacity .25s ease; }
.pm-nav-group.is-open .pm-nav-chev { transform: rotate(180deg); opacity: .9; }
/* group header highlight when it contains the active item: text/icon
   colour only — the gradient pill belongs to the sub-item itself */
.pm-nav-group.has-active .pm-nav-ghead { color: var(--brand-ink); }
.pm-nav-group.has-active svg.pm-gicon {
  background: color-mix(in srgb, var(--brand) 38%, transparent);
  border-color: color-mix(in srgb, var(--brand-hi) 45%, transparent);
  color: var(--brand-ink);
}
.pm-nav-sub {
  display: flex; flex-direction: column; gap: 2px; flex: none;
  max-height: 0; opacity: 0; overflow: hidden; visibility: hidden;
  transition: max-height .38s var(--ease), opacity .28s ease, visibility 0s linear .38s;
}
.pm-nav-group.is-open .pm-nav-sub {
  max-height: 1600px; opacity: 1; visibility: visible;
  transition: max-height .38s var(--ease), opacity .28s ease, visibility 0s;
}
.pm-nav-sub a { padding-left: 3.35rem; font-weight: 500; }
.pm-nav-return { flex: none; }

/* rail mode: headers collapse to icon chips; sub-lists move to the flyout */
@media (min-width: 901px) {
  html.pm-rail .pm-nav-ghead { justify-content: center; padding-left: 0; padding-right: 0; }
  html.pm-rail .pm-nav-glabel, html.pm-rail .pm-nav-chev { display: none; }
  html.pm-rail .pm-nav-sub { display: none; }
  html.pm-rail .pm-nav-return { justify-content: center; font-size: 0; gap: 0; padding-left: 0; padding-right: 0; }
}
/* rail flyout panel (populated + positioned by ui.js v12) */
.pm-nav-flyout {
  position: fixed; z-index: 320; width: 236px; max-height: 72vh; overflow-y: auto;
  padding: var(--s-2);
  background: linear-gradient(var(--glass-bg), var(--glass-bg)), var(--side-2);
  border: 1px solid var(--glass-stroke); border-radius: var(--r-lg);
  box-shadow: var(--glass-shadow);
  opacity: 0; visibility: hidden; transform: translateX(-5px);
  transition: opacity .16s var(--ease), transform .16s var(--ease), visibility 0s linear .16s;
}
.pm-nav-flyout.show { opacity: 1; visibility: visible; transform: none; transition: opacity .16s var(--ease), transform .16s var(--ease); }
.pm-fly-title {
  padding: var(--s-2) var(--s-3) var(--s-2);
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: var(--tracking-caps);
  text-transform: uppercase; color: var(--side-label);
}
.pm-fly-item {
  display: flex; align-items: center; padding: .52rem .65rem; border-radius: .6rem;
  color: var(--side-text); font-size: var(--fs-sm); font-weight: 500; text-decoration: none;
  border: 1px solid transparent; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pm-fly-item:hover { background: var(--am-08); color: var(--brand-ink); }
.pm-fly-item.pm-active {
  background: var(--grad-brand);
  color: var(--brand-ink); font-weight: 700;
  box-shadow: 0 10px 22px -8px color-mix(in srgb, var(--brand) 70%, transparent),
              inset 0 1px 0 rgba(255,255,255,.28);
}
/* mobile drawer: groups expand in place with generous touch targets */
@media (max-width: 900px) {
  .pm-nav-ghead { min-height: 48px; padding-top: .72rem; padding-bottom: .72rem; }
}
@media (prefers-reduced-motion: reduce) {
  .pm-nav-sub, .pm-nav-chev, .pm-nav-flyout { transition: none !important; }
}

/* ============================================================
   v7 — GLASSIFY DASHBOARD (greeting, KPI spark cards, revenue
   tabs, donut centre, quick actions). Tokens only; layout and
   grouped sidebar structure unchanged from v6/v12.
   ============================================================ */

/* --- greeting band --- */
.pm-greet { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--s-4); flex-wrap: wrap; margin-bottom: var(--s-5); }
.pm-greet h2 { font-size: var(--fs-2xl); font-weight: 800; letter-spacing: -.02em; color: var(--text-1); line-height: var(--lh-tight); margin: 0; }
.pm-greet .pm-greet-sub { color: var(--text-3); font-size: var(--fs-sm); margin-top: .3rem; }
.pm-greet-date {
  display: inline-flex; align-items: center; gap: .5rem; padding: .5rem .9rem; border-radius: 999px;
  background: var(--glass-bg); border: 1px solid var(--glass-stroke); box-shadow: var(--shadow-1);
  color: var(--text-2); font-size: var(--fs-sm); font-weight: 600; white-space: nowrap;
  -webkit-backdrop-filter: blur(var(--glass-blur)); backdrop-filter: blur(var(--glass-blur));
}
.pm-greet-date svg { width: 15px; height: 15px; color: var(--brand-text); }

/* --- KPI cards: glass + round gradient icon + real sparkline --- */
.pm-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s-4); margin-bottom: var(--s-5); }
@media (max-width: 1100px) { .pm-kpis { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .pm-kpis { grid-template-columns: 1fr; } }
.pm-kpi {
  display: block; text-decoration: none; position: relative; overflow: hidden;
  background: var(--card-bg); border: 1px solid var(--stroke); border-radius: var(--r-lg);
  box-shadow: var(--shadow-1), inset 0 1px 0 var(--card-sheen);
  padding: var(--s-4) var(--s-5) var(--s-3); color: var(--text-1);
  transition: transform .25s var(--ease), box-shadow .25s var(--ease);
}
.pm-kpi:hover { transform: translateY(-3px); box-shadow: var(--shadow-2), inset 0 1px 0 var(--card-sheen); }
.pm-kpi-top { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s-3); }
.pm-kpi-ic {
  width: 46px; height: 46px; border-radius: 50%; flex: none; display: grid; place-items: center;
  color: #fff; box-shadow: 0 10px 20px -8px rgba(2,6,23,.45), inset 0 1px 0 rgba(255,255,255,.35);
}
.pm-kpi-ic svg { width: 21px; height: 21px; }
.pm-kpi-ic.g-blue   { background: var(--grad-blue); }
.pm-kpi-ic.g-violet { background: var(--grad-violet); }
.pm-kpi-ic.g-green  { background: var(--grad-green); }
.pm-kpi-ic.g-orange { background: var(--grad-orange); }
.pm-kpi-delta {
  display: inline-flex; align-items: center; gap: .25rem; padding: .18rem .55rem; border-radius: 999px;
  font-size: var(--fs-xs); font-weight: 700; line-height: 1.35; white-space: nowrap;
}
.pm-kpi-delta.up   { background: var(--b-ok-bg);  color: var(--b-ok-fg);  border: 1px solid var(--ao-35); }
.pm-kpi-delta.down { background: var(--b-bad-bg); color: var(--b-bad-fg); border: 1px solid var(--abd-35); }
.pm-kpi-delta.flat { background: var(--b-mut-bg); color: var(--b-mut-fg); border: 1px solid var(--stroke); }
.pm-kpi-val { font-size: var(--fs-2xl); font-weight: 800; letter-spacing: -.02em; line-height: 1.1; margin-top: .7rem; overflow-wrap: anywhere; }
.pm-kpi-label { font-size: var(--fs-sm); font-weight: 600; color: var(--text-2); margin-top: .15rem; }
.pm-kpi-sub { font-size: var(--fs-xs); color: var(--text-3); margin-top: .1rem; }
.pm-kpi-spark { height: 38px; margin-top: .55rem; }
.pm-kpi-spark canvas { display: block; width: 100% !important; height: 100% !important; }

/* --- revenue overview: total + period tabs --- */
.pm-rev-total { font-size: var(--fs-2xl); font-weight: 800; letter-spacing: -.02em; color: var(--text-1); line-height: 1.1; }
.pm-rev-tabs { display: inline-flex; gap: 2px; padding: 3px; border-radius: 999px; background: var(--surface-3); border: 1px solid var(--stroke); }
.pm-rev-tab {
  border: 0; background: transparent; color: var(--text-3); font: inherit; font-size: var(--fs-xs); font-weight: 700;
  padding: .38rem .8rem; border-radius: 999px; cursor: pointer; transition: background-color .2s var(--ease), color .2s var(--ease);
}
.pm-rev-tab:hover { color: var(--text-1); }
.pm-rev-tab.pm-active { background: var(--grad-brand); color: var(--brand-ink); box-shadow: var(--shadow-brand); }

/* --- donut with centre total --- */
.pm-donut-wrap { position: relative; width: 196px; height: 196px; margin: 0 auto; flex: none; }
.pm-donut-center { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; pointer-events: none; }
.pm-donut-center .pm-donut-num { font-size: var(--fs-2xl); font-weight: 800; letter-spacing: -.02em; color: var(--text-1); line-height: 1; }
.pm-donut-center .pm-donut-cap { font-size: var(--fs-xs); color: var(--text-3); font-weight: 600; margin-top: .3rem; letter-spacing: var(--tracking-caps); text-transform: uppercase; }

/* --- quick actions: full-gradient cards (content area, NO rail) --- */
.pm-qa-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-3); }
@media (max-width: 480px) { .pm-qa-grid { grid-template-columns: 1fr; } }
.pm-qa {
  display: flex; flex-direction: column; gap: .45rem; padding: var(--s-4); border-radius: var(--r-lg);
  color: #fff; text-decoration: none; position: relative; overflow: hidden; min-height: 104px;
  box-shadow: 0 14px 28px -14px rgba(2,6,23,.5), inset 0 1px 0 rgba(255,255,255,.30);
  transition: transform .25s var(--ease), box-shadow .25s var(--ease);
}
.pm-qa:hover { transform: translateY(-3px); box-shadow: 0 20px 36px -14px rgba(2,6,23,.55), inset 0 1px 0 rgba(255,255,255,.30); }
.pm-qa::after { content: ''; position: absolute; right: -34px; top: -34px; width: 110px; height: 110px; border-radius: 50%; background: rgba(255,255,255,.16); pointer-events: none; }
.pm-qa.g-blue   { background: var(--grad-blue); }
.pm-qa.g-violet { background: var(--grad-violet); }
.pm-qa.g-green  { background: var(--grad-green); }
.pm-qa.g-orange { background: var(--grad-orange); }
.pm-qa .pm-qa-ic { width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; background: rgba(255,255,255,.22); border: 1px solid rgba(255,255,255,.35); }
.pm-qa .pm-qa-ic svg { width: 17px; height: 17px; }
.pm-qa .pm-qa-t { font-weight: 700; font-size: var(--fs-sm); line-height: var(--lh-tight); }
.pm-qa .pm-qa-s { font-size: var(--fs-xs); color: rgba(255,255,255,.95); line-height: var(--lh-tight); }

/* dashboard hero grid spacing helper */
.pm-dash-grid { display: grid; gap: var(--s-5); margin-bottom: var(--s-5); }
@media (min-width: 1024px) { .pm-dash-grid { grid-template-columns: 2fr 1fr; } }

/* ============================================================
   v8 — GLASSIFY PREMIUM FEEL, deepened. Same structure, same
   tokens discipline: every colour below resolves to tokens.css
   (v8 additions: --wave, --tint-*, --ambient-*, --ic-glow-*,
   --greet-shadow, --side-bg). Overrides sit at the end of the
   cascade so v7 rules stay readable as the base layer.
   ============================================================ */

/* sidebar: aurora sheen flowing behind the deep-navy glass */
.pm-sidebar { background: var(--side-bg); }

/* greeting: soft scrim-shadow keeps white type readable over the
   brighter dark-theme aurora (token is `none` on light) */
.pm-greet h2 { text-shadow: var(--greet-shadow); }
.pm-greet .pm-greet-sub { text-shadow: var(--greet-shadow); }

/* --- KPI cards: per-accent tinted glass + coloured ambient glow ---
   The accent class (g-blue/g-violet/g-green/g-orange) now sits on
   the card itself as well as the icon; it only sets three vars. */
.pm-kpi {
  background: linear-gradient(165deg, var(--acc-tint, transparent), transparent 58%), var(--card-bg);
  box-shadow: 0 22px 46px -22px var(--acc-amb, transparent), var(--shadow-1), inset 0 1px 0 var(--card-sheen);
}
.pm-kpi.g-blue   { --acc-tint: var(--tint-blue);   --acc-amb: var(--ambient-blue);   --acc-ic: var(--ic-glow-blue); }
.pm-kpi.g-violet { --acc-tint: var(--tint-violet); --acc-amb: var(--ambient-violet); --acc-ic: var(--ic-glow-violet); }
.pm-kpi.g-green  { --acc-tint: var(--tint-green);  --acc-amb: var(--ambient-green);  --acc-ic: var(--ic-glow-green); }
.pm-kpi.g-orange { --acc-tint: var(--tint-orange); --acc-amb: var(--ambient-orange); --acc-ic: var(--ic-glow-orange); }
.pm-kpi:hover {
  box-shadow: 0 30px 58px -20px var(--acc-amb, transparent), var(--shadow-2), inset 0 1px 0 var(--card-sheen);
}
/* icon: bigger, brighter — its own accent glow halo */
.pm-kpi-ic {
  width: 52px; height: 52px;
  box-shadow: 0 14px 30px -8px var(--acc-ic, rgba(2,6,23,.45)),
              0 0 24px -2px var(--acc-ic, transparent),
              inset 0 1px 0 rgba(255,255,255,.38);
}
.pm-kpi-ic svg { width: 24px; height: 24px; }
/* delta chips: a touch of their own light */
.pm-kpi-delta.up   { box-shadow: 0 0 16px -4px var(--ao-45); }
.pm-kpi-delta.down { box-shadow: 0 0 16px -4px var(--abd-45); }
/* sparkline stage: taller so the gradient fill reads as a band */
.pm-kpi-spark { height: 44px; }

/* donut centre figure: larger, heavier (ring gradients live in JS) */
.pm-donut-center .pm-donut-num { font-size: 2.7rem; font-weight: 800; }
.pm-donut-wrap { width: 208px; height: 208px; }

/* --- client stat tiles: same tint + ambient-glow treatment ---
   --acc/--acc2 RGB triplets already arrive from theme-v5 (.pm-acc-*). */
.pm-stat.pm-acc-emerald, .pm-stat.pm-acc-amber, .pm-stat.pm-acc-rose,
.pm-stat.pm-acc-indigo, .pm-stat.pm-acc-violet {
  background:
    linear-gradient(160deg, rgba(var(--acc), .15), rgba(var(--acc), .02) 56%),
    var(--v5-surface);
  box-shadow: var(--v5-glass-shadow),
              0 22px 44px -20px rgba(var(--acc), .5),
              inset 0 3px 0 0 rgb(var(--acc));
}
.pm-stat.pm-acc-emerald .pm-stat-icon, .pm-stat.pm-acc-amber .pm-stat-icon, .pm-stat.pm-acc-rose .pm-stat-icon,
.pm-stat.pm-acc-indigo .pm-stat-icon, .pm-stat.pm-acc-violet .pm-stat-icon {
  box-shadow: 0 10px 24px -6px rgba(var(--acc), .55), 0 0 20px -2px rgba(var(--acc), .5), inset 0 1px 0 var(--aw-15);
}

/* ============================================================
   WHMCS-STYLE FORM ROWS — label left / field / help right
   (BUILD-LAYOUT-2026-10-23 Phase 1: product definition tabs.
   Mirrors the WHMCS config form geometry so staff moving from
   WHMCS recognise every field's place; visuals stay ours.)
   ============================================================ */
.pm-frow { display: grid; grid-template-columns: 200px minmax(0, 1.2fr) minmax(0, 1fr); gap: 4px var(--s-4); align-items: start; padding: 9px 0; border-bottom: 1px solid var(--stroke); }
.pm-frow:last-child { border-bottom: 0; }
.pm-flabel { font-size: var(--fs-sm); font-weight: 600; color: var(--text-2); padding-top: 9px; }
.pm-ffield { min-width: 0; }
.pm-ffield .pm-input, .pm-ffield .pm-select { width: 100%; }
.pm-fhelp { font-size: var(--fs-xs); color: var(--text-3); padding-top: 10px; line-height: var(--lh-base); }
.pm-fcheck { display: flex; align-items: center; gap: var(--s-2); font-size: var(--fs-md); color: var(--text-1); padding-top: 8px; }
.pm-fsub { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
.pm-fsub .pm-input { width: auto; }
@media (max-width: 900px) {
  .pm-frow { grid-template-columns: 1fr; }
  .pm-flabel { padding-top: 0; }
  .pm-fhelp { padding-top: 0; }
}

/* ============ BUILD-LAYOUT FONT SYSTEM — Inter (2026-10-23) ============
   Family comes from --font-sans (tokens.css, self-hosted @font-face).
   Weights: body 400 · labels/nav/table-heads 500 · headings/buttons 600 ·
   KPI/big numbers 700. Tabular figures in tables so amounts align in a
   column. Font-size scale is unchanged — family/weight only. */
/* 2026-11-03: family switched to Manrope — the same face the website uses —
   so the client area and the site read as one brand. Manrope is lighter
   than Inter at the same weight, hence body 500 and headings 700. */
body { font-family: var(--font-sans); font-weight: 500; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; }
h1, h2, h3, h4, h5, h6 { font-family: var(--font-sans); font-weight: 700; letter-spacing: -0.01em; }
label, .pm-flabel, .pm-nav-label, .pm-nav-glabel, th { font-weight: 600; }
.pm-nav a { font-weight: 600; }
.pm-btn { font-weight: 700; }
input, select, textarea, button { font-family: var(--font-sans); }
.pm-kpi-val { font-weight: 700; letter-spacing: -0.02em; font-feature-settings: "tnum" 1; }
.pm-kpi-delta, .pm-kpi-sub { font-feature-settings: "tnum" 1; }
td, .pm-amount, .pm-num { font-feature-settings: "tnum" 1; }

/* ===== v13 BUILD-DASH-ANIM: entrance motion system (reusable) =====
   .pm-reveal  — single element rises in.
   .pm-stagger — children rise in sequence; --pm-i (set per nth-child
   below, capped at 8) × --stagger gives each delay, so long grids
   settle quickly. Transform/opacity only: layout boxes are reserved
   by the normal flow and never move. Fill is `backwards` only, so
   after the entrance the element's own hover transitions/transforms
   behave exactly as before. Charts join the same cascade through
   the animation delay ui.js (v15) adds in registration order;
   [data-counter] count-up already lives in ui.js. */
.pm-reveal { animation: pm-rise var(--dur-rise) var(--ease) backwards; }
.pm-stagger > * {
  animation: pm-rise var(--dur-rise) var(--ease) backwards;
  animation-delay: calc(var(--pm-i, 0) * var(--stagger));
}
.pm-stagger > *:nth-child(2) { --pm-i: 1; }
.pm-stagger > *:nth-child(3) { --pm-i: 2; }
.pm-stagger > *:nth-child(4) { --pm-i: 3; }
.pm-stagger > *:nth-child(5) { --pm-i: 4; }
.pm-stagger > *:nth-child(6) { --pm-i: 5; }
.pm-stagger > *:nth-child(7) { --pm-i: 6; }
.pm-stagger > *:nth-child(8) { --pm-i: 7; }
.pm-stagger > *:nth-child(n+9) { --pm-i: 8; }
/* Progress/usage bars: grow from 0 to the width reserved in --pm-w.
   Only the `from` keyframe is declared, so the bar animates to its
   natural (custom-property) width and stays there. */
.pm-bar-x {
  width: var(--pm-w, 0%); height: 100%; border-radius: 9999px;
  background: var(--pm-grad);
  animation: pm-grow var(--dur-grow) var(--ease) .35s backwards;
}
@keyframes pm-grow { from { width: 0; } }
@media (prefers-reduced-motion: reduce) {
  .pm-reveal, .pm-stagger > *, .pm-bar-x { animation: none !important; }
}
@media print {
  .pm-reveal, .pm-stagger > *, .pm-bar-x { animation: none !important; }
}


/* ============================================================
   v14 — GLASSIFY PREMIUM PASS (2026-10-24 master task)
   1) Rail flyout: theme-independent navy glass (defect: light
      theme composed --glass-bg white over --side-2 → flat gray
      panel, pale links invisible). Sidebar is navy in BOTH
      themes, so the flyout now uses --fly-bg/--fly-stroke.
   2) Shell finishing: topbar + footer become floating panels
      on desktop, mirroring the floating sidebar (same .8rem
      inset, --r-lg radius, 1px glass/stroke border).
   3) Scrollbars: one token-driven style in BOTH themes (v5 only
      styled dark); sidebar rail scrollbar slim + muted.
   4) Row actions: .pm-row-actions / .pm-act icon-only buttons.
   5) Global tooltip .pm-tip (JS-positioned, position:fixed —
      can never be clipped by table/card scroll containers).
   6) Button loading state + chart skeleton shimmer.
   ============================================================ */

/* ---------- 1) rail flyout: navy glass in both themes ---------- */
.pm-nav-flyout {
  background: var(--fly-bg);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  backdrop-filter: blur(20px) saturate(150%);
  border: 1px solid var(--fly-stroke);
  box-shadow: var(--shadow-pop);
}
.pm-fly-title { color: var(--side-muted); }
.pm-fly-item:hover { background: var(--aw-10); }
.pm-fly-item:focus-visible { outline: none; box-shadow: var(--ring); }
/* flyout scrollbar matches the sidebar's slim muted bar */
.pm-nav-flyout { scrollbar-width: thin; scrollbar-color: var(--aw-14) transparent; }
.pm-nav-flyout::-webkit-scrollbar { width: 4px; }
.pm-nav-flyout::-webkit-scrollbar-track { background: transparent; }
.pm-nav-flyout::-webkit-scrollbar-thumb { background: var(--aw-14); border-radius: 999px; }

/* rail tooltip + global tooltip share the tip tokens */
.pm-rail-tip {
  background: var(--tip-bg); color: var(--tip-fg);
  border: 1px solid var(--tip-stroke); box-shadow: var(--shadow-pop);
}

/* ---------- 2) shell finishing: floating topbar + footer ---------- */
@media (min-width: 901px) {
  .pm-topbar {
    top: .8rem; margin-right: .8rem;
    border: 1px solid var(--glass-stroke); border-radius: var(--r-lg);
  }
  .pm-footer {
    margin: auto .8rem .8rem 0;
    border: 1px solid var(--stroke); border-radius: var(--r-lg);
  }
}

/* ---------- 3) scrollbars: both themes, token-driven ---------- */
html[data-theme] ::-webkit-scrollbar { width: 10px; height: 10px; }
html[data-theme] ::-webkit-scrollbar-thumb {
  background: var(--scroll-thumb); border-radius: 8px; border: 2px solid var(--surface-0);
}
html[data-theme] ::-webkit-scrollbar-track { background: transparent; }
html[data-theme] { scrollbar-color: var(--scroll-thumb) transparent; }
/* sidebar nav: slim 4px, muted white on the navy rail (both themes) */
.pm-nav { scrollbar-width: thin; scrollbar-color: var(--aw-14) transparent; }
.pm-nav::-webkit-scrollbar { width: 4px; }
.pm-nav::-webkit-scrollbar-track { background: transparent; }
.pm-nav::-webkit-scrollbar-thumb { background: var(--aw-14); border-radius: 999px; }
.pm-nav::-webkit-scrollbar-thumb:hover { background: var(--aw-24); }

/* ---------- 4) table row actions: icon-only buttons ---------- */
.pm-row-actions { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.pm-act {
  width: 30px; height: 30px; min-width: 30px; display: inline-grid; place-items: center;
  border-radius: var(--r-sm); background: var(--surface-1); color: var(--text-2);
  border: 1px solid var(--stroke-strong); cursor: pointer; text-decoration: none;
  font: inherit; padding: 0; vertical-align: middle;
  transition: background-color var(--fast) var(--ease), color var(--fast) var(--ease),
              border-color var(--fast) var(--ease), transform var(--fast) var(--ease);
}
.pm-act svg { width: 15px; height: 15px; pointer-events: none; }
.pm-act:hover { background: var(--brand-soft); color: var(--brand-text); border-color: var(--btn-edge); }
.pm-act:active { transform: translateY(1px); }
.pm-act:focus-visible { outline: none; box-shadow: var(--ring); }
.pm-act[disabled], .pm-act.disabled { opacity: .5; pointer-events: none; }
.pm-act.pm-act-danger { color: var(--bad-text); }
.pm-act.pm-act-danger:hover { background: var(--b-bad-bg); color: var(--bad-text); border-color: var(--abd-35); }
.pm-act.pm-act-success { color: var(--ok-text); }
.pm-act.pm-act-success:hover { background: var(--b-ok-bg); color: var(--ok-text); border-color: var(--ao-35); }
.pm-act.pm-act-warn { color: var(--b-warn-fg); }
.pm-act.pm-act-warn:hover { background: var(--b-warn-bg); color: var(--b-warn-fg); border-color: var(--awn-35); }
@media (max-width: 900px) { .pm-act { width: 34px; height: 34px; min-width: 34px; } }
/* expand/collapse row toggle (services list): chevron rotates open */
.pm-act-toggle svg { transition: transform var(--base) var(--ease); }
.pm-act-toggle.pm-act-open svg { transform: rotate(180deg); }

/* ---------- 5) global tooltip (JS-positioned, never clipped) ---------- */
.pm-tip {
  position: fixed; z-index: 400; pointer-events: none; max-width: 260px;
  background: var(--tip-bg); color: var(--tip-fg);
  border: 1px solid var(--tip-stroke); border-radius: 8px;
  padding: .35rem .6rem; font-size: var(--fs-xs); font-weight: 600; line-height: 1.35;
  box-shadow: var(--shadow-pop); text-align: center;
  opacity: 0; transform: translate(-50%, 3px);
  transition: opacity .15s var(--ease), transform .15s var(--ease);
}
.pm-tip.show { opacity: 1; transform: translate(-50%, 0); }
.pm-tip.below { transform: translate(-50%, -3px); }
.pm-tip.below.show { transform: translate(-50%, 0); }
@media (prefers-reduced-motion: reduce) { .pm-tip { transition: none; } }

/* ---------- 6) button loading state + skeletons ---------- */
.pm-btn.is-loading { position: relative; color: transparent !important; pointer-events: none; }
.pm-btn.is-loading svg { visibility: hidden; }
.pm-btn.is-loading::after {
  content: ''; position: absolute; left: 50%; top: 50%; width: 16px; height: 16px;
  margin: -8px 0 0 -8px; border-radius: 50%;
  border: 2px solid var(--asl-30); border-top-color: var(--brand-text);
  animation: pm-v5-spin .7s linear infinite;
}
.pm-btn-primary.is-loading::after, .pm-btn-danger.is-loading::after,
.pm-btn-success.is-loading::after, .btn--primary.is-loading::after,
.btn--danger.is-loading::after, .btn--success.is-loading::after {
  border-color: var(--aw-35); border-top-color: var(--brand-ink);
}
.pm-btn-warning.is-loading::after { border-color: var(--ai-35); border-top-color: var(--on-warn); }

.pm-skeleton { position: relative; overflow: hidden; background: var(--surface-3); border-radius: var(--r-md); }
.pm-skeleton::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(100deg, transparent 20%, color-mix(in srgb, var(--text-1) 7%, transparent) 50%, transparent 80%);
  animation: pm-shimmer 1.4s ease-in-out infinite;
}
@keyframes pm-shimmer { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) { .pm-skeleton::after { animation: none; } }
/* chart boxes shimmer until Chart.js has painted (real async state) */
.pm-chart-box canvas { transition: opacity .3s var(--ease); }
.pm-chart-box:not(.pm-chart-ready) canvas { opacity: 0; }
.pm-chart-box:not(.pm-chart-ready)::before {
  content: ''; position: absolute; inset: 0; border-radius: var(--r-md);
  background: linear-gradient(100deg, transparent 20%, color-mix(in srgb, var(--text-1) 6%, transparent) 50%, transparent 80%);
  background-size: 200% 100%; animation: pm-shimmer-bg 1.4s ease-in-out infinite;
}
@keyframes pm-shimmer-bg { from { background-position: 120% 0; } to { background-position: -80% 0; } }
@media (prefers-reduced-motion: reduce) { .pm-chart-box:not(.pm-chart-ready)::before { animation: none; } }

/* ============================================================
   STICKY TOPBAR — nothing scrolls through the gutter
   ============================================================
   The admin topbar is a rounded bar that floats with a ~0.8rem
   gutter above and to each side. It sticks on scroll, but the
   gutter was left transparent, so the page kept scrolling
   through it: table rows appeared ABOVE the bar and beside its
   rounded corners, which read as a broken, detached header.

   Paint the gutter with the page colour, behind the bar. The
   negative z-index keeps it under the bar's own background but
   still inside the bar's stacking context, so it stays above
   everything scrolling past. The sidebar sits higher again and
   is unaffected. */
.pm-topbar::before {
  content: '';
  position: absolute;
  top: calc(-1 * var(--topbar-gutter, .8rem));
  left: calc(-1 * var(--topbar-gutter, .8rem));
  right: calc(-1 * var(--topbar-gutter, .8rem));
  bottom: 0;
  background: var(--surface-0);
  border-radius: inherit;
  z-index: -1;
  pointer-events: none;
}

/* ============================================================
   HEADER WIDTH — the website's cap, not Tailwind's
   ============================================================
   The client area loads the Tailwind CDN, whose own `.container`
   utility sets a max-width per breakpoint (1536px at the widest).
   It is injected at runtime, so it lands after the site stylesheet
   and overrode `.wx22`'s 1280px — the header stretched ~256px wider
   here than the identical header does on the website.

   Win on specificity rather than on order: this is three classes
   and a tag, Tailwind's is one class. */
nav.wx21 .container.wx22,
footer.wx1 .container.wx22 {
  max-width: 1280px;
}

/* Divider inside a header menu. */
.pm-menu-sep { height: 1px; margin: .35rem 0; background: var(--stroke); }

/* ============================================================
   SHELL GEOMETRY — v9 (2026-10-27)
   ============================================================
   Four things were wrong with the console shell:

   1. The topbar and footer ran edge-to-edge into the sidebar, so
      the floating sidebar read as part of them rather than beside
      them. The main column now carries the same gutter the
      sidebar already had, and both bars are rounded, so the gap
      is visible on every edge.
   2. The topbar was a fixed 82px with .8rem of padding on top of
      that — far more height than a title and a row of 38px
      buttons need.
   3. .pm-content reserved 5rem below the page, which read as a
      large empty band above the footer on every short page.
   4. .pm-content was capped at 1280px and centred, so on a wide
      monitor — or any zoomed-out window — the page sat in a
      narrow column with huge empty margins either side. Tables
      with a dozen columns were scrolling horizontally inside a
      window with 600px of unused space. The cap is gone; the
      column's own padding is the only margin now.
   ============================================================ */

@media (min-width: 901px) {
  /* The sidebar is a floating card with its own margin; the main column
     needs the matching gutter on this side or the bars butt straight into
     it and the two read as one slab. */
  .pm-main { margin: var(--shell-gutter, .8rem); }
  .pm-topbar {
    height: 64px;
    padding-top: 0; padding-bottom: 0;
    border-radius: var(--r-lg, 14px);
    border-bottom: 1px solid var(--glass-stroke);
  }
  .pm-brand { height: 64px; }
  /* The gutter now belongs to .pm-main, so the bars must not carry their
     own copy of it as well — that is what pushed them 13px in from the
     page column on the right. */
  .pm-topbar { margin-right: 0; }
  .pm-footer { margin: auto 0 0 0; }
  .pm-footer {
    border-radius: var(--r-lg, 14px);
    border-top: 1px solid var(--stroke);
  }
  /* The shield paints the sticky bar's own gutter so rows cannot
     scroll through it. It must not reach past that gutter, or it
     fills the gap to the sidebar and the bar looks welded on. */
  .pm-topbar::before {
    top: calc(-1 * var(--shell-gutter, .8rem));
    left: 0;
    right: 0;
    border-radius: 0;
  }
}

/* Full width, and only the column's padding for margin. */
.pm-content {
  max-width: none;
  margin: 0;
  padding-bottom: 1.5rem;
}

/* ------------------------------------------------------------
   Client area: header and page agree on one width.

   The admin console runs full width because its tables are wide.
   The client area keeps the website's centred container — that
   was the point of capping the header — but 1280px left a very
   wide window mostly empty. One shared cap, generous enough that
   a zoomed-out window is not half margin, applied to the header,
   the footer and the page alike so no edge is out of line.
   ------------------------------------------------------------ */
body.sh-shell-page .pm-content {
  max-width: var(--shell-max, 1600px);
  margin: 0 auto;
  width: 100%;
}
nav.wx21 .container.wx22,
footer.wx1 .container.wx22 {
  max-width: var(--shell-max, 1600px);
}

/* The bars take the sidebar's corner, not the generic card corner — all
   three are floating panels on the same page and a 16px header beside an
   18.4px sidebar reads as a mistake rather than a choice. */
@media (min-width: 901px) {
  .pm-topbar, .pm-footer { border-radius: 1.15rem; }
  /* The gutter shield sits behind the bar; square corners there would
     show through the bar's own rounded ones. */
  .pm-topbar::before { border-radius: 0 0 1.15rem 1.15rem; }
}
