
/* ── Self-hosted fonts ───────────────────────────────────────────────
   Readex Pro: body/data workhorse — one face for Arabic and Latin.
   El Messiri: display face — warmth + character, used with restraint
   for page titles, hero numbers, and the AI's own voice. Both served
   from /fonts (see server.ts) so font-src 'self' in the CSP is enough —
   no third-party stylesheet, no render-blocking cross-origin request. ── */
/* ── Daylight typefaces, self-hosted from public/fonts ──────────────────
   IBM Plex Sans Arabic carries headings, metrics and every number.
   Readex Pro carries body text. Both cover Arabic AND Latin in one face,
   which is the point: a mixed string like "USD 187.50 المبلغ المنفق"
   never switches typeface mid-line the way a Latin+Arabic pairing does.
   Readex Pro is variable — one file per subset spans weights 300-600. */
@font-face { font-family: 'Readex Pro'; font-style: normal; font-weight: 300 600; font-display: swap; src: url('/fonts/readex-pro-arabic-variable.woff2') format('woff2-variations'); unicode-range: U+0600-06FF,U+0750-077F,U+0870-088E,U+0890-0891,U+0898-08E1,U+08E3-08FF,U+FB50-FDFF,U+FE70-FEFF;
}
@font-face { font-family: 'Readex Pro'; font-style: normal; font-weight: 300 600; font-display: swap; src: url('/fonts/readex-pro-latin-variable.woff2') format('woff2-variations'); unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face { font-family: 'IBM Plex Sans Arabic'; font-style: normal; font-weight: 400; font-display: swap; src: url('/fonts/ibm-plex-sans-arabic-arabic-400-normal.woff2') format('woff2'); unicode-range: U+0600-06FF,U+0750-077F,U+0870-088E,U+0890-0891,U+0898-08E1,U+08E3-08FF,U+FB50-FDFF,U+FE70-FEFF;
}
@font-face { font-family: 'IBM Plex Sans Arabic'; font-style: normal; font-weight: 500; font-display: swap; src: url('/fonts/ibm-plex-sans-arabic-arabic-500-normal.woff2') format('woff2'); unicode-range: U+0600-06FF,U+0750-077F,U+0870-088E,U+0890-0891,U+0898-08E1,U+08E3-08FF,U+FB50-FDFF,U+FE70-FEFF;
}
@font-face { font-family: 'IBM Plex Sans Arabic'; font-style: normal; font-weight: 600; font-display: swap; src: url('/fonts/ibm-plex-sans-arabic-arabic-600-normal.woff2') format('woff2'); unicode-range: U+0600-06FF,U+0750-077F,U+0870-088E,U+0890-0891,U+0898-08E1,U+08E3-08FF,U+FB50-FDFF,U+FE70-FEFF;
}
@font-face { font-family: 'IBM Plex Sans Arabic'; font-style: normal; font-weight: 700; font-display: swap; src: url('/fonts/ibm-plex-sans-arabic-arabic-700-normal.woff2') format('woff2'); unicode-range: U+0600-06FF,U+0750-077F,U+0870-088E,U+0890-0891,U+0898-08E1,U+08E3-08FF,U+FB50-FDFF,U+FE70-FEFF;
}
@font-face { font-family: 'IBM Plex Sans Arabic'; font-style: normal; font-weight: 400; font-display: swap; src: url('/fonts/ibm-plex-sans-arabic-latin-400-normal.woff2') format('woff2'); unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face { font-family: 'IBM Plex Sans Arabic'; font-style: normal; font-weight: 500; font-display: swap; src: url('/fonts/ibm-plex-sans-arabic-latin-500-normal.woff2') format('woff2'); unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face { font-family: 'IBM Plex Sans Arabic'; font-style: normal; font-weight: 600; font-display: swap; src: url('/fonts/ibm-plex-sans-arabic-latin-600-normal.woff2') format('woff2'); unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face { font-family: 'IBM Plex Sans Arabic'; font-style: normal; font-weight: 700; font-display: swap; src: url('/fonts/ibm-plex-sans-arabic-latin-700-normal.woff2') format('woff2'); unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face { font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 400; font-display: swap; src: url('/fonts/ibm-plex-mono-latin-400-normal.woff2') format('woff2'); unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face { font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 500; font-display: swap; src: url('/fonts/ibm-plex-mono-latin-500-normal.woff2') format('woff2'); unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

:root {
  /* ══ ADLYTIC DAYLIGHT ═══════════════════════════════════════════════
     Light theme, RTL-first. Values transcribed from the Claude Design
     handoff (tokens/adlytic-daylight.css v1.0.0-draft) — see
     src/ui/daylight.css for the vendored source and src/ui/tokens.ts for
     the typed mirror.

     WHY THE VARIABLE NAMES DID NOT CHANGE: the codebase reads these
     through var() 848 times and hardcodes a colour only ~107 times, so
     replacing the VALUES here flips the entire product at once. Renaming
     them would have meant touching every consumer to achieve exactly the
     same pixels. The names are already semantic (--surface, not --dark),
     which is what makes this possible.

     Contrast ratios below are measured against --bg (#F2F7F4). Two splits
     are load-bearing and must not be collapsed:
       · --text-3 (#5F7268, 4.8:1) is the faintest colour allowed to carry
         words. --nontext (#7C8F87, 3.2:1) FAILS as text and is for
         hatching, gridlines and icon strokes only.
       · --success (#17714F, 5.6:1) is green TEXT; --success-fill
         (#1D8A63, 4.0:1) is bars and fills only.
     Both were the designer's own corrections, found by measuring. ───── */

  /* ── Surface. Three levels, and only three. ─────────────────────── */
  --bg: #F2F7F4;
  --surface: #FFFFFF;
  --surface-2: #E8F0EA;
  --surface-hover: #E8F0EA;
  --border: #D8E4DC;
  --border-2: #C7D8CE;
  /* ── Control boundary ─────────────────────────────────────────────
     --border and --border-2 are SEPARATORS: they divide two regions the
     eye already reads as separate, so 1.2:1 is enough and anything
     stronger turns every card into a box.

     A control boundary is a different job. The line around a text field
     is the only thing telling a merchant where to type; if it vanishes,
     the field is not "subtle", it is gone. WCAG 1.4.11 asks 3:1 for it,
     and the Daylight palette shipped it at 1.13:1 on --surface-2 — which
     is where our fields actually sit, not on --bg where the handoff
     measured. A customer reading these screens said the form looked
     empty. It was not; the borders were.

     3.18:1 on --surface-2, 3.41:1 on --bg, 3.69:1 on --surface — clears
     3:1 on ALL THREE grounds a control can land on, which is the whole
     point of measuring it separately. Not --nontext (#7C8F87): that one
     is 2.95:1 on --surface-2 and would have failed the same way. */
  --border-control: #748A80;
  --text: #0B1F19;            /* 15.8:1 */
  --text-2: #4A5F57;          /* 6.4:1  */
  --text-3: #5D7066;          /* 4.9:1 on --bg, 4.6:1 on --surface-2 */
  --nontext: #7C8F87;         /* 3.2:1 — NON-TEXT ONLY, never words */

  /* ── Brand — deep forest green. Replaces the gold. ───────────────── */
  --accent: #0E4034;          /* 9.9:1 — also the focus ring */
  --accent-2: #0B1F19;        /* hover */
  --accent-3: #082A22;        /* active */
  --accent-dim: rgba(14,64,52,0.08);
  --accent-glow: rgba(14,64,52,0.18);
  /* The lime signal: legible ONLY on the brand ground, at most once per
     screen. Its entire value is scarcity. */
  --signal: #C8F26B;

  /* ── Status. Distinct hues by contract — a merchant must never
     confuse "still counting" with "something is wrong", so --info is a
     calm blue that appears nowhere in the severity ramp. ───────────── */
  --success: #17714F;         /* 5.6:1 text */
  --success-fill: #1D8A63;    /* 4.0:1 — fills only, never text */
  --success-dim: rgba(23,113,79,0.10);
  --warning: #AF502A;         /* 4.8:1 on --bg, 4.5:1 on --surface-2 */
  --warning-dim: rgba(180,85,47,0.10);
  --error: #A32B1E;           /* 6.7:1 */
  --error-dim: rgba(163,43,30,0.10);
  --critical: #A32B1E;
  --critical-dim: rgba(163,43,30,0.10);
  --info: #3E6C8A;            /* 5.2:1 — INSUFFICIENT_DATA, never a warning */
  --info-dim: rgba(62,108,138,0.10);
  /* INSUFFICIENT_DATA fill. A PATTERN, not a colour — it survives
     greyscale and colour-blindness, which a tint does not. */
  --hatch: repeating-linear-gradient(135deg, #F2F7F4 0 7px, #E8F0EA 7px 14px);

  /* The veil behind a modal. ONE value, because five overlays had five —
     pure black at 0.55, 0.6, 0.65, and the old dark ink at 0.92, which is so
     close to opaque that opening a dialog blacked the product out instead of
     dimming it. Deep ink rather than #000: a green-black veil belongs to this
     palette, a pure black slab belongs to no palette at all. */
  --scrim: rgba(11,31,25,0.55);

  /* ── Data-viz series — WHICH campaign, never how healthy. ──────────
     No value here appears in the status ramp above, and a chart may not
     borrow a status colour for a series: two lines meaning "campaign A"
     and "campaign B" must never read as "good" and "bad". Ordered for
     distinctness at small size and under common colour deficiencies. */
  --series-1: #0E4034;
  --series-2: #4A6FA5;
  --series-3: #7B4B7E;
  --series-4: #B8873B;
  --series-5: #5F8A7D;
  --series-6: #8C6A5D;
  --gridline: #D8E4DC;
  --benchmark: #0B1F19;

  /* Gradients are flattened to solids. Daylight has no gradient surfaces:
     elevation is surface tint plus a 1px border, full stop. Kept as
     variables so the ~20 consumers need no edit. */
  --grad-accent: #0E4034;
  --grad-accent-hover: #0B1F19;
  --grad-success: #17714F;
  --grad-surface: none;

  --font-body: 'Readex Pro', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-display: 'IBM Plex Sans Arabic', system-ui, -apple-system, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, Menlo, monospace;

  --sidebar-w: 236px;
  --topbar-h: 56px;
  --radius: 8px;
  --radius-sm: 5px;
  --radius-lg: 12px;
  --shadow: 0 1px 3px transparent, 0 1px 2px transparent;
  --shadow-lg: 0 4px 16px transparent, 0 1px 3px transparent;
  --shadow-xl: 0 8px 32px transparent, 0 2px 8px transparent;
  --shadow-accent: 0 4px 14px var(--accent-glow);
  --shadow-glow: 0 0 0 1px var(--accent-dim), 0 8px 24px var(--accent-dim);
  --shadow-inner-glow: inset 0 1px 0 transparent, inset 0 0 0 1px transparent;
  --transition: 150ms cubic-bezier(0.4,0,0.2,1);
  --transition-slow: 260ms cubic-bezier(0.34,1.56,0.64,1);
}
/* ══ END TOKENS ══ */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { font-size: 14px; -webkit-font-smoothing: antialiased; }
body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  line-height: 1.5;
  min-height: 100vh;
}
h1, h2, h3, .page-title, .card-title-lg { font-family: var(--font-display); }
[dir="auto"] { letter-spacing: normal; line-height: 1.6; }
a { color: var(--accent-2); text-decoration: none; }
a:hover { color: var(--text); }
button { cursor: pointer; font-family: inherit; }
input, select, textarea { font-family: inherit; }

/* ── App shell ───────────────────────────────────────────────────── */
.app-shell { display: flex; min-height: 100vh; }

/* ── Sidebar ─────────────────────────────────────────────────────── */
.sidebar {
  width: var(--sidebar-w);
  min-width: var(--sidebar-w);
  background:
    linear-gradient(180deg, var(--accent-dim) 0%, transparent 38%),
    var(--surface);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  position: fixed;
  top: 0; left: 0; bottom: 0;
  z-index: 100;
  overflow-y: auto;
  overflow-x: hidden;
}
.sidebar-logo {
  padding: 16px 14px 14px;
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 11px;
  text-decoration: none;
  color: inherit;
  transition: background var(--transition);
  position: relative;
}
.sidebar-logo::after {
  content: "";
  position: absolute; inset: auto 14px 0 14px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent-glow), transparent);
  opacity: 0.6;
}
.sidebar-logo:hover { background: var(--surface-2); }
.sidebar-logo-mark {
  width: 38px; height: 38px;
  flex-shrink: 0;
  filter: drop-shadow(0 4px 14px var(--accent-dim));
  transition: transform var(--transition-slow);
}
.sidebar-logo:hover .sidebar-logo-mark { transform: scale(1.04); }
.sidebar-logo-copy {
  display: flex; flex-direction: column; gap: 1px; min-width: 0;
}
.sidebar-logo-text {
  font-family: var(--font-display); font-weight: 700; font-size: 17px;
  color: var(--text); letter-spacing: -0.4px; line-height: 1.1;
}
.sidebar-logo-tagline {
  font-size: 10.5px; font-weight: 600; color: var(--text-3); letter-spacing: 0.01em;
}
.sidebar-nav { flex: 1; padding: 12px 10px 8px; }
.nav-section-label {
  font-size: 10px; font-weight: 700; color: var(--text-3);
  letter-spacing: 0.06em;
  padding: 4px 10px 10px;
}
.nav-list {
  position: relative;
  display: flex; flex-direction: column; gap: 4px;
}
.nav-indicator {
  position: absolute;
  inset-inline-start: 0;
  width: 3px;
  border-radius: 999px;
  background: var(--grad-accent);
  box-shadow: none;
  opacity: 0;
  pointer-events: none;
  transition:
    transform 280ms cubic-bezier(0.34, 1.2, 0.64, 1),
    height 280ms cubic-bezier(0.34, 1.2, 0.64, 1),
    opacity 180ms ease;
  z-index: 0;
}
.nav-item {
  position: relative;
  display: flex; align-items: center; gap: 11px;
  padding: 9px 10px;
  border-radius: 11px;
  color: var(--text-2);
  font-size: 13.5px; font-weight: 600;
  transition:
    color 200ms ease,
    background 200ms ease,
    transform 200ms ease,
    box-shadow 200ms ease;
  margin-bottom: 0;
  text-decoration: none;
  border: 1px solid transparent;
  z-index: 1;
}
.nav-item::before {
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;
  background: linear-gradient(135deg, var(--accent-dim) 0%, var(--accent-dim) 100%);
  opacity: 0;
  transition: opacity 200ms ease;
  pointer-events: none;
}
.nav-item:hover {
  background: var(--surface-2);
  color: var(--text);
  transform: translateX(2px);
}
[dir="rtl"] .nav-item:hover { transform: translateX(-2px); }
.nav-item.active {
  color: var(--accent-2);
  background: var(--accent-dim);
  border-color: var(--accent-dim);
  box-shadow: none;
}
.nav-item.active::before { opacity: 1; }
.nav-item-icon {
  width: 32px; height: 32px;
  border-radius: 9px;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-2);
  border: 1px solid var(--border);
  flex-shrink: 0;
  transition: background 200ms ease, border-color 200ms ease, transform 200ms ease;
}
.nav-item svg { width: 17px; height: 17px; flex-shrink: 0; opacity: 0.78; transition: opacity 200ms ease; }
.nav-item:hover .nav-item-icon { background: var(--border); border-color: var(--border); }
.nav-item.active .nav-item-icon {
  background: var(--accent-dim);
  border-color: var(--accent-glow);
  transform: scale(1.03);
}
.nav-item.active svg { opacity: 1; color: var(--accent-2); }
.nav-item-label { flex: 1; min-width: 0; line-height: 1.25; }
.nav-item.nav-item--muted { color: var(--text-3); font-weight: 500; }
.nav-item.nav-item--muted:hover { color: var(--text-2); }
.sidebar-footer {
  padding: 10px 10px 14px;
  border-top: 1px solid var(--border);
  background:
    linear-gradient(180deg, transparent 0%, transparent 100%);
}
.sidebar-footer-label {
  padding-bottom: 8px;
}
.sidebar-footer-card {
  border-radius: 13px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  overflow: hidden;
  box-shadow: none;
}
.sidebar-user {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 11px;
  border-radius: 0;
  cursor: pointer;
  transition: background var(--transition), color var(--transition);
  border: none;
  text-decoration: none;
  color: inherit;
  width: 100%;
  box-sizing: border-box;
}
.sidebar-user:hover {
  background: var(--surface-2);
}
.sidebar-user:hover .sidebar-user-chevron { opacity: 0.75; color: var(--accent-2); }
.avatar {
  position: relative;
  width: 36px; height: 36px;
  background: var(--grad-accent);
  border-radius: 11px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  box-shadow: none;
  border: 2px solid var(--border);
}
.avatar-initials {
  font-size: 12px; font-weight: 800; color: var(--bg); line-height: 1;
}
.avatar-status {
  position: absolute;
  bottom: -1px; inset-inline-end: -1px;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--success);
  border: 2px solid var(--surface);
  box-shadow: none;
}
.sidebar-user-info { flex: 1; min-width: 0; }
.sidebar-user-name { font-size: 13px; font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; line-height: 1.2; }
.sidebar-user-email { font-size: 11px; color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 2px; }
.sidebar-user-chevron {
  flex-shrink: 0;
  opacity: 0.35;
  color: var(--text-3);
  transition: opacity var(--transition), color var(--transition), transform var(--transition);
}
.sidebar-user-chevron svg { width: 14px; height: 14px; display: block; }
[dir="rtl"] .sidebar-user-chevron svg { transform: scaleX(-1); }
.sidebar-footer-divider {
  height: 1px;
  margin: 0 11px;
  background: linear-gradient(90deg, transparent, var(--surface-2), transparent);
}
.sidebar-logout {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  padding: 9px 11px 10px;
  border: none;
  background: transparent;
  color: var(--text-3);
  font-size: 13px; font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  transition: background var(--transition), color var(--transition);
  text-align: inherit;
}
.sidebar-logout:hover {
  background: var(--error-dim);
  color: var(--error-dim);
}
.sidebar-logout:active { transform: scale(0.99); }
.sidebar-logout-icon {
  width: 32px; height: 32px;
  border-radius: 9px;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-2);
  border: 1px solid var(--border);
  flex-shrink: 0;
  transition: background var(--transition), border-color var(--transition);
}
.sidebar-logout:hover .sidebar-logout-icon {
  background: var(--error-dim);
  border-color: var(--error-dim);
}
.sidebar-logout svg { width: 16px; height: 16px; opacity: 0.85; }

/* Page enter — subtle fade when navigating between shell pages */
@keyframes shell-page-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* ── Main area ───────────────────────────────────────────────────── */
.main {
  flex: 1;
  /* A flex item defaults to min-width:auto and REFUSES to shrink below its
     content. .main only got min-width:0 inside the <=768px block, so between
     769px and ~1300px it stayed as wide as its widest child and hung off the
     edge: the AI page measured 1008px inside a 900px viewport, overflowing
     344px. In RTL that overflow goes LEFT, which is why it went unnoticed —
     every overflow detector here was checking rect.right only.
     Same root cause as the bottom-nav labels earlier; it belongs here, not
     in one breakpoint. */
  min-width: 0;
  margin-left: var(--sidebar-w);
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  animation: shell-page-in 320ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* ── Topbar ──────────────────────────────────────────────────────── */
.topbar {
  height: var(--topbar-h);
  background:
    linear-gradient(180deg, var(--accent-dim) 0%, transparent 42%),
    var(--surface);
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center;
  padding: 0 20px;
  gap: 12px;
  position: sticky; top: 0; z-index: 90;
  backdrop-filter: blur(10px);
}
.topbar::after {
  content: "";
  position: absolute; inset: auto 20px 0 20px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent-dim), transparent);
  opacity: 0.55;
  pointer-events: none;
}
.topbar-title {
  font-size: 15px; font-weight: 700; color: var(--text);
  flex: 1; min-width: 0; letter-spacing: -0.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.topbar-actions {
  display: flex; align-items: center; gap: 8px;
  flex-shrink: 0;
}
.topbar-ws {
  display: flex; align-items: center; gap: 9px;
  padding: 6px 10px 6px 8px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 12px;
  font-size: 12.5px; color: var(--text-2);
  cursor: pointer;
  transition: all var(--transition);
  max-width: 220px;
  box-shadow: none;
}
.topbar-ws:hover {
  border-color: var(--accent-glow);
  color: var(--text);
  background: var(--accent-dim);
  box-shadow: none;
}
.topbar-ws-icon {
  width: 28px; height: 28px;
  border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-dim);
  border: 1px solid var(--accent-dim);
  color: var(--accent-2);
  flex-shrink: 0;
}
.topbar-ws-icon svg { width: 13px; height: 13px; }
.topbar-ws-copy {
  display: flex; flex-direction: column; gap: 1px;
  min-width: 0; flex: 1;
}
.topbar-ws-label {
  font-size: 9.5px; font-weight: 700; color: var(--text-3);
  letter-spacing: 0.04em; text-transform: uppercase; line-height: 1;
}
/* direction:ltr is load-bearing, not cosmetic. "Ali's Workspace" is a Latin
   string in an RTL bar; inheriting rtl made the ellipsis eat the START, so
   the user read "…rkspace" on every page — the least identifying part of
   their own workspace name. Truncating an LTR string from its own end gives
   "Ali's Wor…", which they can actually recognise. */
.topbar-ws-name {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-weight: 600; color: var(--text); line-height: 1.2;
  direction: ltr; text-align: start;
}
.topbar-ws-chevron {
  flex-shrink: 0; opacity: 0.45; color: var(--text-3);
  transition: opacity var(--transition), transform var(--transition);
}
.topbar-ws:hover .topbar-ws-chevron { opacity: 0.85; color: var(--accent-2); }
.topbar-ws-chevron svg { width: 13px; height: 13px; display: block; }
.topbar-btn {
  width: 36px; height: 36px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 11px;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-2);
  transition: all var(--transition);
  flex-shrink: 0;
}
.topbar-btn:hover {
  background: var(--surface-2);
  color: var(--text);
  border-color: var(--border);
  transform: translateY(-1px);
}
.topbar-btn:active { transform: scale(0.96); }
.topbar-btn svg { width: 16px; height: 16px; }
.topbar-btn--menu { margin-inline-end: 0; }

/* ── Page content ────────────────────────────────────────────────── */
.page-content {
  flex: 1;
  width: 100%;
  max-width: 1400px;
  margin-left: auto;
  margin-right: auto;
  padding: 28px 28px 48px;
  box-sizing: border-box;
}
.page-header { margin-bottom: 24px; }
.page-title { font-size: 22px; font-weight: 700; color: var(--text); letter-spacing: -0.4px; }
.page-subtitle { font-size: 13px; color: var(--text-2); margin-top: 3px; }

/* ── Cards ───────────────────────────────────────────────────────── */
.card {
  position: relative;
  background: var(--surface);
  background-image: var(--grad-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 20px;
  box-shadow: none;
  transition: border-color var(--transition), box-shadow var(--transition), transform var(--transition);
}
.card:hover { border-color: var(--border-2); box-shadow: none; }
/* Optional gradient top-edge accent: add class .card-accent */
.card-accent::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: var(--grad-accent);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
.card-title {
  font-size: 12px; font-weight: 600; color: var(--text-3);
  text-transform: uppercase; letter-spacing: 0.06em;
  margin-bottom: 12px;
}

/* ── KPI grid ────────────────────────────────────────────────────── */
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 12px;
  margin-bottom: 24px;
}
.kpi-card {
  position: relative;
  background: var(--surface);
  background-image: var(--grad-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 16px 18px;
  overflow: hidden;
  box-shadow: none;
  transition: border-color var(--transition), box-shadow 0.22s ease, transform 0.22s cubic-bezier(0.34,1.56,0.64,1);
}
.kpi-card::before {
  content: ""; position: absolute; inset-inline-start: 0; top: 0; bottom: 0; width: 3px;
  background: var(--grad-accent);
  opacity: 0; transition: opacity var(--transition);
}
.kpi-card:hover { border-color: var(--border-2); transform: translateY(-3px); box-shadow: none; }
.kpi-card:hover::before { opacity: 1; }
.kpi-label { font-size: 11.5px; color: var(--text-3); font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 8px; }
.kpi-value { font-family: var(--font-display); font-size: 22px; font-weight: 700; color: var(--text); letter-spacing: -0.5px; line-height: 1.2; font-variant-numeric: tabular-nums; }
.kpi-delta {
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 11.5px; font-weight: 600;
  margin-top: 6px;
  padding: 2px 6px;
  border-radius: 4px;
}
.kpi-delta.up-good { color: var(--success); background: var(--success-dim); }
.kpi-delta.down-good { color: var(--success); background: var(--success-dim); }
.kpi-delta.up-bad { color: var(--error); background: var(--error-dim); }
.kpi-delta.down-bad { color: var(--error); background: var(--error-dim); }
.kpi-delta.flat { color: var(--text-3); background: transparent; }

/* ── Campaigns KPI row ──────────────────────────────────────────── */
.camp-kpi-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
  margin-bottom: 24px;
}
.camp-kpi-row--hero {
  grid-template-columns: repeat(3, 1fr);
}
.camp-kpi {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--surface);
  background-image: var(--grad-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px 20px;
  overflow: hidden;
  box-shadow: none;
  transition: border-color var(--transition), box-shadow 0.22s ease, transform 0.22s cubic-bezier(0.34,1.56,0.64,1);
}
.camp-kpi:hover {
  border-color: var(--border-2);
  transform: translateY(-3px);
  box-shadow: none;
}
.camp-kpi-icon {
  flex-shrink: 0;
  width: 42px;
  height: 42px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.camp-kpi-icon svg {
  width: 22px;
  height: 22px;
}
.camp-kpi[data-accent="gold"]  .camp-kpi-icon { background: var(--accent-dim); color: var(--accent); }
.camp-kpi[data-accent="green"] .camp-kpi-icon { background: var(--success-dim); color: var(--success); }
.camp-kpi[data-accent="amber"] .camp-kpi-icon { background: var(--warning-dim); color: var(--warning); }
.camp-kpi[data-accent="blue"]  .camp-kpi-icon { background: rgba(91,141,239,0.12); color: var(--series-2); }
.camp-kpi-body { min-width: 0; }
.camp-kpi-label {
  font-size: 11.5px;
  color: var(--text-3);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 4px;
  white-space: nowrap;
}
.camp-kpi-value {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.5px;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
.camp-kpi-sub {
  font-size: 11px;
  color: var(--text-3);
  margin-top: 2px;
}

/* ── Campaigns chart grid (2×2 outcomes-first) ──────────────────── */
.camp-chart-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
  margin-bottom: 24px;
}

/* ── Charts ──────────────────────────────────────────────────────── */
.chart-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));
  gap: 16px;
  margin-bottom: 24px;
}
.chart-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 20px;
  min-width: 0;
  box-shadow: none;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.chart-card:hover { border-color: var(--border-2); box-shadow: none; }
.chart-card-header {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  margin-bottom: 14px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
}
.chart-card-title { font-family: var(--font-display); font-size: 13.5px; font-weight: 700; color: var(--text); letter-spacing: -0.01em; }
.chart-card-sub {
  font-size: 11px;
  color: var(--text-3);
  font-weight: 500;
  line-height: 1.35;
}
.chart-canvas-wrap {
  position: relative;
  height: 220px;
  max-height: 220px;
  min-height: 220px;
  width: 100%;
  overflow: hidden;
  contain: layout size style;
}
.chart-canvas-wrap > canvas {
  display: block;
  max-width: 100%;
}
.chart-grid, .camp-chart-grid { min-width: 0; }

/* ── Tables ──────────────────────────────────────────────────────── */
.table-wrap {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.table-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
}
.table-title { font-size: 14px; font-weight: 600; color: var(--text); }
table { width: 100%; border-collapse: collapse; }
th {
  text-align: left;
  padding: 11px 16px;
  font-size: 11px; font-weight: 600; color: var(--text-3);
  text-transform: uppercase; letter-spacing: 0.07em;
  border-bottom: 1px solid var(--border);
  background: var(--surface-2);
  white-space: nowrap;
}
td {
  padding: 12px 16px;
  font-size: 13px; color: var(--text);
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
tr:last-child td { border-bottom: none; }
tr:hover td { background: var(--surface-hover); transition: background 0.12s ease; }

/* ── Badges ──────────────────────────────────────────────────────── */
.badge {
  display: inline-flex; align-items: center;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.05em;
}
.badge-green  { background: var(--success-dim); color: var(--success); }
.badge-yellow { background: var(--warning-dim); color: var(--warning); }
.badge-red    { background: var(--error-dim);   color: var(--error); }
.badge-critical { background: var(--critical-dim); color: var(--critical); }
.badge-gray   { background: var(--surface-2); color: var(--text-3); }
.badge-blue   { background: var(--accent-dim); color: var(--accent-2); }

/* ── Buttons ─────────────────────────────────────────────────────── */
.btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 7px 14px;
  border-radius: var(--radius-sm);
  font-size: 13px; font-weight: 600;
  border: none; cursor: pointer;
  transition: transform var(--transition), box-shadow var(--transition), background var(--transition), border-color var(--transition), color var(--transition), filter var(--transition);
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  isolation: isolate;
}
.btn:active { transform: translateY(1px) scale(0.985); }
/* Ripple */
.btn::after {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(circle at var(--rx, 50%) var(--ry, 50%), var(--surface-2) 0%, var(--surface-2) 45%);
  opacity: 0;
  transition: opacity 500ms ease;
  pointer-events: none;
  z-index: -1;
}
.btn.is-rippling::after { opacity: 1; transition: opacity 0ms; }
.btn-primary { background: var(--grad-accent); color: #fff; box-shadow: none; }
.btn-primary:hover { background: var(--grad-accent-hover); transform: translateY(-1px); box-shadow: none; }
.btn-primary:active { transform: translateY(0) scale(0.985); }
.btn-secondary {
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--border-control);
}
/* color was #fff — a dark-theme leftover that painted white text on a
   light-green ground the moment the pointer touched it. */
.btn-secondary:hover { background: var(--surface-hover); border-color: var(--accent); color: var(--text); transform: translateY(-1px); }
.btn-danger { background: var(--error-dim); color: var(--error); border: 1px solid transparent; }
.btn-danger:hover { background: var(--error); color: #fff; transform: translateY(-1px); box-shadow: none; }
.btn-ghost { background: transparent; color: var(--text-2); }
.btn-ghost:hover { background: var(--surface-hover); color: var(--text); }
.btn-success { background: var(--grad-success); color: #fff; box-shadow: none; }
.btn-success:hover { transform: translateY(-1px); filter: brightness(1.08); box-shadow: none; }
.btn-sm { padding: 5px 10px; font-size: 12px; }
.btn-lg { padding: 10px 20px; font-size: 14px; }
.btn:disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; transform: none; box-shadow: none; }
/* Loading state: hide label, show spinner */
.btn.is-loading { color: transparent !important; pointer-events: none; }
.btn.is-loading::before {
  content: "";
  position: absolute; top: 50%; left: 50%;
  width: 15px; height: 15px; margin: -7.5px 0 0 -7.5px;
  border: 2px solid var(--border);
  border-top-color: #fff;
  border-radius: 50%;
  animation: btn-spin 0.6s linear infinite;
  z-index: 1;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }

/* ── Forms ───────────────────────────────────────────────────────── */
.form-group { margin-bottom: 16px; }
.form-label { display: block; font-size: 12.5px; font-weight: 500; color: var(--text-2); margin-bottom: 6px; }
.form-input {
  width: 100%;
  background: var(--surface-2);
  border: 1px solid var(--border-control);
  border-radius: var(--radius-sm);
  padding: 8px 12px;
  font-size: 13.5px; color: var(--text);
  outline: none;
  transition: border-color var(--transition);
}
.form-input:focus { border-color: var(--accent); }
.form-input::placeholder { color: var(--text-3); }
select.form-input { cursor: pointer; }

/* ── Alerts ──────────────────────────────────────────────────────── */
.alert {
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  margin-bottom: 16px;
  display: flex; align-items: flex-start; gap: 9px;
}
.alert-error { background: var(--error-dim); color: var(--error); border: 1px solid var(--error-dim); }
.alert-success { background: var(--success-dim); color: var(--success); border: 1px solid var(--success-dim); }
.alert-warning { background: var(--warning-dim); color: var(--warning); border: 1px solid var(--warning-dim); }
.alert-info { background: var(--accent-dim); color: var(--accent-2); border: 1px solid var(--accent-dim); }

/* ── Global token-decrypt failure banner ─────────────────────────── */
.token-decrypt-banner {
  display: none;
  align-items: center;
  gap: 14px;
  padding: 14px 24px;
  background: linear-gradient(90deg, rgba(199,56,42,0.22), var(--error-dim));
  border-bottom: 2px solid var(--critical);
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.45;
  position: sticky;
  top: var(--topbar-h);
  z-index: 85;
}
.token-decrypt-banner.visible { display: flex; }
.token-decrypt-banner-icon {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  color: var(--critical);
}
.token-decrypt-banner-body { flex: 1; min-width: 0; }
.token-decrypt-banner-title {
  font-size: 14px;
  font-weight: 800;
  color: var(--error-dim);
  letter-spacing: -0.2px;
  margin-bottom: 2px;
}
.token-decrypt-banner-text {
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
}
.token-decrypt-banner-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
.token-decrypt-banner .btn-reconnect {
  background: var(--critical);
  color: #fff;
  padding: 8px 16px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--transition);
}
.token-decrypt-banner .btn-reconnect:hover { background: var(--critical); color: #fff; }
.token-decrypt-banner-dismiss {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-2);
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.token-decrypt-banner-dismiss:hover { background: var(--surface-2); color: var(--text); }
@media (max-width: 768px) {
  .token-decrypt-banner { flex-wrap: wrap; padding: 12px 16px; }
  .token-decrypt-banner-actions { width: 100%; justify-content: flex-end; }
}

/* ── Empty state ─────────────────────────────────────────────────── */
.empty-state {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 48px 24px;
  text-align: center;
}
.empty-icon { font-size: 36px; margin-bottom: 12px; opacity: 0.4; }
.empty-title { font-size: 15px; font-weight: 600; color: var(--text); margin-bottom: 6px; }
.empty-text { font-size: 13px; color: var(--text-2); max-width: 300px; }

/* ── Spinner ─────────────────────────────────────────────────────── */
.spinner {
  width: 20px; height: 20px;
  border: 2px solid var(--border-2);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
  display: inline-block;
}
@keyframes spin { to { transform: rotate(360deg); } }
.loading-overlay {
  display: flex; align-items: center; justify-content: center;
  min-height: 300px;
  flex-direction: column; gap: 12px;
}
.loading-text { font-size: 13px; color: var(--text-2); }

/* ── Health score ring ───────────────────────────────────────────── */
.health-ring { position: relative; display: inline-flex; align-items: center; justify-content: center; }
.health-number { font-size: 24px; font-weight: 800; letter-spacing: -0.5px; }
.health-label { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.1em; }

/* ── Section divider ─────────────────────────────────────────────── */
.section-gap { margin-bottom: 24px; }

/* ── Flex helpers ────────────────────────────────────────────────── */
.flex { display: flex; }
.flex-1 { flex: 1; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-2 { gap: 8px; }
.gap-3 { gap: 12px; }
.gap-4 { gap: 16px; }

/* ── Text helpers ────────────────────────────────────────────────── */
.text-2 { color: var(--text-2); }
.text-3 { color: var(--text-3); }
.text-sm { font-size: 12px; }
.text-xs { font-size: 11px; }
.font-medium { font-weight: 500; }
.font-semibold { font-weight: 600; }
.font-bold { font-weight: 700; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Tabs ────────────────────────────────────────────────────────── */
.tabs { display: flex; gap: 2px; padding: 3px; background: var(--surface-2); border-radius: var(--radius-sm); border: 1px solid var(--border-control); width: fit-content; }
.tab {
  padding: 5px 12px; font-size: 12.5px; font-weight: 500; color: var(--text-2);
  border-radius: 4px; cursor: pointer; transition: all var(--transition); border: none; background: none;
}
/* The active pill is white on an --surface-2 track: 1.16:1. Inset ring
   instead of a border so selecting a tab does not shift the row by 2px. */
.tab.active { background: var(--surface); color: var(--text); box-shadow: inset 0 0 0 1px var(--border-control); }
.tab:hover:not(.active) { color: var(--text); }

/* ── Search ──────────────────────────────────────────────────────── */
.search-wrap { position: relative; }
.search-wrap svg { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); width: 14px; height: 14px; color: var(--text-3); pointer-events: none; }
.search-input { padding-left: 32px !important; }

/* ── Toast ───────────────────────────────────────────────────────── */
#toast-container {
  position: fixed; bottom: 20px; right: 20px; z-index: 9999;
  display: flex; flex-direction: column; gap: 8px;
}
.toast {
  padding: 12px 16px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-size: 13px; color: var(--text);
  box-shadow: none;
  animation: slide-in 0.2s ease;
  max-width: 320px;
}
.toast.success { border-left: 3px solid var(--success); }
.toast.error   { border-left: 3px solid var(--error); }
.toast.info    { border-left: 3px solid var(--accent); }
.toast.warning { border-left: 3px solid var(--warning); }
@keyframes slide-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }

/* ── Background sync status bar (B-0) ─────────────────────────────── */
.sync-status-bar {
  display: none;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  margin-bottom: 16px;
  background: var(--accent-dim);
  border: 1px solid var(--accent-glow);
  border-radius: var(--radius-lg);
  font-size: 13px;
  color: var(--text);
}
.sync-status-inner { display: flex; align-items: center; gap: 10px; flex: 1; min-width: 0; flex-wrap: wrap; }
.sync-status-spinner {
  width: 14px; height: 14px; flex-shrink: 0;
  border: 2px solid var(--accent-glow);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.75s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.sync-status-text { font-weight: 600; color: var(--text); }
.sync-status-progress {
  flex: 1; min-width: 80px; max-width: 200px; height: 5px;
  background: var(--border); border-radius: 999px; overflow: hidden;
}
.sync-status-progress-bar {
  height: 100%; width: 0%;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  border-radius: 999px;
  transition: width 0.5s ease;
}
.sync-status-meta { font-size: 11.5px; color: var(--text-3); margin-left: auto; }

/* ── Meta CDN image fallbacks (C-2) ─────────────────────────────── */
.meta-img-wrap, .inspector-creative-thumb {
  position: relative;
  overflow: hidden;
  background: var(--surface-2);
}
.meta-img-wrap img, .inspector-creative-img {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.meta-img-wrap img.meta-img-loading {
  opacity: 0;
}
.meta-img-fallback, .inspector-creative-fallback {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  font-size: 28px;
  background: linear-gradient(135deg, var(--surface-2) 0%, var(--surface) 100%);
  color: var(--text-3);
}
.meta-img-fallback.visible, .inspector-creative-fallback.visible { display: flex; }
.meta-img-placeholder {
  position: absolute; inset: 0;
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-hover) 50%, var(--surface-2) 75%);
  background-size: 200% 100%;
  animation: meta-img-shimmer 1.2s ease-in-out infinite;
}
@keyframes meta-img-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
.section-fallback {
  padding: 16px; border: 1px dashed var(--border);
  border-radius: var(--radius); color: var(--text-3); font-size: 13px; text-align: center;
}

/* ── Modal ───────────────────────────────────────────────────────── */
.modal-overlay {
  position: fixed; inset: 0; background: transparent;
  display: flex; align-items: center; justify-content: center;
  z-index: 200; backdrop-filter: blur(4px);
  animation: fade-in 0.15s ease;
}
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
.modal {
  background: var(--surface);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-lg);
  padding: 24px;
  width: 100%; max-width: 440px;
  box-shadow: none;
  animation: scale-in 0.15s ease;
}
@keyframes scale-in { from { opacity: 0; transform: scale(0.97); } to { opacity: 1; transform: scale(1); } }
.modal-title { font-size: 16px; font-weight: 700; color: var(--text); margin-bottom: 6px; }
.modal-subtitle { font-size: 13px; color: var(--text-2); margin-bottom: 20px; }
.modal-footer { display: flex; justify-content: flex-end; gap: 8px; margin-top: 20px; }

/* ── Metric "Explain" info trigger + popover body ───────────────────── */
.info-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border-radius: 50%;
  background: transparent; border: 1px solid var(--text-3); color: var(--text-3);
  font-size: 10px; font-weight: 700; line-height: 1; cursor: pointer;
  flex-shrink: 0; transition: all var(--transition);
}
.info-btn:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-dim); }
.metric-info-block { margin-bottom: 14px; }
.metric-info-block:last-child { margin-bottom: 0; }
.metric-info-block-title { font-size: 10.5px; font-weight: 700; color: var(--text-3); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 5px; }
#metric-info-body p { font-size: 13px; color: var(--text-2); line-height: 1.55; }
.metric-info-formula { font-family: var(--font-mono); font-size: 13.5px; color: var(--accent-2); background: var(--accent-dim); border-radius: var(--radius-sm); padding: 8px 10px; display: inline-block; }
.metric-info-causes { margin: 0; padding-inline-start: 18px; font-size: 13px; color: var(--text-2); line-height: 1.6; }
.metric-info-causes li { margin-bottom: 3px; }

/* ── Command Palette — ported from AdsPulse ─────────────────────────────
   The pattern proven on the AdsPulse flagship page: one input, a filtered
   list, arrow-key navigation, Enter to run. Adlytic's version sources its
   items from the page's own nav (so admin entries appear only when the
   sidebar rendered them) plus a small set of shell actions. Opened with
   Ctrl+K (layout-independent via e.code), the slash key, or the topbar
   button; closed with Esc, backdrop, or running an item. */
.cmd-overlay {
  position: fixed; inset: 0; z-index: 300;
  background: var(--scrim); backdrop-filter: blur(2px);
  display: none; align-items: flex-start; justify-content: center;
  padding: 12vh 16px 16px;
}
.cmd-overlay.is-open { display: flex; animation: fade-in 0.12s ease; }
.cmd-box {
  width: 100%; max-width: 560px;
  background: var(--surface);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-lg);
  overflow: hidden;
  animation: scale-in 0.12s ease;
}
.cmd-input-row {
  display: flex; align-items: center; gap: 10px;
  padding: 2px 16px;
  border-bottom: 1px solid var(--border);
}
.cmd-input-row svg { width: 16px; height: 16px; color: var(--text-3); flex-shrink: 0; }
.cmd-input {
  flex: 1; min-width: 0; min-height: 46px;
  border: none; outline: none; background: transparent; box-shadow: none;
  color: var(--text); font: inherit; font-size: 15px; padding: 12px 0;
}
/* The palette IS the focus context — the whole box lights up instead of a
   ring around the bare input, which the global field styles draw oddly here. */
.cmd-input:focus, .cmd-input:focus-visible { border: none; box-shadow: none; outline: none; }
.cmd-box:focus-within { border-color: var(--accent); }
.cmd-input::placeholder { color: var(--text-3); }
.cmd-list { max-height: min(320px, 42vh); overflow-y: auto; padding: 6px; }
.cmd-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: 10px 12px;
  border: none; background: transparent; border-radius: var(--radius);
  color: var(--text); font: inherit; font-size: 14px;
  text-align: start; cursor: pointer;
}
/* Same pair as .nav-item.active — the one accent-on-dim combo the palette
   (colour palette, that is) already certifies for small text. */
.cmd-item:hover, .cmd-item[aria-selected="true"] { background: var(--accent-dim); color: var(--accent-2); }
.cmd-item-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmd-item-kind { font-size: 11px; color: var(--text-3); flex-shrink: 0; }
.cmd-empty { padding: 22px 16px; font-size: 13px; color: var(--text-2); text-align: center; }
.cmd-foot {
  display: flex; gap: 16px; align-items: center;
  padding: 8px 16px; border-top: 1px solid var(--border);
  font-size: 11px; color: var(--text-3);
}
.cmd-foot span { display: inline-flex; align-items: center; gap: 5px; }
kbd.cmd-kbd {
  display: inline-block; min-width: 18px; padding: 1px 5px;
  border: 1px solid var(--border-2); border-bottom-width: 2px;
  border-radius: var(--radius-sm);
  background: var(--surface-2); color: var(--text-2);
  font-family: inherit; font-size: 10.5px; font-weight: 600;
  text-align: center; line-height: 1.5;
}
/* Topbar trigger: desktop-only. On phones the bottom nav already puts every
   destination one thumb away; the palette stays reachable but not advertised. */
/* Two classes, not one: the touch-target layer later in this file re-asserts
   display on every .topbar-btn, and at equal specificity the later rule wins —
   which put this button back on phones. .topbar-actions makes hide/show
   outrank that layer in both directions. */
.topbar-actions .topbar-btn--cmd { display: none; }
@media (min-width: 1024px) {
  .topbar-actions .topbar-btn--cmd {
    display: inline-flex; align-items: center; gap: 8px;
    width: auto; padding: 0 12px;
  }
  .topbar-btn--cmd .cmd-kbd { pointer-events: none; }
}

/* ── Shortcuts map (the ؟ overlay) — ported from AdsPulse ──────────────── */
.kbd-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 0; border-bottom: 1px solid var(--border);
  font-size: 13.5px; color: var(--text-2);
}
.kbd-row:last-child { border-bottom: none; }
/* Key sequences read left-to-right regardless of page direction — they
   mirror what is printed on the physical keyboard. */
.kbd-keys { display: flex; gap: 4px; direction: ltr; flex-shrink: 0; }

/* ── Density axis — ported from AdsPulse ────────────────────────────────
   One attribute on <html>, persisted per browser, toggled from the command
   palette. Desktop-only by media query: on touch screens compact rows would
   fall below the 44px target minimum the mobile gate enforces. */
@media (min-width: 1024px) and (pointer: fine) {
  html[data-density="compact"] th { padding: 7px 12px; }
  html[data-density="compact"] td { padding: 7px 12px; font-size: 12.5px; }
  html[data-density="compact"] .card { padding: 16px; }
}

/* ── Smart Context Actions — chip row under a KPI's delta, only when an
   issue is actively affecting that metric. Quiet by default (no chips on
   healthy metrics), matches the redesign's "recessive unless there's a
   story" principle. ──────────────────────────────────────────────────── */
.context-actions { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 7px; }
.context-action-chip {
  display: inline-flex; align-items: center;
  font-size: 10.5px; font-weight: 600;
  padding: 3px 9px; border-radius: 999px;
  background: var(--accent-dim); color: var(--accent-2);
  border: 1px solid transparent;
  transition: all var(--transition);
}
.context-action-chip:hover { background: var(--accent); color: #fff; }

/* ── Sidebar overlay (mobile) ─────────────────────────────────────── */
.sidebar-overlay {
  display: none; position: fixed; inset: 0; z-index: 99;
  background: var(--scrim); backdrop-filter: blur(2px);
  opacity: 0; transition: opacity 0.2s;
}
@media (max-width: 768px) {
  .sidebar-overlay.visible { display: block; opacity: 1; }
}

/* ── Responsive ──────────────────────────────────���───────────────── */
@media (max-width: 768px) {
  /* The off-canvas sidebar is position:fixed and slid off-screen with a
     transform. A translated fixed element STILL contributes to the document's
     horizontal scroll width, so it added ~a sidebar-width of phantom overflow
     on phones (content looked shifted/cut off). Clip it at the root. We use
     the html element (not body) so the sticky topbar's scroll container is
     unaffected. */
  html { overflow-x: hidden; }

  /* OFF-CANVAS SIDEBAR — must not exist outside the viewport at all.
     A position:fixed element's containing block is the VIEWPORT, not the html
     box, so the html overflow-x:hidden above cannot clip it. Translating the
     panel off-screen therefore left a real, draggable horizontal scroll area
     (measured: 117px of sideways drag at 320px in RTL, where the panel is
     pushed to the RIGHT). Arabic is the default locale, so that affected every
     phone user.
     Fix: the closed panel is display:none — no box, no overflow, on either
     side. The slide is restored with a keyframe on open, so the animation is
     unchanged while the geometry problem disappears. */
  .sidebar { display: none; transition: none; z-index: 100; }
  .sidebar.open { display: flex; animation: sidebarIn 0.24s cubic-bezier(0.32, 0.72, 0, 1); }
  @keyframes sidebarIn { from { transform: translateX(-100%); } to { transform: translateX(0); } }
  .main { margin-left: 0; padding-bottom: 72px; min-width: 0; }
  .kpi-grid { grid-template-columns: repeat(2, 1fr); }
  .chart-grid { grid-template-columns: 1fr; }
  .camp-kpi-row { grid-template-columns: repeat(2, 1fr); }
  .camp-kpi-row--hero { grid-template-columns: 1fr; }
  .camp-chart-grid { grid-template-columns: 1fr; }
  .page-content { padding: 14px 12px 24px; }
  .mobile-menu-btn { display: flex !important; }

  /* ══ MOBILE SYSTEM — STRUCTURE ═══════════════════════════════════════
     Layout and overflow containment only.

     The TOUCH and TEXT floors deliberately do NOT live here. They live in
     MOBILE_FLOORS_CSS, which is emitted after every page's own <style>.
     Reason, measured rather than assumed: layout() emits SHARED_CSS in
     <head> and then the page's extraHead, so a page stylesheet always comes
     later in the cascade. A .ws-selector min-height rule sat in this block
     and never applied — the element is id="ws-selector" class="topbar-ws",
     so the selector matched nothing at all; and .auth-footer's 11.5px in
     AUTH_STYLES beat the shared 12px floor purely on source order. Two
     different failures, one symptom: a shared rule that silently loses.
     Emitting the floors last fixes both without a single !important. */

  /* Flex items default to min-width:auto, so they refuse to shrink below
     their content. Raising the label to the 12px text floor made the five
     Arabic labels wider than their 1/5 share and pushed the whole fixed nav
     to 440px at a 320px viewport — reintroducing the horizontal drag this
     system exists to remove. min-width:0 lets them share the row honestly;
     the label truncates rather than the bar overflowing. */
  /* The fixed bar sizes itself against the INITIAL containing block, which in
     RTL had already been widened by overflow — so width:100% resolved to 438px
     at a 320px viewport and the bar itself then sustained the overflow. Pin it
     to the viewport explicitly so it can never participate in that loop. */
  .mobile-bottom-nav {
    left: 0; right: 0;
    width: 100vw; max-width: 100vw;
    box-sizing: border-box;
  }
  .mobile-nav-item {
    min-height: 52px; justify-content: center;
    min-width: 0; padding-inline: 2px;
  }
  /* Belt and braces: nothing in the shell may exceed the viewport. */
  body, .app-shell, .main, .page-content { max-width: 100vw; overflow-x: clip; }
  .mobile-nav-item span {
    font-size: 12px;
    max-width: 100%;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }

  /* Tab rows scroll inside themselves rather than widening the page. */
  .tabs, .tab-row, .chip-row {
    display: flex; flex-wrap: nowrap;
    overflow-x: auto; -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .tabs::-webkit-scrollbar, .tab-row::-webkit-scrollbar, .chip-row::-webkit-scrollbar { display: none; }

  /* — Density —————————————————————————————————————
     Card padding tightens on the narrowest phones so content, not chrome,
     owns the width. Applied by breakpoint rather than by !important. */
  .card, .panel { padding: 14px; }
}

@media (max-width: 380px) {
  /* On the tightest phones the workspace NAME is dropped and the selector
     becomes icon-only. The control is not removed — it is still a 44px
     target that opens the same switcher. This is the one piece of topbar
     text that can go without losing a function, and dropping it is what
     keeps the notifications bell on screen at 320px. */
  .topbar-ws-name, .topbar-ws-chevron { display: none; }
  .topbar-ws { min-width: 44px; justify-content: center; padding-inline: 0; }
  /* The mode toggle is the largest item in the bar (~135px) and it is the
     ONLY place either mode can be selected — hiding it would delete the
     feature, so it tightens instead. Reclaiming its padding is what lets
     the notifications bell stay on screen at 320px while every control
     keeps a 44px target. Height is untouched; only the horizontal padding
     gives. */
  .mode-toggle-btn { padding-inline: 8px; }
  .topbar { gap: 4px; }
  .topbar-actions { gap: 4px; }

  /* 320–375px: the tightest real devices (iPhone SE, older Androids). */
  .card, .panel, .page-content { padding-inline: 10px; }
  .kpi-grid { grid-template-columns: 1fr; }
  .result-chips { gap: 8px; }
  .funnel-stage { padding: 9px 11px; }
  .funnel-stage-count { font-size: 16px; }
  .diag-title { font-size: 16px; }
}

@media (max-width: 768px) {
  /* — Reduced motion is honoured for the new sidebar animation too — */
  @media (prefers-reduced-motion: reduce) {
    .sidebar.open { animation: none; }
    [dir="rtl"] .sidebar.open { animation: none; }
  }
  .topbar { padding: 0 12px; }
  /* The page title is HIDDEN on a phone, deliberately — not shrunk.
     At 390px the bar holds a menu button, this title, the mode toggle, the
     workspace selector and three icon buttons. Something has to yield, and
     the title is the one piece of information already shown elsewhere: the
     bottom nav labels the current page and highlights it. Squeezing it
     instead produced "لوحة ا…" — a truncated word that identifies nothing
     while still consuming the space the workspace name needed.
     The workspace name is NOT duplicated anywhere, so it gets the room. */
  .topbar-title { display: none; }
  .topbar-ws-name { max-width: 148px; }
  /* Below 44px a control is not a control. Letting the workspace selector
     absorb the whole squeeze took it to 18x44 at 320px — present, on screen,
     and untappable. It keeps a real target and stops shrinking there. */
  .topbar-ws { min-width: 44px; }
  .modal { max-width: calc(100vw - 24px) !important; margin: 12px auto !important; }
}
.mobile-menu-btn { display: none; }

/* ── Beginner mode: hide pro chrome (sidebar + mobile nav) ───────────
   Beginner is a focused, simplified surface. Pro navigation lives in the
   sidebar / bottom nav — hide both so only the beginner dashboard +
   topbar (mode toggle) remain. Switching back to احترافي restores them. */
.app-shell--beginner .sidebar,
.app-shell--beginner + .mobile-bottom-nav,
body:has(.app-shell--beginner) .mobile-bottom-nav,
body:has(.app-shell--beginner) .sidebar-overlay {
  display: none !important;
}
.app-shell--beginner .main {
  margin-left: 0 !important;
  margin-right: 0 !important;
}
.app-shell--beginner .mobile-menu-btn { display: none !important; }
[dir="rtl"] .app-shell--beginner .main {
  margin-left: 0 !important;
  margin-right: 0 !important;
}
@media (max-width: 768px) {
  .app-shell--beginner .main { padding-bottom: 24px; }
}

/* ── Mobile Bottom Navigation ─────────────────────────────────────── */
.mobile-bottom-nav {
  display: none;
  position: fixed; bottom: 0; left: 0; right: 0;
  z-index: 1000;
  background: var(--surface);
  border-top: 1px solid var(--border);
  padding: 6px 0 env(safe-area-inset-bottom, 8px);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
@media (max-width: 768px) {
  .mobile-bottom-nav { display: flex; }
}
.mobile-nav-item {
  flex: 1;
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 8px 4px 6px;
  text-decoration: none;
  color: var(--text-3);
  font-size: 10px; font-weight: 700;
  transition: color 0.22s ease, transform 0.18s ease;
  -webkit-tap-highlight-color: transparent;
}
.mobile-nav-item::before {
  content: "";
  position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 0; height: 3px; border-radius: 999px;
  background: var(--grad-accent);
  transition: width 0.25s cubic-bezier(0.34, 1.2, 0.64, 1);
}
.mobile-nav-item svg { width: 21px; height: 21px; transition: transform 0.2s ease; }
.mobile-nav-item.active {
  color: var(--accent-2);
}
.mobile-nav-item.active::before { width: 28px; }
.mobile-nav-item.active svg { transform: translateY(-1px); }
.mobile-nav-item:active { transform: scale(0.94); }

/* ── Mobile touch targets + spacing ───────────────────────────────── */
@media (max-width: 768px) {
  .btn, .topbar-btn, .nav-item, .context-action-chip { min-height: 44px; min-width: 44px; }
  .info-btn { min-width: 32px; min-height: 32px; font-size: 13px; }
  .ticker-item { padding: 6px 12px; }
  .strategy-card { padding: 14px 16px; }
  .hero-card { padding: 16px; }
  .hero-value { font-size: 26px; }
  .hero-label { font-size: 10px; }
}

/* ── Dashboard mode toggle (Pro / Beginner) ──────────────────────────── */
.mode-toggle {
  position: relative;
  display: inline-flex; align-items: center;
  padding: 3px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  box-shadow: none;
}
.mode-toggle-indicator {
  position: absolute;
  top: 3px; bottom: 3px;
  left: 0;
  border-radius: 999px;
  background: var(--grad-accent);
  box-shadow: none;
  pointer-events: none;
  transition:
    transform 280ms cubic-bezier(0.34, 1.2, 0.64, 1),
    width 280ms cubic-bezier(0.34, 1.2, 0.64, 1);
  z-index: 0;
}
.mode-toggle-btn {
  position: relative; z-index: 1;
  padding: 6px 13px;
  font-size: 12px; font-weight: 700;
  color: var(--text-3);
  background: transparent;
  border: none; border-radius: 999px;
  cursor: pointer;
  transition: color 200ms ease;
  font-family: inherit;
  white-space: nowrap;
}
.mode-toggle-btn:hover { color: var(--text); }
/* The label sits on .mode-toggle-indicator — an absolutely-positioned
   SIBLING filled with --accent, not on any ancestor. --surface reads 11.66:1
   against it; the previous --bg read 10.76:1, so this is a small clarity
   gain, NOT a bug fix.
   Recorded because an automated audit flagged this at 1.07:1 and it was
   wrong: the probe walked ancestors for the backdrop, and the real backdrop
   is a sibling it could never see. Verified by screenshot — white on deep
   green, entirely legible. Any future contrast checker will trip here for
   the same reason; the element is fine. */
.mode-toggle-btn.active { color: var(--surface); }

/* ── RTL Support ────────────────────────────────────────────────── */
[dir="rtl"] .sidebar { left: auto; right: 0; border-right: none; border-left: 1px solid var(--border); }
[dir="rtl"] .main { margin-left: 0; margin-right: var(--sidebar-w); }
[dir="rtl"] th { text-align: right; }
[dir="rtl"] .search-wrap svg { left: auto; right: 10px; }
[dir="rtl"] .search-input { padding-left: 12px !important; padding-right: 32px !important; }
[dir="rtl"] .toast.success { border-left: none; border-right: 3px solid var(--success); }
[dir="rtl"] .toast.error { border-left: none; border-right: 3px solid var(--error); }
[dir="rtl"] .toast.info { border-left: none; border-right: 3px solid var(--accent); }
[dir="rtl"] .toast.warning { border-left: none; border-right: 3px solid var(--warning); }
[dir="rtl"] #toast-container { right: auto; left: 20px; }
[dir="rtl"] .kpi-value, [dir="rtl"] .health-number { font-feature-settings: 'tnum'; direction: ltr; }
[dir="rtl"] .sync-status-meta { margin-left: 0; margin-right: auto; }
[dir="rtl"] .mode-toggle { margin-right: 0; margin-left: 0; }
[dir="rtl"] .topbar-btn.mobile-menu-btn { margin-right: 0; margin-left: 0; }
@media (max-width: 768px) {
  .topbar-actions { gap: 6px; }
  .topbar-ws-label { display: none; }
  .topbar-ws { max-width: 140px; padding: 5px 8px; }
  .mode-toggle-btn { padding: 6px 10px; font-size: 11px; }
}
@media (max-width: 768px) {
  /* RTL slides in from the right; same display-based hiding as above. */
  [dir="rtl"] .sidebar { display: none; z-index: 100; }
  [dir="rtl"] .sidebar.open { display: flex; animation: sidebarInRtl 0.24s cubic-bezier(0.32, 0.72, 0, 1); }
  @keyframes sidebarInRtl { from { transform: translateX(100%); } to { transform: translateX(0); } }
  [dir="rtl"] .main { margin-right: 0; }
}

/* ── Diagnosis cards ────────────────────────────────────────────── */
.diagnosis-grid { display: grid; grid-template-columns: 1fr; gap: 14px; margin-bottom: 8px; }
.diagnosis-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 16px 16px 14px;
  border-inline-start: 3px solid var(--accent);
  direction: rtl;
  transition: border-color var(--transition);
  width: 100%;
  max-width: none;
}
.diagnosis-card:hover { border-color: var(--accent-glow); }
.diagnosis-header { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.diagnosis-name { font-size: 14.5px; font-weight: 800; color: var(--text); line-height: 1.35; }
.diagnosis-confidence { font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: 999px; white-space: nowrap; }
.diagnosis-confidence.high { background: var(--success-dim); color: var(--success); }
.diagnosis-confidence.medium { background: var(--warning-dim); color: var(--warning); }
.diagnosis-confidence.low { background: var(--surface-2); color: var(--text-3); }
.diagnosis-narrative { font-size: 13.5px; color: var(--text-2); line-height: 1.65; margin-bottom: 12px; }
.diagnosis-action {
  font-size: 13px; color: var(--text); background: var(--accent-dim);
  border: 1px solid var(--accent-dim);
  padding: 11px 13px; border-radius: 12px; line-height: 1.55;
}
.diagnosis-action-label { font-weight: 800; font-size: 11px; margin-bottom: 4px; color: var(--accent-2); }
.diagnosis-expect {
  margin-top: 8px; font-size: 12.5px; color: var(--text-2); line-height: 1.5;
  padding-top: 8px; border-top: 1px dashed var(--accent-dim);
}
.diagnosis-card--hero {
  padding: 20px 20px 16px;
  border-inline-start-width: 4px;
  background:
    radial-gradient(120% 80% at 100% 0%, var(--accent-dim), transparent 55%),
    var(--surface);
  border-color: var(--accent-glow);
  box-shadow: none;
}
.diagnosis-card--hero .diagnosis-name { font-size: 20px; letter-spacing: -0.02em; }
.diagnosis-card--hero .diagnosis-narrative { font-size: 14px; margin-bottom: 14px; }
.diagnosis-card--hero .diagnosis-action { font-size: 13.5px; padding: 13px 14px; }
.diagnosis-cta-row { margin-top: 14px; }
.diagnosis-card--hero.has-critical { border-inline-start-color: var(--error); }
.diagnosis-card--hero.has-warning { border-inline-start-color: var(--warning); }
/* Standalone headline used ONLY by the redesigned pro dashboard's hero
   (dashboardPage.ts renderMainMove) — sits below the header row rather than
   inline with the confidence badge, so it needs its own class rather than
   reusing .diagnosis-name (which beginnerDashboardPage.ts still renders
   INSIDE .diagnosis-header, inline with its badge — giving it this same
   large/display treatment would break that page's header alignment). */
.diagnosis-headline {
  font-family: var(--font-display); font-weight: 700;
  font-size: 21px; line-height: 1.45; letter-spacing: -0.01em;
  color: var(--text);
  margin-bottom: 14px;
}

/* ── The golden thread — signature narrative treatment ────────────────────
   A vertical connector linking the read (evidence + diagnosis) to the
   recommendation, so a decision reads as one continuous line of reasoning
   instead of stacked, disconnected paragraphs. Reused wherever the product
   narrates a diagnosis: dashboard hero, AI assistant replies, ad analysis,
   tasks. The final step's dot is filled solid — it's where the reasoning
   resolves into an action. */
.thread { position: relative; padding-inline-start: 22px; }
.thread::before {
  content: ""; position: absolute; inset-inline-start: 5px; top: 5px; bottom: 5px;
  width: 2px; border-radius: 2px;
  background: linear-gradient(180deg, var(--accent), var(--accent-dim));
}
.thread-steps { display: flex; flex-direction: column; gap: 12px; }
.thread-step { position: relative; font-size: 13px; line-height: 1.6; color: var(--text); }
.thread-step::before {
  content: ""; position: absolute; inset-inline-start: -22px; top: 4px;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--bg); border: 2px solid var(--accent-glow);
}
.thread-step-label { display: block; font-size: 10px; font-weight: 800; color: var(--accent-2); margin-bottom: 3px; }
.thread-step-sub { margin-top: 6px; font-size: 12px; color: var(--text-2); }
.thread-step--action::before { background: var(--accent); border-color: var(--accent); box-shadow: none; }

/* ── Unified honest status strip — one connected read on where every
   campaign actually stands, replacing scattered counters. Segments are
   proportional to real counts; "بدون إنفاق" (Meta-ACTIVE, zero spend) is
   rendered in --warning, never counted as delivering — see
   lib/campaignCatalog.ts for the counts contract this renders. ─────────── */
.status-strip-bar { display: flex; height: 10px; border-radius: 999px; overflow: hidden; gap: 2px; background: var(--surface-2); }
.status-strip-bar > span { display: block; min-width: 2px; }
.status-strip-legend { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 9px; font-size: 10.5px; color: var(--text-2); font-weight: 700; }
.status-strip-item { display: flex; align-items: center; gap: 5px; }
.status-strip-dot { width: 8px; height: 8px; border-radius: 3px; flex-shrink: 0; }
.status-strip-note { margin-top: 7px; font-size: 10.5px; color: var(--text-3); line-height: 1.5; }

/* Advanced analytics section chrome (shared) */
.adv-block { margin-bottom: 22px; direction: rtl; }
.adv-block-head { margin-bottom: 12px; }
.adv-block-title {
  font-size: 13px; font-weight: 800; color: var(--text);
  padding-inline-start: 10px; border-inline-start: 3px solid var(--accent);
}
.adv-block-sub { font-size: 12px; color: var(--text-3); margin-top: 4px; padding-inline-start: 13px; }
.adv-empty-ok {
  font-size: 13px; color: var(--text-2); padding: 14px 16px;
  background: var(--success-dim); border: 1px solid var(--success-dim);
  border-radius: 12px;
}
.adv-issues-list { display: flex; flex-direction: column; gap: 0; }
.adv-issue-row { padding: 12px 0; border-bottom: 1px solid var(--border); }
.adv-issue-row:last-child { border-bottom: none; }
.adv-issue-top { display: flex; justify-content: space-between; gap: 10px; align-items: flex-start; }
.adv-issue-title { font-size: 13.5px; font-weight: 700; color: var(--text); }
.adv-issue-sev {
  font-size: 10.5px; font-weight: 800; padding: 3px 8px; border-radius: 999px; white-space: nowrap;
}
.adv-issue-sev.critical { background: var(--error-dim); color: var(--error); }
.adv-issue-sev.high { background: var(--warning-dim); color: var(--warning); }
.adv-issue-sev.medium { background: var(--accent-dim); color: var(--accent-2); }
.adv-issue-sev.low { background: var(--surface-2); color: var(--text-3); }
.adv-issue-why { font-size: 12.5px; color: var(--text-2); margin-top: 4px; line-height: 1.5; }
.adv-issue-action { font-size: 12.5px; color: var(--accent-2); margin-top: 6px; line-height: 1.5; }
.adv-campaigns-table { width: 100%; border-collapse: collapse; direction: rtl; }
.adv-campaigns-table th {
  text-align: start; font-size: 11px; font-weight: 700; color: var(--text-3);
  padding: 8px 10px; border-bottom: 1px solid var(--border); white-space: nowrap;
}
.adv-campaigns-table td {
  padding: 12px 10px; border-bottom: 1px solid var(--border);
  font-size: 13px; color: var(--text); vertical-align: top;
}
.adv-camp-name { font-weight: 700; line-height: 1.35; }
.adv-camp-obj { font-size: 11.5px; color: var(--text-3); margin-top: 3px; }
.adv-camp-num { font-variant-numeric: tabular-nums; white-space: nowrap; }
.adv-camp-note {
  display: inline-flex; font-size: 11px; font-weight: 700; padding: 3px 8px; border-radius: 999px;
}
.adv-camp-note.note-best { background: var(--success-dim); color: var(--success); }
.adv-camp-note.note-worst { background: var(--error-dim); color: var(--error); }
.adv-camp-note.note-danger { background: rgba(211,47,47,0.14); color: var(--error); }
.adv-camp-note.note-hot { background: var(--accent-dim); color: var(--accent-2); }
.adv-camp-note.note-watch { background: var(--warning-dim); color: var(--warning); }
.adv-camp-note.note-muted { background: var(--surface-2); color: var(--text-3); }

/* ── Attribution bar ────────────────────────────────────────────── */
.attribution-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px 20px;
  margin-bottom: 24px;
}
.attribution-title { font-size: 13px; font-weight: 800; color: var(--text); margin-bottom: 14px; }
.attribution-bars { display: flex; gap: 16px; flex-wrap: wrap; }
.attribution-factor { flex: 1; min-width: 120px; }
.attribution-factor-label { font-size: 12px; color: var(--text-2); margin-bottom: 6px; font-weight: 500; }
.attribution-factor-value { font-size: 20px; font-weight: 700; letter-spacing: -0.3px; direction: ltr; }
.attribution-factor-value.positive { color: var(--success); }
.attribution-factor-value.negative { color: var(--error); }
.attribution-factor-value.neutral { color: var(--text-3); }
.attribution-factor-bar {
  height: 4px; border-radius: 2px; margin-top: 6px;
  background: var(--surface-2);
}
.attribution-factor-fill {
  height: 100%; border-radius: 2px;
  transition: width 0.5s ease;
}
.attribution-primary-tag {
  display: inline-block; font-size: 10px; font-weight: 700; text-transform: uppercase;
  padding: 1px 6px; border-radius: 3px; margin-top: 4px;
  background: var(--accent-dim); color: var(--accent-2); letter-spacing: 0.05em;
}
.attribution-narrative { font-size: 13px; color: var(--text-2); margin-top: 14px; line-height: 1.6; padding-top: 14px; border-top: 1px solid var(--border); }
.attribution-creative-card { margin-top: 12px; margin-bottom: 0; }
.attribution-creative-list { display: flex; flex-direction: column; gap: 8px; }
.attribution-creative-row { display: flex; align-items: center; gap: 10px; font-size: 13px; }
.attribution-creative-rank { color: var(--text-3); font-weight: 700; width: 22px; flex-shrink: 0; }
.attribution-creative-name { color: var(--text-1); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.attribution-creative-spend { color: var(--text-2); direction: ltr; font-variant-numeric: tabular-nums; }

/* ── Table horizontal scroll on mobile ──────────────────────────── */
@media (max-width: 768px) {
  .table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .table-wrap table { min-width: 700px; }
  .adv-campaigns-table { min-width: 720px; }
  .account-cards { grid-template-columns: 1fr !important; }
  .rec-grid { grid-template-columns: 1fr !important; }
  .settings-grid { grid-template-columns: 1fr !important; }
  .gate-grid { grid-template-columns: 1fr !important; }
  .diagnosis-grid { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .modal { max-width: calc(100vw - 32px); margin: 16px; }
}

/* ── New components ─────────────────────────────────────────────── */
/* Gradient text (headings / brand emphasis) */
.gradient-text {
  background: var(--grad-accent);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}

/* Skeleton loaders */
.skeleton {
  position: relative; overflow: hidden;
  background: var(--surface-2);
  border-radius: var(--radius-sm);
}
.skeleton::after {
  content: ""; position: absolute; inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, var(--surface-2), transparent);
  animation: skeleton-shimmer 1.3s infinite;
}
[dir="rtl"] .skeleton::after { animation-name: skeleton-shimmer-rtl; }
@keyframes skeleton-shimmer { 100% { transform: translateX(100%); } }
@keyframes skeleton-shimmer-rtl { 100% { transform: translateX(-100%); } }
[dir="rtl"] .skeleton::after { transform: translateX(100%); }
.skeleton-line { height: 12px; margin-bottom: 8px; }
.skeleton-line.sk-lg { height: 20px; }
.skeleton-line.w-40 { width: 40%; } .skeleton-line.w-60 { width: 60%; } .skeleton-line.w-80 { width: 80%; }
.skeleton-kpi { height: 78px; border-radius: var(--radius-lg); }

/* Empty states */
.empty-state {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 48px 24px; gap: 6px;
}
.empty-state-icon {
  width: 56px; height: 56px; border-radius: 16px;
  display: flex; align-items: center; justify-content: center;
  font-size: 26px; margin-bottom: 10px;
  background: var(--accent-dim); color: var(--accent-2);
}
.empty-state-title { font-size: 15px; font-weight: 700; color: var(--text); }
.empty-state-text { font-size: 13px; color: var(--text-2); max-width: 340px; line-height: 1.6; }
.empty-state .btn { margin-top: 12px; }

/* Tooltips (data-tooltip attribute) */
[data-tooltip] { position: relative; }
[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%) translateY(4px);
  background: var(--surface-2); color: var(--text); border: 1px solid var(--border-2);
  padding: 5px 9px; border-radius: var(--radius-sm);
  font-size: 11.5px; font-weight: 500; white-space: nowrap;
  box-shadow: none;
  opacity: 0; pointer-events: none;
  transition: opacity var(--transition), transform var(--transition);
  z-index: 200;
}
[data-tooltip]:hover::after { opacity: 1; transform: translateX(-50%) translateY(0); }

/* Section header with gradient accent bar */
.section-header {
  display: flex; align-items: center; gap: 10px; margin-bottom: 14px;
}
.section-header::before {
  content: ""; width: 4px; height: 18px; border-radius: 2px;
  background: var(--grad-accent); flex-shrink: 0;
}
.section-header-title { font-size: 15px; font-weight: 700; color: var(--text); }

/* Chip / pill */
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 10px; border-radius: 999px;
  font-size: 12px; font-weight: 600;
  background: var(--surface-2); color: var(--text-2);
  border: 1px solid var(--border);
}
.chip-accent { background: var(--accent-dim); color: var(--accent-2); border-color: transparent; }

/* ── Accessibility ──────────────────────────────────────────────── */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* ── Section reveal (Magic UI blur-fade port) ─────────────────────
   JS adds .reveal + .reveal-in together (staggerReveal), so nothing is
   ever left invisible if scripts fail; reduced-motion users skip it in JS. */
@media (prefers-reduced-motion: no-preference) {
  .reveal { opacity: 0; }
  .reveal.reveal-in {
    animation: blur-fade-in .45s cubic-bezier(.22,.61,.36,1) forwards;
  }
  .reveal.reveal-d1 { animation-delay: 60ms; }
  .reveal.reveal-d2 { animation-delay: 120ms; }
  .reveal.reveal-d3 { animation-delay: 180ms; }
  .reveal.reveal-d4 { animation-delay: 240ms; }
  .reveal.reveal-d5 { animation-delay: 300ms; }
  @keyframes blur-fade-in {
    from { opacity: 0; transform: translateY(8px); filter: blur(6px); }
    to   { opacity: 1; transform: none;            filter: none; }
  }
}

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