/* The previous panel's stylesheet (styles.css), every rule scoped under .legacy.
 * GENERATED by ops/raven-admin/build-from-mockup.py from styles.css — edit styles.css, not this.
 * The pages it styles are the ones not yet rebuilt in the mockup's design. */
:root{
  --border:rgba(255, 255, 255, .08);
  --border-str:rgba(255, 255, 255, .14);
  --faint:#6C7A97;
  --green:#34D399;
  --red:#F87171;
  --blue:#60A5FA;
  --s-1:4px;
  --s-2:8px;
  --s-3:12px;
  --s-4:16px;
  --s-5:20px;
  --s-6:24px;
  --s-7:32px;
  --s-8:44px;
  --r:12px;
  --r-pill:999px;
  --ease:cubic-bezier(.16, 1, .3, 1);
  --dur:200ms;
  --shadow-lg:0 2px 6px rgba(0,0,0,.45), 0 24px 60px -20px rgba(0,0,0,.75);
  --glow-gold:0 0 0 1px rgba(232,184,75,.25), 0 8px 24px -8px rgba(232,184,75,.35);
  --z-nav:40;
  --z-toast:1000;
  --pv-bg:#0D1420;
  --pv-card:#161F30;
  --pv-ink:#F1F4FA;
  --pv-muted:#9AA5BC;
  --pv-line:#2E3B54;
  --pv-accent:#E4C468;
  --pv-navy-tint:#243654;
  --pv-success:#41C980;
  --pv-danger:#F06A75;
  --pv-warning:#E8A94E;
  --pv-danger-tint:#3A1E22;
  --pv-warning-tint:#3A2E19;
}
/* Raven admin — Modern Dark, dense dashboard variant.
 *
 * Design system generated by the ui-ux-pro-max skill for
 * "internal operations dashboard / analytics / admin / dark / fintech",
 * with dials variance 6, motion 4, density 8. Two deliberate departures from
 * what the generator returned, both recorded here so nobody re-litigates them:
 *
 *   1. It returned a LIGHT palette (#F8FAFC background) while simultaneously
 *      classifying the style as "Dark Mode Primary". The dark reading wins —
 *      this panel is checked at night, sits beside a dark product, and the
 *      style's own rule is "avoid pure #000000 (OLED smear)". Base is a navy
 *      #0A0F1C that matches the product's own theme-color (#0F172A) rather than
 *      the generator's neutral black, because style consistency with the shipped
 *      product outranks a generic palette.
 *   2. It recommended Fira Sans / Fira Code. Neither has Persian coverage, and
 *      this interface is entirely Persian. Estedad (already self-hosted for the
 *      site, OFL) is used instead, with tabular figures standing in for the
 *      monospace half of the pairing.
 *
 * Every foreground/background pair below was measured, not eyeballed:
 * ink 15.1:1, muted 7.0:1, gold 9.6:1, green 9.2:1, red 6.4:1, blue 7.0:1 —
 * all comfortably past WCAG AA on the card surface.
 *
 * ── 2026-09-15 rework ──────────────────────────────────────────────────────
 * Three levels of hierarchy now exist where there was one: a tab holds
 * labelled GROUPS, a group holds CARDS, and a card that you act on
 * (`.card-action`) is visibly not a card you only read. The wall of stacked
 * `.note-block` paragraphs that used to sit above every form moved into a
 * closed `<details class="help">` in the card header — the guidance is still
 * one click away, but the form is what you see when the tab opens.
 */

/* Coupled to the Astro site, which ships and preloads this file. If the site
   ever stops serving it the panel degrades to Tahoma rather than breaking. */
@font-face {
  font-family: 'Estedad';
  src: url('/fonts/EstedadVar.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-display: swap;
}

.legacy {
  /* surfaces */
  --bg:         #0A0F1C;
  --surface:    #111827;
  --surface-2:  #161F33;
  --surface-3:  #1D2740;
  --border:     rgba(255, 255, 255, .08);
  --border-str: rgba(255, 255, 255, .14);

  /* ink */
  --ink:        #E9EDF5;
  --muted:      #96A3BE;
  --faint:      #6C7A97;

  /* semantic — never used as the only carrier of meaning; every state also
     ships an icon or a word, per the color-not-only rule. */
  --gold:       #E8B84B;
  --gold-ink:   #1A1204;
  --green:      #34D399;
  --red:        #F87171;
  --blue:       #60A5FA;
  --violet:     #A78BFA;

  /* density 8/10 → 8–32px scale */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px;
  --s-5: 20px; --s-6: 24px; --s-7: 32px; --s-8: 44px;

  --r-sm: 8px; --r: 12px; --r-lg: 16px; --r-pill: 999px;

  --ease: cubic-bezier(.16, 1, .3, 1);
  --dur: 200ms;

  --shadow: 0 1px 2px rgba(0,0,0,.4), 0 8px 24px -12px rgba(0,0,0,.6);
  --shadow-lg: 0 2px 6px rgba(0,0,0,.45), 0 24px 60px -20px rgba(0,0,0,.75);
  --glow-gold: 0 0 0 1px rgba(232,184,75,.25), 0 8px 24px -8px rgba(232,184,75,.35);

  --z-nav: 40; --z-toast: 1000;

  /* The product's own dark theme, copied from lib/core/theme/app_theme.dart so
     the message preview shows the colours the app really uses rather than an
     approximation of them. If those change, these change with them. */
  --pv-bg: #0D1420;  --pv-card: #161F30;  --pv-ink: #F1F4FA;
  --pv-muted: #9AA5BC;  --pv-line: #2E3B54;  --pv-accent: #E4C468;
  --pv-navy-tint: #243654;
  --pv-success: #41C980;  --pv-danger: #F06A75;  --pv-warning: #E8A94E;
  --pv-danger-tint: #3A1E22;  --pv-warning-tint: #3A2E19;
}

.legacy * { box-sizing: border-box; }

.legacy, .legacy { height: 100%; }

/* ── The one rule this panel was missing ────────────────────────────────────
   `.auth` and `.shell` both set `display`, and an author `display` beats the
   user-agent's `[hidden] { display: none }`. So the login card and the entire
   dashboard rendered STACKED: sign in, and the login screen stayed exactly
   where it was while the dashboard sat one full viewport below it — which is
   why "signing in" felt like it did nothing and the dashboard had to be
   scrolled to. It also meant the whole shell was drawn for anyone who opened
   /admin/ without a password. */
.legacy [hidden] { display: none !important; }

.legacy {
  margin: 0;
  background: var(--bg);
  /* Two very low-opacity radial washes instead of the style's animated blobs:
     the ambient depth without a permanent animation on a page that people leave
     open all day. */
  background-image:
    radial-gradient(900px 500px at 85% -8%, rgba(232,184,75,.055), transparent 60%),
    radial-gradient(800px 500px at 10% 0%, rgba(96,165,250,.05), transparent 60%);
  background-attachment: fixed;
  color: var(--ink);
  font-family: Estedad, Vazirmatn, Tahoma, system-ui, sans-serif;
  font-size: 14px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}

/* Data must never jitter as digits change. */
.legacy .num, .legacy table td.num, .legacy table th.num, .legacy .kpi-value, .legacy .mono { font-variant-numeric: tabular-nums; }

.legacy code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .92em; padding: 1px 5px; border-radius: 5px;
  background: var(--surface-3); color: var(--ink);
}

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

.legacy :focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

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

/* ============================ controls ============================ */

.legacy .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  min-height: 40px; padding: 0 var(--s-4);
  border: 1px solid transparent; border-radius: var(--r);
  font: inherit; font-weight: 600; cursor: pointer; white-space: nowrap;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
              color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.legacy .btn:active { transform: scale(.97); }
.legacy .btn-primary { background: var(--gold); color: var(--gold-ink); box-shadow: var(--glow-gold); }
.legacy .btn-primary:hover { background: #f0c65e; }
.legacy .btn-quiet { background: #1C2A48; color: var(--ink); border-color: rgb(255 255 255 / .22); box-shadow: inset 0 1px 0 rgb(255 255 255 / .06); }
.legacy .btn-quiet:hover { background: #243559; border-color: rgb(255 255 255 / .34); }
.legacy .btn-block { width: 100%; }

/* The one button that turns something off for every user at once.
   Red because the whole point is that it should not be clicked by accident
   while looking for something else on the same card. */
.legacy .btn-danger { background: rgba(248,113,113,.14); color: var(--red); border-color: rgba(248,113,113,.35); }
.legacy .btn-danger:hover { background: rgba(248,113,113,.22); border-color: rgba(248,113,113,.5); }

/* The mark on a field the form will not submit without. It means exactly
   «without this, nothing saves» — so it goes on every such field and on no
   other, or the unmarked ones start reading as optional. */
.legacy .req { color: var(--red); font-weight: 800; }
.legacy .btn-sm { min-height: 32px; padding: 0 var(--s-3); font-size: 13px; }
.legacy .btn-sm .ic { width: 16px; height: 16px; }
/* flex:none because these sit in flex rows (.topbar, .card-head) and were being
   shrunk below their declared width — that is how a 44px target measured 41.5. */
.legacy .btn-icon { width: 40px; padding: 0; background: var(--surface-2); border-color: var(--border); flex: none; }
.legacy .btn:disabled { opacity: .45; cursor: not-allowed; transform: none; }

.legacy .ic { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; flex: none; }
.legacy .ic-lg { width: 28px; height: 28px; }

/* inputs */
.legacy .field { display: grid; gap: 6px; min-width: 0; align-content: start; }
.legacy .field > label { font-size: 12.5px; color: var(--muted); font-weight: 500; }
.legacy .field .opt { color: var(--faint); font-weight: 400; }
.legacy .help-text { font-size: 12px; color: var(--faint); line-height: 1.6; }

.legacy input, .legacy select, .legacy textarea {
  width: 100%; min-height: 40px; padding: 9px var(--s-3);
  background: var(--surface-2); color: var(--ink);
  border: 1px solid var(--border); border-radius: var(--r);
  font: inherit;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease);
}
.legacy textarea { min-height: 84px; resize: vertical; line-height: 1.8; }
.legacy input:hover, .legacy select:hover, .legacy textarea:hover { border-color: var(--border-str); }
.legacy input:focus, .legacy select:focus, .legacy textarea:focus {
  outline: none; border-color: rgba(232,184,75,.55);
  box-shadow: 0 0 0 3px rgba(232,184,75,.14);
}
.legacy input::placeholder, .legacy textarea::placeholder { color: var(--faint); }
.legacy input[readonly] { background: rgba(255,255,255,.03); color: var(--muted); }
/* Native pickers render black-on-black in a dark theme without this. */
.legacy input[type="date"], .legacy input[type="datetime-local"] { color-scheme: dark; }
/* One chevron, drawn as an SVG. The two rotated linear-gradients this replaced
   met at a seam and read as a pair of specks rather than an arrow. */
.legacy select {
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2396A3BE' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>");
  background-position: left 12px top 50%;
  background-size: 15px 15px;
  background-repeat: no-repeat;
  padding-left: var(--s-7);
}

.legacy .err { color: var(--red); margin: 0; font-size: 13px; }
.legacy .err:empty { display: none; }

.legacy .uploader { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; }
/* A <label for> pointing at a visually-hidden file input: the native control's
   own chrome cannot be styled, and "انتخاب فایل" in English is what it would
   otherwise say on most machines. */
.legacy .uploader > label.btn { cursor: pointer; }

.legacy .ad-preview {
  margin-top: var(--s-2); width: 100%; max-width: 380px;
  aspect-ratio: 6 / 1; object-fit: cover;
  border-radius: var(--r-sm); border: 1px solid var(--border);
}

/* ============================ auth ============================ */

.legacy .auth { min-height: 100dvh; display: grid; place-items: center; padding: var(--s-5); }
.legacy .auth-card {
  width: min(400px, 100%); display: grid; gap: var(--s-4);
  padding: var(--s-7); border-radius: var(--r-lg);
  background: linear-gradient(180deg, rgba(255,255,255,.04), transparent 40%), var(--surface);
  border: 1px solid var(--border); box-shadow: var(--shadow-lg);
}
.legacy .auth-mark {
  width: 52px; height: 52px; display: grid; place-items: center; margin: 0 auto;
  border-radius: var(--r); background: rgba(232,184,75,.12); color: var(--gold);
  border: 1px solid rgba(232,184,75,.25);
}
.legacy .auth-head { text-align: center; display: grid; gap: var(--s-1); }
.legacy .auth-head h1 { margin: 0; font-size: 18px; }
.legacy .auth-head p { margin: 0; color: var(--muted); font-size: 12.5px; }
.legacy .pw-wrap { position: relative; }
.legacy .pw-wrap input { padding-left: 44px; }
.legacy .pw-toggle {
  position: absolute; inset-block: 0; left: 4px; width: 36px;
  display: grid; place-items: center;
  background: none; border: 0; color: var(--muted); cursor: pointer; border-radius: var(--r-sm);
}
.legacy .pw-toggle:hover { color: var(--ink); }

/* ============================ shell ============================ */

.legacy .shell { display: grid; grid-template-columns: 248px 1fr; min-height: 100dvh; }

.legacy .sidebar {
  display: flex; flex-direction: column; gap: var(--s-5);
  padding: var(--s-5) var(--s-4);
  background: var(--surface);
  border-inline-start: 1px solid var(--border);
  position: sticky; top: 0; height: 100dvh; overflow-y: auto;
}
.legacy .brand { display: flex; align-items: center; gap: var(--s-3); padding: 0 var(--s-2); }
.legacy .brand-mark {
  width: 36px; height: 36px; display: grid; place-items: center; flex: none;
  border-radius: 10px; background: var(--gold); color: var(--gold-ink);
  font-weight: 800; font-size: 17px;
}
.legacy .brand-text { display: grid; line-height: 1.35; }
.legacy .brand-text strong { font-size: 15px; }
.legacy .brand-text small { color: var(--muted); font-size: 11.5px; }

.legacy .nav { display: grid; gap: var(--s-1); }
/* The group label is the whole point of the rework: nine buttons in a row told
   you nothing about which three belonged together. */
.legacy .nav-label {
  margin: var(--s-4) var(--s-3) var(--s-1); font-size: 11px; font-weight: 700;
  letter-spacing: .04em; color: var(--faint); text-transform: none;
}
.legacy .nav-label:first-child { margin-top: 0; }
.legacy .nav-group { display: grid; gap: 2px; }
.legacy .nav-item {
  display: flex; align-items: center; gap: var(--s-3);
  min-height: 42px; padding: 0 var(--s-3);
  background: none; border: 0; border-radius: var(--r);
  color: var(--muted); font: inherit; font-weight: 500; text-align: start; cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.legacy .nav-item > span:first-of-type { flex: 1; min-width: 0; }
.legacy .nav-item:hover { background: var(--surface-2); color: var(--ink); }
/* Active state carries weight + a bar, not colour alone. */
.legacy .nav-item.active { background: var(--surface-3); color: var(--ink); font-weight: 700; position: relative; }
.legacy .nav-item.active::before {
  content: ''; position: absolute; inset-inline-start: 0; inset-block: 9px;
  width: 3px; border-radius: var(--r-pill); background: var(--gold);
}
/* A live count, not a decoration: it says how many rows are actually reaching
   users right now, so «آیا چیزی روشن مانده؟» is answered without opening the tab. */
.legacy .nav-count {
  flex: none; min-width: 22px; height: 20px; padding: 0 6px;
  display: grid; place-items: center; border-radius: var(--r-pill);
  background: rgba(52,211,153,.16); color: var(--green);
  font-size: 11.5px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.legacy .nav-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--red); }

.legacy .sidebar-foot { margin-top: auto; padding-top: var(--s-4); }

.legacy .content { min-width: 0; display: flex; flex-direction: column; }

.legacy .topbar {
  display: flex; align-items: center; gap: var(--s-4);
  padding: var(--s-4) var(--s-6);
  border-bottom: 1px solid var(--border);
  background: rgba(10,15,28,.72);
  backdrop-filter: blur(12px);
  position: sticky; top: 0; z-index: var(--z-nav);
}
.legacy .page-title { margin: 0; font-size: 17px; font-weight: 700; }
.legacy .topbar-actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--s-3); }

.legacy .seg { display: flex; padding: 3px; gap: 2px; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r); }
.legacy .seg-item {
  min-height: 32px; padding: 0 var(--s-3); border: 0; border-radius: var(--r-sm);
  background: none; color: var(--muted); font: inherit; font-size: 13px; cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.legacy .seg-item:hover { color: var(--ink); }
.legacy .seg-item.active { background: var(--surface-3); color: var(--ink); font-weight: 600; }
.legacy .seg-sm .seg-item { min-height: 28px; font-size: 12.5px; padding: 0 10px; }

.legacy main { padding: var(--s-6); flex: 1; width: 100%; max-width: 1480px; margin-inline: auto; }

.legacy .foot { padding: var(--s-4) var(--s-6) var(--s-7); color: var(--faint); font-size: 12px; }

/* The mobile drawer's scrim. A real element rather than a ::after with a
   negative z-index: the pseudo-element version could not be clicked reliably
   on iOS, so "tap outside to close" depended on a document listener alone. */
.legacy .scrim {
  position: fixed; inset: 0; background: rgba(0,0,0,.55);
  z-index: calc(var(--z-nav) + 5);
  animation: fade var(--dur) var(--ease);
}

/* ============================ panels & cards ============================ */

.legacy .panel { display: none; }
.legacy .panel.active { display: block; animation: fade var(--dur) var(--ease); }
@keyframes fade { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

/* Second level of hierarchy: a labelled group of cards. */
.legacy .group-label {
  display: flex; align-items: center; gap: var(--s-3);
  margin: var(--s-6) 0 var(--s-3);
  font-size: 12px; font-weight: 700; color: var(--faint); letter-spacing: .03em;
}
.legacy .group-label::after {
  content: ''; flex: 1; height: 1px;
  background: linear-gradient(to left, var(--border), transparent);
}
.legacy .panel > .group-label:first-child { margin-top: 0; }

.legacy .grid { display: grid; gap: var(--s-4); margin-bottom: var(--s-4); }
.legacy .grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

.legacy .card {
  background: linear-gradient(180deg, rgba(255,255,255,.03), transparent 45%), var(--surface);
  border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: var(--s-5); margin-bottom: var(--s-4);
  box-shadow: var(--shadow);
  min-width: 0;
}
.legacy .grid > .card { margin-bottom: 0; }
/* A card you DO something in, not one you read. The gold edge is the same
   signal the primary button carries, so the eye lands on the form first. */
.legacy .card-action {
  border-color: rgba(232,184,75,.22);
  background:
    linear-gradient(180deg, rgba(232,184,75,.06), transparent 120px),
    linear-gradient(180deg, rgba(255,255,255,.03), transparent 45%), var(--surface);
}

.legacy .card-head {
  display: flex; align-items: center; gap: var(--s-3);
  margin-bottom: var(--s-4); min-height: 32px; flex-wrap: wrap;
}
.legacy .card-head h2 { margin: 0; font-size: 15px; font-weight: 700; }
.legacy .card-head > .btn, .legacy .card-head > .seg, .legacy .card-head > .help, .legacy .card-head > .chip { margin-inline-start: auto; }
.legacy .card-head > .chip + .help, .legacy .card-head > .seg + .help, .legacy .card-head > .btn + .help { margin-inline-start: 0; }

.legacy .note { color: var(--muted); font-size: 12.5px; margin: var(--s-3) 0 0; }

/* Guidance, closed by default. Four stacked note blocks used to push the ad
   form below the fold on a laptop; the words have not changed, only when they
   are on screen. */
.legacy .help { font-size: 12.5px; }
.legacy .help > summary {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 32px; padding: 0 var(--s-3);
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface-2); color: var(--muted);
  cursor: pointer; list-style: none; user-select: none; font-weight: 600;
}
.legacy .help > summary::-webkit-details-marker { display: none; }
.legacy .help > summary::before {
  content: ''; width: 14px; height: 14px; flex: none;
  background: currentColor;
  -webkit-mask: center/contain no-repeat url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'><circle cx='12' cy='12' r='9'/><path d='M9.1 9a3 3 0 0 1 5.8 1c0 2-3 3-3 3'/><path d='M12 17h.01'/></svg>");
  mask: center/contain no-repeat url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'><circle cx='12' cy='12' r='9'/><path d='M9.1 9a3 3 0 0 1 5.8 1c0 2-3 3-3 3'/><path d='M12 17h.01'/></svg>");
}
.legacy .help > summary:hover { color: var(--ink); border-color: var(--border-str); }
.legacy .help[open] > summary { border-color: var(--border-str); color: var(--ink); }
.legacy .help-body {
  flex-basis: 100%; margin-top: var(--s-3);
  padding: var(--s-4); border-radius: var(--r);
  background: var(--surface-2); border: 1px solid var(--border);
  border-inline-start: 3px solid var(--blue);
  color: var(--muted); line-height: 1.9;
}
.legacy .help-body p { margin: 0 0 var(--s-3); }
.legacy .help-body p:last-child { margin-bottom: 0; }
.legacy .help-body strong { color: var(--ink); }
.legacy .help-body em { color: var(--gold); font-style: normal; font-weight: 600; }

.legacy .banner {
  display: flex; align-items: flex-start; gap: var(--s-3);
  margin: var(--s-4) var(--s-6) 0; padding: var(--s-3) var(--s-4);
  background: rgba(248,113,113,.1); border: 1px solid rgba(248,113,113,.3);
  border-radius: var(--r); color: var(--ink); font-size: 13px;
}
.legacy .banner .ic { color: var(--red); margin-top: 2px; }
/* Same shape, lower temperature: "this number does not mean what you think"
   is not the same alarm as "a data source is down". */
.legacy .banner-warn {
  margin: 0 0 var(--s-4);
  background: rgba(232,184,75,.1); border-color: rgba(232,184,75,.3);
}
.legacy .banner-warn .ic { color: var(--gold); }

/* ============================ kpis ============================ */

/* Four columns, not auto-fit. The overview carries eight KPIs and auto-fit put
   six on one row and two on the next, which reads as a row that ran out rather
   than a block of eight. Four gives 4+4 there and a clean row everywhere else. */
.legacy .kpis { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-3); margin-bottom: var(--s-4); }
@media (max-width: 1100px) { .legacy .kpis { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 820px)  { .legacy .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.legacy .kpi {
  padding: var(--s-4);
  background: linear-gradient(180deg, rgba(255,255,255,.035), transparent 50%), var(--surface);
  border: 1px solid var(--border); border-radius: var(--r-lg);
  position: relative; overflow: hidden;
}
.legacy .kpi::after {
  content: ''; position: absolute; inset-block-start: 0; inset-inline: var(--s-4);
  height: 2px; border-radius: var(--r-pill); background: var(--muted); opacity: .5;
}
.legacy .kpi.good::after { background: var(--green); opacity: 1; }
.legacy .kpi.bad::after { background: var(--red);   opacity: 1; }
.legacy .kpi.gold::after { background: var(--gold);  opacity: 1; }
.legacy .kpi-label { color: var(--muted); font-size: 12.5px; }
.legacy .kpi-value { font-size: 27px; font-weight: 800; letter-spacing: -.4px; line-height: 1.25; margin-top: 2px; }
.legacy .kpi.good .kpi-value { color: var(--green); }
.legacy .kpi.bad  .kpi-value { color: var(--red); }
.legacy .kpi.gold .kpi-value { color: var(--gold); }
.legacy .kpi-sub { font-size: 12px; color: var(--faint); }

/* ============================ charts ============================ */

.legacy .chart-wrap { position: relative; height: 260px; }
.legacy .chart-tall { height: 320px; }

/* ============================ tables ============================ */

/* Every table scrolls inside its own box; the page itself must never scroll
   sideways on a phone. */
.legacy .table-scroll { overflow-x: auto; margin: 0 calc(var(--s-5) * -1) calc(var(--s-5) * -1); padding: 0 var(--s-5) var(--s-5); }

.legacy table { width: 100%; border-collapse: collapse; font-size: 13px; }
.legacy th, .legacy td { text-align: start; padding: 9px var(--s-3); border-bottom: 1px solid var(--border); white-space: nowrap; }
.legacy th {
  color: var(--faint); font-weight: 600; font-size: 12px;
  position: sticky; top: 0; background: var(--surface); z-index: 1;
}
.legacy th[data-sort] { cursor: pointer; user-select: none; }
.legacy th[data-sort]:hover { color: var(--ink); }
.legacy th[data-sort]::after { content: '↕'; opacity: .35; margin-inline-start: 6px; font-size: 11px; }
.legacy th[aria-sort="ascending"]::after { content: '↑'; opacity: 1; color: var(--gold); }
.legacy th[aria-sort="descending"]::after { content: '↓'; opacity: 1; color: var(--gold); }
.legacy tbody tr { transition: background var(--dur) var(--ease); }
.legacy tbody tr:hover { background: var(--surface-2); }
.legacy tbody tr:last-child td { border-bottom: 0; }
.legacy td.wrap { white-space: normal; min-width: 220px; }
/* The id column is a machine string in a Persian table; keeping it LTR stops
   a leading digit from flipping the whole slug around. */
.legacy td.ltr { direction: ltr; text-align: right; font-size: 12.5px; color: var(--muted); }

.legacy .row-actions { display: flex; gap: var(--s-1); justify-content: flex-end; }

/* ===================== the data table component ===================== *
 *
 * One table for the whole panel — `datatable.js` renders into a plain `<div>`
 * and this styles it. The bare `table` rules above still apply inside it; what
 * is here is only the furniture the old tables did not have: the toolbar with
 * the search box, the footer with the counter and the pager, and the dialog
 * that replaced `confirm()`.
 */

.legacy .dt { display: flex; flex-direction: column; gap: var(--s-3); }

.legacy .dt-tools {
  display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap;
}
/* The search box takes the leftover room and pushes everything else to the
   start of the row, so a table with two extra controls and a table with none
   still look like the same component. */
.legacy .dt-search {
  position: relative; display: flex; align-items: center;
  margin-inline-start: auto; min-width: 180px; flex: 0 1 280px;
}
.legacy .dt-search .ic {
  position: absolute; inset-inline-start: 10px;
  width: 15px; height: 15px; color: var(--faint); pointer-events: none;
}
.legacy .dt-search input {
  width: 100%; min-height: 32px;
  padding: 0 var(--s-3) 0 0; padding-inline-start: 32px;
  background: var(--surface-2); color: var(--ink);
  border: 1px solid var(--border); border-radius: var(--r-sm);
  font: inherit; font-size: 13px;
}
.legacy .dt-search input:focus-visible {
  outline: 2px solid var(--gold); outline-offset: 1px; border-color: transparent;
}
/* Safari/Chrome's own × sits on the wrong side in an RTL row and is tiny;
   clearing is what the empty state's own hint tells people to do. */
/* Chrome's own × is a few pixels wide and lands on the wrong side in an RTL
   row, so the component draws its own (`.dt-search-clear`) instead. */
.legacy .dt-search input::-webkit-search-cancel-button { -webkit-appearance: none; }
.legacy .dt-search input { padding-inline-end: 30px; }
.legacy .dt-search-clear {
  position: absolute; inset-inline-end: 4px;
  width: 24px; height: 24px; display: grid; place-items: center;
  background: none; border: 0; border-radius: var(--r-sm);
  color: var(--faint); font-size: 18px; line-height: 1; cursor: pointer;
}
.legacy .dt-search-clear:hover { color: var(--ink); background: var(--surface-3); }
.legacy .dt-search-clear:focus-visible { outline: 2px solid var(--gold); outline-offset: 1px; }

.legacy .dt-scroll {
  overflow-x: auto;
  margin: 0 calc(var(--s-5) * -1); padding: 0 var(--s-5);
}

.legacy .dt th[data-dtsort] { cursor: pointer; user-select: none; }
.legacy .dt th[data-dtsort]:hover { color: var(--ink); }
.legacy .dt th[data-dtsort]::after { content: '↕'; opacity: .35; margin-inline-start: 6px; font-size: 11px; }
.legacy .dt th[aria-sort="ascending"]::after { content: '↑'; opacity: 1; color: var(--gold); }
.legacy .dt th[aria-sort="descending"]::after { content: '↓'; opacity: 1; color: var(--gold); }
.legacy .dt th[data-dtsort]:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }

/* The action column stays pinned to the end of the row and never stretches,
   so the buttons line up down the table however wide the content is. */
.legacy .dt td.dt-actions, .legacy .dt th.dt-actions { width: 1%; }
.legacy .dt-dense td, .legacy .dt-dense th { padding: 6px var(--s-3); }

.legacy .dt-foot {
  display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap;
  font-size: 12px; color: var(--muted);
}
.legacy .dt-count { font-variant-numeric: tabular-nums; }
.legacy .dt-size { display: flex; align-items: center; gap: var(--s-2); }
.legacy .dt-size select {
  min-height: 28px; padding: 0 var(--s-2);
  background: var(--surface-2); color: var(--ink);
  border: 1px solid var(--border); border-radius: var(--r-sm);
  font: inherit; font-size: 12px;
}
.legacy .dt-pager { display: flex; align-items: center; gap: var(--s-1); margin-inline-start: auto; }
.legacy .dt-page { padding: 0 var(--s-2); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---- the confirmation dialog ---- */

.dt-dialog {
  border: 1px solid var(--border-str); border-radius: var(--r-lg);
  background: var(--surface); color: var(--ink);
  padding: var(--s-5); max-width: 420px; width: calc(100vw - 2 * var(--s-4));
  box-shadow: var(--shadow-lg); font: inherit;
}
.dt-dialog::backdrop { background: rgba(4, 7, 14, .68); backdrop-filter: blur(2px); }
.dt-dialog h3 { margin: 0 0 var(--s-2); font-size: 16px; font-weight: 700; }
.dt-dialog-body { font-size: 13px; color: var(--muted); line-height: 1.85; }
.dt-dialog-body strong { color: var(--ink); }
.dt-dialog-body code, .dt-confirm-type code {
  direction: ltr; display: inline-block;
  padding: 0 5px; border-radius: 4px;
  background: var(--surface-3); color: var(--gold); font-size: 12.5px;
}
.dt-confirm-type {
  display: block; margin-top: var(--s-4);
  font-size: 12.5px; color: var(--muted);
}
.dt-confirm-type input {
  display: block; width: 100%; margin-top: var(--s-2); min-height: 36px;
  padding: 0 var(--s-3); direction: ltr; text-align: left;
  background: var(--surface-2); color: var(--ink);
  border: 1px solid var(--border); border-radius: var(--r-sm);
  font: inherit; font-size: 13px; letter-spacing: 1px;
}
.dt-dialog-foot {
  display: flex; gap: var(--s-2); justify-content: flex-start;
  margin-top: var(--s-5);
}
.dt-dialog.danger h3 { color: var(--red); }

@media (max-width: 720px) {
  .legacy .dt-search { flex: 1 1 100%; margin-inline-start: 0; }
  .legacy .dt-pager { margin-inline-start: 0; }
}

.legacy .chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px; border-radius: var(--r-pill);
  font-size: 11.5px; font-weight: 600; white-space: nowrap;
}
.legacy .chip .ic { width: 13px; height: 13px; stroke-width: 2.2; }
.legacy .chip-ok { background: rgba(52,211,153,.14); color: var(--green); }
.legacy .chip-warn { background: rgba(232,184,75,.14); color: var(--gold); }
.legacy .chip-bad { background: rgba(248,113,113,.14); color: var(--red); }
.legacy .chip-mute { background: rgba(150,163,190,.14); color: var(--muted); }
.legacy .chip-info { background: rgba(96,165,250,.14); color: var(--blue); }

/* Audience/targeting summaries: several small facts on one row without the
   weight of a chip each. */
.legacy .tags { display: flex; gap: 5px; flex-wrap: wrap; }
.legacy .tag {
  padding: 1px 7px; border-radius: var(--r-sm); font-size: 11px;
  background: var(--surface-3); color: var(--muted); border: 1px solid var(--border);
}

.legacy .icon-btn {
  display: grid; place-items: center; width: 32px; height: 32px;
  background: none; border: 1px solid transparent; border-radius: var(--r-sm);
  color: var(--muted); cursor: pointer; flex: none;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.legacy .icon-btn:hover { background: var(--surface-3); color: var(--ink); border-color: var(--border-str); }
.legacy .icon-btn-danger:hover { background: rgba(248,113,113,.12); color: var(--red); border-color: rgba(248,113,113,.3); }
.legacy .icon-btn .ic { width: 17px; height: 17px; }

/* ============================ forms ============================ */

.legacy .form { display: grid; gap: var(--s-4); }
/* A 12-column grid instead of auto-fit: fields land where they were put, and a
   label no longer moves to a different row when the window narrows by 20px. */
.legacy .row { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--s-3); align-items: start; }
.legacy .col-3 { grid-column: span 3; }
.legacy .col-4 { grid-column: span 4; }
.legacy .col-6 { grid-column: span 6; }
.legacy .col-8 { grid-column: span 8; }
.legacy .col-12 { grid-column: span 12; }

.legacy .fset {
  border: 1px solid var(--border); border-radius: var(--r);
  padding: var(--s-4); margin: 0; min-width: 0;
  background: rgba(255,255,255,.012);
}
.legacy .fset > legend {
  padding: 2px var(--s-3); margin-inline-start: var(--s-2);
  font-size: 11.5px; font-weight: 700; color: var(--gold);
  background: var(--surface-3); border-radius: var(--r-pill);
}

.legacy .form-foot {
  display: flex; align-items: center; gap: var(--s-4); flex-wrap: wrap;
  padding-top: var(--s-2);
}
.legacy .form-foot .err { flex: 1; min-width: 160px; }
.legacy .form-foot .btn { margin-inline-start: auto; min-width: 140px; }

/* ============================ message composer ============================ */

.legacy .composer { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: var(--s-4); align-items: start; }
.legacy .composer > .card { margin-bottom: 0; }
.legacy .preview-card { position: sticky; top: 84px; }

/* The preview stage is a slice of the app, not a mood board: same background,
   same card colour, same gold. Drawn at the app's own dark theme values. */
.legacy .preview-stage {
  position: relative; border-radius: var(--r);
  background: var(--pv-bg); border: 1px solid var(--pv-line);
  padding: var(--s-4); min-height: 300px;
  display: flex; flex-direction: column; justify-content: center; gap: var(--s-3);
  color: var(--pv-ink); overflow: hidden;
}
.legacy .preview-stage.web { padding: var(--s-5); }
.legacy .pv-chrome {
  position: absolute; inset-block-start: 0; inset-inline: 0; height: 26px;
  background: var(--pv-card); border-bottom: 1px solid var(--pv-line);
  display: flex; align-items: center; justify-content: center;
  font-size: 10.5px; color: var(--pv-muted); letter-spacing: .04em;
}
.legacy .preview-stage.has-chrome { padding-top: var(--s-7); }

.legacy .pv-modal {
  background: var(--pv-card); border-radius: 18px; overflow: hidden;
  border: 1px solid var(--pv-line); box-shadow: var(--shadow-lg);
}
.legacy .pv-img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; display: block; background: var(--pv-navy-tint); }
.legacy .pv-body { padding: 18px 20px 20px; display: grid; gap: 10px; }
.legacy .pv-title { font-size: 16px; font-weight: 700; line-height: 1.6; margin: 0; }
.legacy .pv-text { font-size: 13px; color: var(--pv-muted); line-height: 1.9; margin: 0; white-space: pre-wrap; }
.legacy .pv-promo {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border-radius: 12px;
  background: rgba(228,196,104,.10); border: 1px dashed rgba(228,196,104,.45);
}
.legacy .pv-promo-code { flex: 1; font-size: 15px; font-weight: 800; letter-spacing: .1em; color: var(--pv-accent); direction: ltr; text-align: right; }
.legacy .pv-promo-copy { font-size: 11.5px; color: var(--pv-muted); display: flex; align-items: center; gap: 4px; }
.legacy .pv-meta { font-size: 11.5px; color: var(--pv-muted); }
.legacy .pv-cta {
  display: block; width: 100%; text-align: center;
  padding: 11px 14px; border-radius: 12px; border: 0;
  background: var(--pv-accent); color: #21180A; font: inherit; font-weight: 700; font-size: 13.5px;
}
.legacy .pv-dismiss { display: block; width: 100%; text-align: center; padding: 8px; font-size: 13px; color: var(--pv-muted); }
.legacy .pv-x {
  position: absolute; inset-block-start: 8px; inset-inline-end: 8px;
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center; font-size: 15px; line-height: 1;
  background: rgba(22,31,48,.85); color: var(--pv-muted);
}
.legacy .pv-modal-wrap { position: relative; }

.legacy .pv-notice {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 14px; border-radius: 14px;
  font-size: 13px; line-height: 1.8;
}
.legacy .pv-notice.info { background: rgba(53,80,127,.35); border: 1px solid var(--pv-navy-tint); color: var(--pv-ink); }
.legacy .pv-notice.warning { background: var(--pv-warning-tint); border: 1px solid rgba(232,169,78,.45); color: var(--pv-warning); }
.legacy .pv-notice.critical { background: var(--pv-danger-tint); border: 1px solid rgba(240,106,117,.45); color: var(--pv-danger); }
.legacy .pv-notice-mark { font-size: 15px; line-height: 1.3; }

.legacy .pv-inbox { background: var(--pv-card); border: 1px solid var(--pv-line); border-radius: 14px; overflow: hidden; }
.legacy .pv-inbox-head { padding: 10px 14px; border-bottom: 1px solid var(--pv-line); font-size: 12px; color: var(--pv-muted); }
.legacy .pv-inbox-row { display: flex; gap: 10px; padding: 13px 14px; align-items: flex-start; }
.legacy .pv-unread { width: 8px; height: 8px; border-radius: 50%; background: var(--pv-accent); margin-top: 7px; flex: none; }
.legacy .pv-inbox-text { min-width: 0; display: grid; gap: 3px; }
.legacy .pv-inbox-title { font-size: 13.5px; font-weight: 700; }
.legacy .pv-inbox-sub { font-size: 12px; color: var(--pv-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.legacy .pv-blocking-note {
  margin: 0; text-align: center; font-size: 11.5px; color: var(--pv-danger);
}
.legacy .pv-placeholder { text-align: center; color: var(--pv-muted); font-size: 12.5px; padding: var(--s-6) var(--s-4); }

/* ============================ empty & loading ============================ */

.legacy .empty {
  display: grid; place-items: center; gap: var(--s-2);
  padding: var(--s-7) var(--s-4); text-align: center; color: var(--muted);
}
.legacy .empty .ic { width: 30px; height: 30px; opacity: .5; }
.legacy .empty-title { font-weight: 600; color: var(--ink); font-size: 13.5px; }
.legacy .empty-hint { font-size: 12.5px; max-width: 44ch; }

.legacy .skeleton {
  border-radius: var(--r-sm);
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 37%, var(--surface-2) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.3s ease-in-out infinite;
}
@keyframes shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }
.legacy .sk-kpi { height: 92px; border-radius: var(--r-lg); }
.legacy .sk-row { height: 14px; margin-bottom: 10px; }

/* ============================ toasts ============================ */

.toasts {
  position: fixed; inset-block-end: var(--s-5); inset-inline-start: var(--s-5);
  display: grid; gap: var(--s-2); z-index: var(--z-toast);
}
.toast {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-3) var(--s-4); min-width: 240px;
  background: var(--surface-3); border: 1px solid var(--border-str);
  border-radius: var(--r); box-shadow: var(--shadow); font-size: 13px;
  animation: toastIn var(--dur) var(--ease);
}
.toast.ok  .ic { color: var(--green); }
.toast.bad .ic { color: var(--red); }
@keyframes toastIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* ============================ responsive ============================ */

.legacy .only-mobile { display: none; }

@media (max-width: 1280px) {
  .legacy .composer { grid-template-columns: 1fr; }
  .legacy .preview-card { position: static; max-width: 420px; }
}

@media (max-width: 1023px) {
  .legacy .shell { grid-template-columns: 1fr; }
  /* The drawer must live on the same side the desktop sidebar occupies —
     inset-inline-start is the RIGHT edge under dir="rtl" — so the navigation
     never changes sides between breakpoints. transform is NOT direction-aware,
     so translateX(100%) is what pushes it off the right edge here. */
  .legacy .sidebar {
    position: fixed; inset-block: 0; inset-inline-start: 0; width: 264px;
    z-index: calc(var(--z-nav) + 10);
    transform: translateX(100%);
    transition: transform var(--dur) var(--ease);
    box-shadow: var(--shadow-lg);
    border-inline-start: 0;
    border-inline-end: 1px solid var(--border);
  }
  .legacy .sidebar.open { transform: none; }
  .legacy .only-mobile { display: inline-flex; }
  .legacy .grid-2 { grid-template-columns: 1fr; }
  .legacy main { padding: var(--s-4); }
  .legacy .topbar { padding: var(--s-3) var(--s-4); }
  .legacy .banner { margin-inline: var(--s-4); }
  .legacy .col-3, .legacy .col-4 { grid-column: span 6; }
  .legacy .col-8 { grid-column: span 12; }

  /* Touch minimum is 44x44. 40px is fine for a mouse but fails on a phone,
     and every control below is reachable at this breakpoint. */
  .legacy .btn { min-height: 44px; }
  .legacy .btn-icon { width: 44px; height: 44px; }
  .legacy .btn-sm { min-height: 38px; }
  .legacy .seg-item { min-height: 44px; min-width: 44px; }
  .legacy .seg-sm .seg-item { min-height: 38px; }
  .legacy .pw-toggle { width: 44px; }
  .legacy input, .legacy select, .legacy textarea { min-height: 44px; }
  .legacy .icon-btn { width: 44px; height: 44px; }
  .legacy .help > summary { min-height: 38px; }
}

@media (max-width: 560px) {
  .legacy .only-desktop { display: none; }
  .legacy .seg-item { padding: 0 10px; font-size: 12px; }
  .legacy .kpi-value { font-size: 23px; }
  .legacy .col-3, .legacy .col-4, .legacy .col-6, .legacy .col-8 { grid-column: span 12; }
  .legacy .card { padding: var(--s-4); }
  .legacy .table-scroll { margin: 0 calc(var(--s-4) * -1) calc(var(--s-4) * -1); padding: 0 var(--s-4) var(--s-4); }
  .legacy .fset { padding: var(--s-3); }
  .legacy .form-foot .btn { width: 100%; }
}

.legacy #healthBox table td:first-child, .legacy #bazaarBox table td:first-child { color: var(--muted); }
.legacy #healthBox td, .legacy #bazaarBox td { white-space: normal; }
