/* =========================================================================
   Socials (5000 app) — design system overlay
   Brings the clean, modern "Socials Suite" (8000) look to the uploader tool
   WITHOUT changing any element IDs or feature logic.
   ========================================================================= */

:root {
  --brand-50:  #eef2ff;
  --brand-100: #e0e7ff;
  --brand-200: #c7d2fe;
  --brand-300: #a5b4fc;
  --brand-400: #818cf8;
  --brand-500: #6366f1;
  --brand-600: #4f46e5;
  --brand-700: #4338ca;

  --accent-400: #22d3ee;
  --accent-500: #06b6d4;

  --surface: #f8fafc;
  --surface-2: #f1f5f9;
  --border: #e2e8f0;
  --border-2: #cbd5e1;
  --text: #0f172a;
  --text-2: #475569;
  --text-3: #94a3b8;

  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 18px;
  --r-pill: 999px;

  --shadow-sm: 0 1px 2px rgba(15,23,42,.06);
  --shadow-md: 0 4px 12px rgba(15,23,42,.08);
  --shadow-lg: 0 12px 32px rgba(15,23,42,.12);
  --shadow-brand: 0 8px 24px rgba(99,102,241,.28);

  --danger: #e11d48;
  --danger-50: #fff1f2;
  --success: #059669;
  --success-50: #ecfdf5;

  --sidebar-w: 232px;
  --sidebar-w-min: 68px;
}

/* ---- brand logo artwork ----------------------------------------------------
   The real lockup (images/logo.png) replaces the old emoji mark + wordmark.
   Dark ink for light surfaces, images/logo-white.png (same artwork with the
   ink turned white) for the dark ones: the sidebar and the page footers.
   The height is set per surface with an inline style; width follows the
   786:227 aspect (and max-width keeps it inside a narrow container).          */
.brand-logo {
  display: block;
  height: 40px;
  width: auto;
  max-width: 100%;
  object-fit: contain;
}

html, body { height: 100%; }
body.dash-body {
  font-family: "Inter", "Segoe UI", system-ui, -apple-system, sans-serif;
  background: var(--surface);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
}

/* ---- dashboard shell ----------------------------------------------------- */
.app-shell { display: flex; min-height: 100vh; }
/* Hide the whole app shell until the auth check resolves, so the
   dashboard/composer never flashes on screen before the login popup.
   Toggled by setAppShellVisible() in app.js (class .app-shell-hidden). */
.app-shell-hidden { display: none; }

.sidebar {
  width: var(--sidebar-w);
  background: #0f172a;
  color: #cbd5e1;
  position: fixed; top: 0; left: 0; bottom: 0;
  display: flex; flex-direction: column;
  z-index: 45;
  transition: transform .25s ease;
}
.sidebar .sb-brand {
  padding: 20px 18px 16px; display: flex; align-items: center; gap: 10px;
  font-weight: 800; font-size: 17px; color: #fff; border-bottom: 1px solid #1e293b;
  /* It is a link to the public landing page now (see templates/index.html), so it
     must not pick up the default link colour/underline, and it needs a hover hint
     that it is clickable — the sidebar is otherwise all buttons. */
  text-decoration: none; transition: background .15s ease;
}
.sidebar .sb-brand:hover { background: rgba(255, 255, 255, .06); }
.sidebar .sb-brand .brand-mark {
  width: 34px; height: 34px; border-radius: 10px;
  background: linear-gradient(135deg, var(--brand-500), var(--accent-500));
  display: flex; align-items: center; justify-content: center; font-size: 18px; color: #fff;
}
.sidebar .sb-brand .brand-logo { height: 34px; }
.sidebar .sb-nav { padding: 14px 12px; flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 3px;
  /* no visible scrollbar on the left main menu — keep scrolling, hide the bar */
  scrollbar-width: none; -ms-overflow-style: none; }
.sidebar .sb-nav::-webkit-scrollbar { width: 0; height: 0; display: none; }
.sidebar .sb-label { font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em; color: #64748b; padding: 10px 12px 5px; display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.sidebar .sb-label img { flex: none; }
.sb-item {
  display: flex; align-items: center; gap: 11px;
  padding: 10px 12px; border-radius: 10px; color: #cbd5e1;
  font-weight: 500; font-size: 14px; cursor: pointer; border: none; background: transparent;
  width: 100%; text-align: left; transition: background .15s, color .15s;
}
.sb-item:hover { background: #1e293b; color: #fff; }
.sb-item.active { background: var(--brand-600); color: #fff; }
.sb-item.disabled { opacity: .45; cursor: not-allowed; }
.sb-item.disabled:hover { background: transparent; color: #cbd5e1; }
/* Photographers gets a warm marker of its own.
   It is the one entry in the sidebar that is a client-facing WORKFLOW rather
   than a composer or a list — you upload a session and send somebody a link —
   and it sat at the end of the Studio group looking like just another tool. The
   amber tint separates it from its neighbours without competing with the indigo
   that means "this is the page you are on": the ACTIVE state below still wins, so
   the highlight never makes it ambiguous which section is open.
   Amber rather than the literal yellow that was asked for: yellow (#facc15) on
   the navy sidebar glares, and amber reads as "photography" while matching the
   📸 it sits next to. */
.sb-item.pg-nav {
  background: rgba(245, 158, 11, .14);
  color: #fbbf24;
  font-weight: 600;
  /* An inset accent bar instead of a border: a border would change the item's
     box and shift the whole column by a pixel when it is added. */
  box-shadow: inset 3px 0 0 0 #f59e0b;
}
html[dir="rtl"] .sb-item.pg-nav { box-shadow: inset -3px 0 0 0 #f59e0b; }
.sb-item.pg-nav:hover { background: rgba(245, 158, 11, .24); color: #fde68a; }
/* Active: the same indigo every other section uses, so "where am I" stays
   consistent — but keep the amber bar so the section is still recognisable
   from the marker alone. */
.sb-item.pg-nav.active {
  background: var(--brand-600);
  color: #fff;
  box-shadow: inset 3px 0 0 0 #f59e0b;
}
html[dir="rtl"] .sb-item.pg-nav.active { box-shadow: inset -3px 0 0 0 #f59e0b; }
/* Collapsed to icons: the label is hidden, so the tint is the ONLY thing left
   saying which item this is — keep it. */
.app-shell.sb-min .sidebar .sb-item.pg-nav { background: rgba(245, 158, 11, .18); }
/* Anchor variant of .sb-item used for menu links that leave the SPA for a
   standalone page (e.g. the Activity & Logs dashboard at /activity). */
a.sb-item.sb-link { text-decoration: none; -webkit-tap-highlight-color: transparent; }
a.sb-item.sb-link:visited { color: inherit; }
a.sb-item.sb-link:hover { background: #1e293b; color: #fff; }
.sb-item .sb-ico { width: 22px; text-align: center; flex: none; }
/* Page links open in a new tab, so they must be visually distinguishable from
   the in-app nav buttons. Two cues, no extra markup:
   (a) a small ↗ marker, added by CSS only (an <a> has no child element to put
       it in, unlike the <button> items which must NOT get one), and
   (b) the hover title is set by the markup. */
a.sb-item.sb-link::after {
  content: "↗"; font-size: 11px; opacity: .55; margin-left: auto; padding-left: 6px;
}
.app-shell.sb-min .sidebar a.sb-item.sb-link::after { display: none; }
/* SVG/PNG icon replacements inside emoji slots: size to fit, no tint (assets
   ship their own colour), centre vertically next to the label. */
.sb-item .sb-ico,
.mb-tab .mb-ico,
.cs-act .cs-ico {
  display: inline-flex; align-items: center; justify-content: center;
}
.sb-item .sb-ico img,
.mb-tab .mb-ico img,
.cs-act .cs-ico img {
  width: 22px; height: 22px; object-fit: contain; display: block; flex: none;
}

.sidebar .sb-foot { padding: 12px; border-top: 1px solid #1e293b; }
/* Profile button shown above Logout in the sidebar footer. */
.sb-profile {
  display: flex; align-items: center; justify-content: flex-start; gap: 9px;
  width: 100%; padding: 9px 12px; margin-bottom: 8px; border-radius: 10px;
  background: #1e293b; color: #e2e8f0; border: none; cursor: pointer;
  font-size: 13px; font-weight: 600; text-align: left; transition: background .15s;
}
.sb-profile:hover { background: #334155; }
.sb-profile-email { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sb-profile-icon { color: #94a3b8; flex: none; display: inline-flex; align-items: center; }
/* Sidebar Logout: icon + label laid out nicely (only when shown, so the
   Tailwind .hidden state still fully hides it before login). */
#btnLogout:not(.hidden) { display: inline-flex; align-items: center; justify-content: flex-start; gap: 8px; }
#btnLogout.sb-foot-logout-danger,
.sb-foot #btnLogout { background: transparent; border-color: #334155; color: #cbd5e1; }
.sb-foot #btnLogout:hover { background: #dc2626; border-color: #dc2626; color: #fff; }
.sb-logout-lbl { white-space: nowrap; }
.sb-badge { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 600; padding: 4px 10px; border-radius: var(--r-pill); background: #1e293b; color: #94a3b8; }
.sb-badge.on { background: #064e3b; color: #6ee7b7; }

.app-main { flex: 1; margin-left: var(--sidebar-w); display: flex; flex-direction: column; min-width: 0; }

/* ---- RTL: the menu column moves to the RIGHT in Farsi ----------------------
   The sidebar is `position: fixed` with a hard-coded `left: 0`, and .app-main
   reserves its space with `margin-left` — so in Farsi the menu stayed nailed to
   the LEFT of an RTL page and the content margin reserved empty space on the
   wrong side. Flipping both is what puts the menu where a Farsi reader expects
   it. `margin-right` on .app-main (not `margin-left: 0` alone) keeps the content
   clear of the column. */
[dir="rtl"] .sidebar { left: auto; right: 0; }
[dir="rtl"] .app-main { margin-left: 0; margin-right: var(--sidebar-w); }

.topbar {
  height: 62px; background: #fff; border-bottom: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between; padding: 0 26px;
  position: sticky; top: 0; z-index: 40;
}
.topbar h1 { font-size: 18px; margin: 0; }
.topbar .tb-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* The pinned bottom nav (+Create) and the sidebar now provide Compose/Accounts,
   so drop the redundant top-right "＋ Compose" and "🔑 Accounts" header buttons. */
#btnQuickPost, #btnAccounts { display: none !important; }

/* ---- Collapsible sidebar (desktop icon rail) -------------------------------
   A topbar hamburger (visible on both desktop & mobile) collapses the desktop
   sidebar to a slim icon rail; mobile keeps its slide-in drawer. */
@media (min-width: 861px) {
  #hamburger { display: inline-flex !important; }
  /* rail: narrow sidebar, icons centered, text labels hidden */
  .app-shell.sb-min .sidebar { width: var(--sidebar-w-min); transition: width .2s ease; }
  .app-shell.sb-min .app-main { margin-left: var(--sidebar-w-min); transition: margin-left .2s ease; }
  /* The collapsed icon rail follows the sidebar: in Farsi the space it frees is on
     the RIGHT, so the RTL variant must reserve the narrow width there. */
  [dir="rtl"] .app-shell.sb-min .app-main { margin-left: 0; margin-right: var(--sidebar-w-min); }
  .app-shell.sb-min .sidebar .sb-brand { justify-content: center; padding: 18px 6px 14px; }
  .app-shell.sb-min .sidebar .sb-brand .brand-word { display: none; }
  /* Rail mode: shrink the lockup to the width of the rail instead of hiding it
     (it is the only branding left once the menu labels are gone). */
  .app-shell.sb-min .sidebar .sb-brand .brand-logo { height: auto; width: 100%; }
  .app-shell.sb-min .sidebar .sb-label { display: none; }
  .app-shell.sb-min .sidebar .sb-item { justify-content: center; padding: 11px 6px; }
  .app-shell.sb-min .sidebar .sb-item > span:not(.sb-ico) { display: none; }
  /* Minimised rail: the user footer shows the user ICON only… */
  .app-shell.sb-min .sidebar .sb-profile-email { display: none; }
  .app-shell.sb-min .sidebar .sb-profile { justify-content: center; padding: 9px 6px; }
  .app-shell.sb-min .sidebar .sb-profile-icon { display: inline-flex; flex: none; }
  .app-shell.sb-min .sidebar .sb-profile-icon img { width: 20px; height: 20px; }
  /* …and Logout becomes an icon-only button using logout.svg. */
  .app-shell.sb-min .sidebar .sb-logout-lbl { display: none; }
  .app-shell.sb-min #btnLogout { justify-content: center; padding: 9px 6px; }
  .app-shell.sb-min .sb-foot { padding: 10px 8px; }
}

/* =========================================================================
   Admin Hub — one sidebar entry that opens a colour-coded card grid.
   Each card is a shortcut to an existing admin view (accent colour comes from
   the inline --hub-c custom property set per category in shell.js).
   ========================================================================= */
.hub-head { margin-bottom: 4px; }
.hub-toolbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 14px 0 16px;
}
.hub-search { position: relative; flex: 1 1 240px; min-width: 200px; max-width: 420px; }
.hub-search-ico {
  position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  font-size: 13px; color: var(--text-3); pointer-events: none;
}
.hub-search input {
  width: 100%; box-sizing: border-box; padding: 9px 12px 9px 32px;
  border: 1px solid var(--border); border-radius: 10px;
  font-size: 13px; font-family: inherit; background: var(--surface, #fff); color: var(--text);
}
.hub-search input:focus { outline: none; border-color: var(--brand-500); box-shadow: 0 0 0 3px var(--brand-50); }
.hub-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.hub-chip {
  border: 1px solid var(--border); background: #fff; color: var(--text-2);
  padding: 7px 13px; border-radius: var(--r-pill); font-size: 12.5px; font-weight: 600;
  font-family: inherit; cursor: pointer; transition: all .15s; white-space: nowrap;
}
.hub-chip:hover { border-color: var(--brand-400); color: var(--brand-600); }
.hub-chip.active { background: var(--brand-600); border-color: var(--brand-600); color: #fff; }

.hub-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 14px;
}
.hub-card {
  position: relative; display: flex; flex-direction: column; gap: 10px;
  padding: 16px 16px 14px 18px; background: #fff; cursor: pointer;
  border: 1px solid var(--border); border-left: 4px solid var(--hub-c, var(--brand-500));
  border-radius: 14px; box-shadow: var(--shadow-sm);
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
.hub-card:hover, .hub-card:focus-visible {
  transform: translateY(-2px); outline: none;
  border-color: var(--hub-c, var(--brand-500));
  box-shadow: 0 12px 28px rgba(15,23,42,.12);
}
.hub-card-top { display: flex; align-items: center; gap: 12px; }
.hub-card-ico {
  flex: none; width: 46px; height: 46px; border-radius: 13px;
  display: flex; align-items: center; justify-content: center; font-size: 23px;
  background: color-mix(in srgb, var(--hub-c, #6366f1) 12%, #fff);
}
.hub-card-txt { min-width: 0; }
.hub-card-title { font-weight: 800; font-size: 15px; color: var(--text, #0f172a); line-height: 1.25; }
.hub-card-sub { font-size: 12.5px; color: var(--text-3); margin-top: 3px; line-height: 1.35; }
.hub-card-stat {
  font-size: 13px; font-weight: 700; color: var(--hub-c, var(--brand-600));
  background: var(--surface-2, #f1f5f9); border-radius: 8px;
  padding: 7px 10px; min-height: 32px; display: flex; align-items: center;
}
.hub-card-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: auto; }
.hub-cat-tag {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  padding: 3px 8px; border-radius: var(--r-pill); white-space: nowrap;
}
.hub-open {
  font-size: 12.5px; font-weight: 700; color: var(--hub-c, var(--brand-600));
  white-space: nowrap; transition: transform .15s ease; display: inline-block;
}
.hub-card:hover .hub-open { transform: translateX(3px); }
.hub-empty {
  text-align: center; color: var(--text-3); font-size: 13.5px; padding: 32px 10px;
}

@media (max-width: 860px) {
  /* Single stacked column on phones/tablets. */
  .hub-grid { grid-template-columns: 1fr; }
  .hub-search { max-width: none; flex-basis: 100%; }
}
/* RTL: the accent border and the "Open →" nudge flip sides. */
[dir="rtl"] .hub-card { border-left: 1px solid var(--border); border-right: 4px solid var(--hub-c, var(--brand-500)); }

/* ---- Admin → Platforms: one card per platform ---------------------------- */
/* A platform used to be a single cramped flex row (toggles + a big purple
   "Connection guide" button + three unlabelled number boxes). Each platform is
   now its own card with a header, a 3-column grid of controls and a full-width
   "Characters per message" row, so the columns line up across every card. */
.pf-intro { font-size: 12.5px; color: var(--text-3); margin-bottom: 12px; line-height: 1.5; }
.pf-list { display: flex; flex-direction: column; gap: 14px; }
.pf-card {
  background: #fff; border: 1px solid var(--border); border-radius: 14px;
  box-shadow: var(--shadow-sm); padding: 14px 16px 16px;
}
.pf-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.pf-ico {
  flex: none; width: 34px; height: 34px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-2, #f1f5f9);
}
.pf-ico img { width: 22px; height: 22px; object-fit: contain; }
.pf-name { font-size: 15px; font-weight: 700; color: var(--text); }
.pf-badge {
  margin-inline-start: auto; font-size: 11.5px; font-weight: 700;
  padding: 3px 10px; border-radius: var(--r-pill);
  background: var(--surface-2, #f1f5f9); color: var(--text-3); white-space: nowrap;
}
.pf-badge.on { background: #e7f6ef; color: var(--success, #059669); }
.pf-grid {
  display: grid; gap: 12px 20px; align-items: start;
  grid-template-columns: minmax(150px, 1fr) minmax(180px, 1.2fr) auto;
}
.pf-col { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.pf-toggle { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-2); cursor: pointer; }
.pf-toggle input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--brand-600); }
.pf-comp { gap: 6px; flex-wrap: wrap; }
.pf-num {
  width: 78px; padding: 5px 8px; border: 1px solid var(--border); border-radius: 8px;
  font-size: 13px; font-family: inherit; color: var(--text); background: #fff;
}
.pf-num:focus { outline: none; border-color: var(--brand-500); box-shadow: 0 0 0 3px var(--brand-50, #eef2ff); }
.pf-comp .pf-num { width: 64px; }
.pf-actions { display: flex; gap: 8px; justify-self: end; align-items: flex-start; }
.pf-iconbtn {
  width: 38px; height: 38px; border-radius: 10px; border: 1px solid var(--border);
  background: #fff; font-size: 17px; line-height: 1; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: border-color .15s, background .15s, transform .12s;
}
.pf-iconbtn:hover:not(:disabled) { border-color: var(--brand-400); background: var(--surface); transform: translateY(-1px); }
.pf-iconbtn.active { border-color: var(--brand-500); background: var(--brand-50, #eef2ff); }
.pf-iconbtn:disabled { opacity: .5; cursor: progress; }
.pf-limits { grid-column: 1 / -1; border-top: 1px dashed var(--border); padding-top: 12px; }
.pf-limits-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.pf-limits-label { font-size: 12.5px; font-weight: 700; color: var(--text-2); white-space: nowrap; }
.pf-field { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--text-3); white-space: nowrap; }
.pf-inputwrap { position: relative; display: inline-flex; align-items: center; }
.pf-inputwrap .pf-num { width: 86px; padding-inline-end: 22px; }
.pf-inf { position: absolute; inset-inline-end: 8px; font-size: 15px; line-height: 1; color: var(--text-3); pointer-events: none; }
.pf-hint { font-size: 12px; color: var(--text-3); margin-top: 6px; line-height: 1.5; }
.pf-guide {
  grid-column: 1 / -1; margin-top: 4px; border: 1px solid var(--border);
  border-radius: 10px; padding: 12px; background: var(--surface-2, #f8fafc);
}
.pf-footer { display: flex; align-items: center; gap: 12px; margin-top: 16px; flex-wrap: wrap; }
.pf-status { font-size: 12.5px; color: var(--text-3); }

@media (max-width: 860px) {
  .pf-grid { grid-template-columns: 1fr; }
  .pf-actions { justify-self: start; }
  .pf-limits { border-top: none; padding-top: 0; }
}
[dir="rtl"] .hub-card:hover .hub-open { transform: translateX(-3px); }

/* =========================================================================
   Admin Hub -> Dependencies (one Update button per package + Update All)
   ========================================================================= */
.deps-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 12px 0 0; }
.deps-pill {
  font-size: 12px; font-weight: 600; color: var(--text-2);
  background: var(--surface-2, #f1f5f9); border: 1px solid var(--border);
  border-radius: var(--r-pill); padding: 4px 11px; white-space: nowrap;
}
.deps-pill.ok { background: #ecfdf5; border-color: #a7f3d0; color: #047857; }
.deps-pill.warn { background: #fffbeb; border-color: #fde68a; color: #b45309; }
.deps-interp {
  font-size: 11px; color: var(--text-3); background: transparent;
  border: none; padding: 0; margin-left: auto; overflow-wrap: anywhere;
}
.deps-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 14px 0 16px; }
.deps-hint { font-size: 12px; color: var(--text-3); }
/* Opt-in auto-restart toggle that sits with the action buttons. */
.deps-auto {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  font-size: 12.5px; font-weight: 600; color: var(--text-2);
  border: 1px solid var(--border); border-radius: var(--r-pill);
  padding: 6px 12px; background: var(--surface, #fff); user-select: none;
}
.deps-auto:hover { border-color: var(--brand-400); color: var(--brand-600); }
.deps-auto input { accent-color: var(--brand-600); cursor: pointer; margin: 0; }

/* Manual restart banner — sits ABOVE the package list and only appears once
   something has actually changed. */
.deps-restart-banner {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  flex-wrap: wrap; margin: 14px 0 0; padding: 13px 16px;
  background: #fffbeb; border: 1px solid #fde68a; border-left: 4px solid #f59e0b;
  border-radius: 12px;
}
.deps-restart-banner.is-busy { background: #eff6ff; border-color: #bfdbfe; border-left-color: #3b82f6; }
.deps-restart-txt { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.deps-restart-txt b { font-size: 13.5px; color: #92400e; }
.deps-restart-banner.is-busy .deps-restart-txt b { color: #1d4ed8; }
.deps-restart-txt span { font-size: 12.5px; color: var(--text-2); }
.deps-restart-what {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11.5px; color: #b45309; overflow-wrap: anywhere;
}
.deps-restart-note { font-size: 12px; color: #b91c1c; overflow-wrap: anywhere; }
.deps-restart-btn { white-space: nowrap; }
.deps-restart-btn[disabled] { opacity: .55; cursor: not-allowed; }
.deps-loading { color: var(--text-3); font-size: 13.5px; text-align: center; padding: 28px 10px; }

.deps-list { display: flex; flex-direction: column; gap: 10px; }
.deps-row {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 14px;
  padding: 14px 16px; background: #fff; border: 1px solid var(--border);
  border-left: 4px solid var(--border); border-radius: 12px; box-shadow: var(--shadow-sm);
}
.deps-row.is-outdated { border-left-color: #f59e0b; }
.deps-row-main { display: flex; align-items: flex-start; gap: 12px; min-width: 0; flex: 1 1 auto; }
.deps-row-ico {
  flex: none; width: 40px; height: 40px; border-radius: 11px;
  display: flex; align-items: center; justify-content: center; font-size: 20px;
  background: var(--surface-2, #f1f5f9);
}
.deps-row-txt { min-width: 0; }
.deps-row-title {
  font-weight: 800; font-size: 14.5px; color: var(--text); line-height: 1.3;
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
}
.deps-kind {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-3); background: var(--surface-2, #f1f5f9);
  border-radius: var(--r-pill); padding: 2px 7px;
}
.deps-tag {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: #b45309; background: #fffbeb; border: 1px solid #fde68a;
  border-radius: var(--r-pill); padding: 2px 7px;
}
.deps-row-why { font-size: 12.5px; color: var(--text-2); margin-top: 4px; line-height: 1.45; }
.deps-row-impact { font-size: 11.5px; color: var(--text-3); margin-top: 4px; }
.deps-ver { display: flex; align-items: center; gap: 6px; margin-top: 6px; font-size: 12px; flex-wrap: wrap; }
.deps-ver-inst { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--text-2); }
.deps-ver-arrow { color: var(--text-3); }
.deps-ver-new { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-weight: 700; color: #b45309; }
.deps-err {
  margin-top: 7px; font-size: 12px; color: #b91c1c; background: #fef2f2;
  border: 1px solid #fecaca; border-radius: 8px; padding: 7px 10px; line-height: 1.45;
}
.deps-note {
  margin-top: 7px; font-size: 12px; color: #92400e; background: #fffbeb;
  border: 1px solid #fde68a; border-radius: 8px; padding: 7px 10px; line-height: 1.45;
  overflow-wrap: anywhere;
}
.deps-last { font-size: 11px; color: var(--text-3); margin: -2px 0 0 4px; }
.deps-row-side { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; flex: none; }
.deps-status {
  font-size: 11.5px; font-weight: 700; border-radius: var(--r-pill);
  padding: 3px 9px; white-space: nowrap; background: var(--surface-2, #f1f5f9); color: var(--text-2);
}
.deps-status.ok { background: #ecfdf5; color: #047857; }
.deps-status.warn { background: #fffbeb; color: #b45309; }
.deps-status.err { background: #fef2f2; color: #b91c1c; }
.deps-status.busy { background: #eff6ff; color: #1d4ed8; }
.deps-btn { white-space: nowrap; }
.deps-btn[disabled] { opacity: .55; cursor: not-allowed; }
/* Already at the latest version: clearly inert, not just faded. */
.deps-btn.is-done,
.deps-btn.is-done[disabled] {
  opacity: .5; background: var(--surface-2, #f1f5f9) !important;
  color: var(--text-3) !important; border-color: var(--border) !important;
  cursor: not-allowed; box-shadow: none;
}
.deps-out {
  margin: 0 0 8px; padding: 10px 12px; font-size: 11.5px; line-height: 1.5;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  background: #0f172a; color: #e2e8f0; border-radius: 10px;
  max-height: 260px; overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere;
}

@media (max-width: 720px) {
  .deps-row { flex-direction: column; }
  .deps-row-side { flex-direction: row; align-items: center; justify-content: space-between; width: 100%; }
  .deps-interp { margin-left: 0; flex-basis: 100%; }
}
[dir="rtl"] .deps-row { border-left: 1px solid var(--border); border-right: 4px solid var(--border); }
[dir="rtl"] .deps-row.is-outdated { border-right-color: #f59e0b; }
[dir="rtl"] .deps-row-side { align-items: flex-start; }
[dir="rtl"] .deps-restart-banner { border-left: 1px solid #fde68a; border-right: 4px solid #f59e0b; }
[dir="rtl"] .deps-restart-banner.is-busy { border-right-color: #3b82f6; }


.plan-strip {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px;
  font-size: 13px; border: 1px solid var(--border); background: #fff;
  border-radius: var(--r-md); padding: 14px 16px; margin-bottom: 20px;
  box-shadow: var(--shadow-sm);
}
.plan-strip span { display: flex; flex-direction: column; gap: 2px; color: var(--text-3); }
/* --- Plan / usage cards: an icon on the left, stacked content on the right --- */
.plan-strip .plan-tag,
.plan-strip .plan-meter-cell {
  flex-direction: row; align-items: center; gap: 9px;
  padding: 8px 11px; border-radius: var(--r-md); background: var(--surface-2);
  min-width: 0;
}
/* ------- card icon (uniform on every card) ------- */
.plan-strip .pc-ico {
  font-size: 19px; line-height: 1; flex: none; color: var(--brand-600);
}
/* ------- content group (label/value, or metric text + bar) ------- */
.plan-strip .pc-body {
  flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px;
  justify-content: center; align-self: stretch;
}
/* --- Tier box: small "Plan" label above a large, prominent tier value ---
   Matches the neutral card background of the other plan cells. */
.plan-strip .plan-tag .pc-body { align-items: flex-start; }
.plan-strip .pt-label {
  font-size: 11px; font-weight: 700; letter-spacing: .3px;
  text-transform: uppercase; color: var(--text-3);
}
.plan-strip .pt-value {
  font-size: 22px; line-height: 1.05; font-weight: 800; letter-spacing: -.2px;
  color: var(--brand-600); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.plan-strip .plan-tag-value {
  font-size: 24px; line-height: 1; font-weight: 800; letter-spacing: -.3px;
  color: var(--brand-600); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* --- Metric cells (Sent / Accounts / Storage) --- */
.plan-strip .plan-meter-cell {
  font-size: 13px; font-weight: 600; color: var(--text-2);
}
.plan-strip .plan-meter-cell > .pc-body { justify-content: center; }
.plan-strip .plan-meter-cell .pc-ico { align-self: center; }
.plan-strip .storage-meter {
  width: 100%; height: 8px; border-radius: 999px; background: var(--surface-3, #e2e8f0);
  overflow: hidden; display: block;
}
.plan-strip .storage-meter > span {
  display: block; height: 100%; width: 0%; border-radius: 999px;
  background: var(--ok, #16a34a); transition: width .3s ease, background .3s ease;
}
.plan-strip .storage-meter > span.st-orange { background: #f59e0b; }
.plan-strip .storage-meter > span.st-red { background: #dc2626; }
.plan-strip .pill-btn-upgrade {
  grid-column: 1 / -1; justify-self: end; align-self: center;
  margin: 0; font-size: 13px; font-weight: 700;
}

.app-content { padding: 26px 26px 40px; max-width: 1320px; margin: 0 auto; width: 100%; }

/* ---- Cards ---------------------------------------------------------------- */
.card {
  background: #fff;
  border-radius: var(--r-lg);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  margin-bottom: 16px;
}
.card-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 15px 20px; font-weight: 700; font-size: 15px;
  background: #fff; border-bottom: 1px solid var(--border);
  text-align: left; color: var(--text);
}
.card-head:hover { background: var(--surface); }
.card-head .chev { transition: transform .15s ease; color: var(--text-3); }
.card-head.open .chev { transform: rotate(180deg); }
.card-body { padding: 18px 20px; }
.card-body.hidden-body { display: none; }
.hidden-body { display: none; }

/* ---- Buttons -------------------------------------------------------------- */
.btn-primary {
  background: var(--brand-600); color: #fff;
  padding: .65rem 1.1rem; border-radius: var(--r-pill); font-weight: 600;
  border: 1px solid transparent; transition: background .15s, box-shadow .15s, opacity .15s;
  box-shadow: var(--shadow-brand);
}
.btn-primary:hover:not(:disabled) { background: var(--brand-700); }
.btn-primary:disabled { opacity: .45; cursor: not-allowed; box-shadow: none; }

.btn-secondary {
  background: #fff; color: var(--text); border: 1px solid var(--border-2);
  padding: .55rem 1rem; border-radius: var(--r-pill); font-weight: 600;
  transition: background .15s, border-color .15s;
}
.btn-secondary:hover:not(:disabled) { background: var(--brand-50); border-color: var(--brand-400); color: var(--brand-600); }
.btn-secondary:disabled { opacity: .45; }

/* "Delete the built files" on Admin → Marketing. Small and red on purpose: it is
   the only destructive control on that page, and it sits at the far end of the
   button row (`margin-inline-start: auto`) so it cannot be caught while reaching
   for Download. It always confirms before doing anything. */
.st-mk-del {
  margin-inline-start: auto;
  background: #fff; color: var(--danger, #dc2626);
  border: 1px solid var(--danger, #dc2626);
  padding: .4rem .8rem; font-size: .8rem; font-weight: 700;
  border-radius: var(--r-pill); cursor: pointer; white-space: nowrap;
  transition: background .15s, color .15s, opacity .15s;
}
.st-mk-del:hover:not(:disabled) { background: var(--danger, #dc2626); color: #fff; }
.st-mk-del:disabled { opacity: .45; cursor: not-allowed; }

.btn-mini {
  background: var(--surface-2); color: var(--text-2); border: 1px solid var(--border);
  padding: .4rem .75rem; border-radius: var(--r-pill); font-size: .8rem; font-weight: 600;
  transition: background .15s, border-color .15s; cursor: pointer; white-space: nowrap;
}
.btn-mini:hover { background: var(--brand-50); border-color: var(--brand-300); color: var(--brand-600); }

.btn-ghost {
  background: transparent; color: var(--text-2); border: 1px solid var(--border-2);
  padding: .4rem .9rem; border-radius: var(--r-pill); font-size: .82rem; font-weight: 600;
  transition: background .15s, border-color .15s; cursor: pointer; white-space: nowrap;
}
.btn-ghost:hover { background: var(--brand-50); border-color: var(--brand-300); color: var(--brand-600); }

/* ===== Email system (admin Emailing + user Reports) =====
   Keep action buttons pill-shaped and never let a long status/error message
   beside them stretch or collapse the button into a circle/oval. */
#emailAdminRoot button.btn-primary,
#emailAdminRoot button.btn-secondary,
#emailAdminRoot button.btn-danger,
#emailAdminRoot .btn-mini,
#reportsBody button.btn-primary,
#reportsBody button.btn-secondary,
#reportsBody button.btn-danger,
#reportsBody .btn-mini {
  flex: 0 0 auto;
  min-width: 0;
  white-space: nowrap;
  width: auto;
}
#emailAdminRoot .row-actions,
#reportsBody .row-actions,
#emailAdminRoot div.flex.flex-wrap,
#reportsBody div.flex.flex-wrap {
  row-gap: .5rem;
}
/* Status messages: keep them small and let them wrap on their own line. */
#emailAdminRoot .email-status,
#reportsBody .email-status {
  max-width: 100%;
  overflow-wrap: break-word;
  line-height: 1.4;
  flex: 1 1 100%;
}

.pill-btn {
  font-size: .76rem; font-weight: 700; padding: .45rem 1rem; border-radius: var(--r-pill);
  border: 1px solid var(--brand-200); background: var(--brand-50); color: var(--brand-700);
  cursor: pointer; transition: all .15s; white-space: nowrap; box-shadow: 0 1px 2px rgba(0,0,0,.05);
}
.pill-btn:hover { background: var(--brand-100); border-color: var(--brand-300); }

/* Topbar Bell + Feedback: flex layout so a dedicated icon glyph can be shown
   alone on compact/mobile screens while the text label stays for desktop. */
.pill-btn#btnBell, .pill-btn#btnFeedback {
  display: inline-flex; align-items: center; gap: 6px;
}
.pill-btn#btnBell .tb-ico, .pill-btn#btnFeedback .tb-ico {
  font-size: 16px; line-height: 1; display: inline-flex;
}
/* Mobile: collapse the Bell + Feedback pills into small circular icon chips so
   they no longer crowd/overlap the page title + hamburger on narrow phones.
   The app applies a global min 44x44 touch-target to all <button>s on mobile,
   so we size the Bell, Feedback and language chips to an equal 44px round so
   the whole top-right cluster lines up as one tidy row. */
@media (max-width: 560px) {
  .topbar .tb-actions .i18n-toggle,
  .topbar .tb-actions .pill-btn#btnBell,
  .topbar .tb-actions .pill-btn#btnFeedback {
    width: 44px; height: 44px; min-width: 44px; min-height: 44px;
    padding: 0; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    gap: 0; flex: none;
  }
  .pill-btn#btnBell .tb-lbl, .pill-btn#btnFeedback .tb-lbl { display: none; }
  .pill-btn#btnBell .tb-ico, .pill-btn#btnFeedback .tb-ico { font-size: 20px; }
}

.fmt-btn {
  width: 2rem; height: 2rem; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: .6rem; background: #fff; color: var(--text);
  font-size: .95rem; cursor: pointer; transition: background .15s, border-color .15s;
}
.fmt-btn:hover { background: var(--brand-50); }
.fmt-btn.active { background: var(--brand-100); border-color: var(--brand-300); }

/* ---- Tabs ----------------------------------------------------------------- */
.tabs { display: flex; gap: .3rem; background: var(--surface-2); padding: .3rem; border-radius: var(--r-pill); }
.tab {
  flex: 1; padding: .5rem .9rem; border-radius: var(--r-pill); font-weight: 600;
  color: var(--text-2); background: transparent; border: none; cursor: pointer;
  transition: background .15s, color .15s;
}
.tab.active { background: #fff; color: var(--brand-600); box-shadow: var(--shadow-sm); }
.tab-panel { display: block; }
.tab-panel.hidden { display: none; }

/* ---- Media Library modal overlay ------------------------------------------- */
/* Visibility is toggled via the .hidden class; flex-centering applies only
   when the overlay is shown (do NOT put display:flex in the inline style,
   inline styles override .hidden and leave the dark backdrop stuck on screen). */
#mediaPanelOverlay { display: none; align-items: center; justify-content: center; }
#mediaPanelOverlay:not(.hidden) { display: flex; }

/* ---- Composer media-library picker grid --------------------------------------
   Give every tile a fixed square-ish thumbnail area so photo/video previews
   render on BOTH desktop and mobile (the inline HTML adds no width/height, so
   without this the media bleeds / the video shows no frame on mobiles). */
#mediaPanel .media-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
  gap: 10px;
}
#mediaPanel .media-tile img,
#mediaPanel .media-tile video { width: 100%; height: 100%; object-fit: cover; display: block; }
.media-thumb {
  position: relative; width: 100%; height: 112px;
  background: var(--surface-2, #f1f5f9); overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.media-thumb.img, .media-thumb.audio { height: 112px; }
.media-thumb.audio { font-size: 30px; }

/* The picker's sticky "Use selected" footer. It MUST paint above the tiles: a
   phone leaves a tapped tile in :hover, which reveals that tile's ✏️ 📂 🗑 action
   strip (inline z-index:3), and with no z-index of its own this sticky bar
   (DOM-later but z-index:auto) lost to them — the reported "the icons overlay the
   Use selected button on the mobile". The solid ground also hides the tiles that
   scroll underneath it. */
#mediaPanel .media-pick-bar {
  position: sticky; bottom: 0; z-index: 20;
  background: var(--surface, #fff);
  padding: 8px 0;
  border-top: 1px solid var(--border, #e2e8f0);
}

/* Selection is a CLASS, not an inline style, so it can be toggled on a tile that
   already exists. Rebuilding the grid on every click destroyed the <img> nodes
   and re-triggered lazy decoding — a visible flicker on desktop, and thumbnails
   that flickered on/off on a phone. */
#mediaPanel .media-tile.on { outline: 3px solid var(--brand-500, #6d5cff); outline-offset: -1px; }
#mediaPanel .media-row.on { background: var(--brand-50); }
@media (max-width: 420px) {
  #mediaPanel .media-grid { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }
  .media-thumb { height: 96px; }
  .media-thumb.img, .media-thumb.audio { height: 96px; }
}

/* ---- Phone: the LIST view must not squeeze the pictures out ----------------
   The list is a five-column table (thumb, Name, Size, Added, Deletes on). On a
   narrow panel the columns cannot all fit, so the table out-grew the card AND the
   auto layout collapsed the thumbnail column to ~15px — Tailwind's `img{max-width:
   100%}` then shrank each 44px thumbnail to a sliver, i.e. "I do not see the
   thumbnails on the mobile". Three rules fix it below 640px:
     1. the metadata columns are dropped (the row is thumb + name + actions);
     2. the thumbnail column and its 44px image are pinned, so they can never
        collapse again;
     3. the name/actions row may wrap, which is what lets the table fit the panel
        instead of overflowing it. */
#mediaPanel .media-list-table th:first-child,
#mediaPanel .media-list-table td:first-child { width: 52px; min-width: 52px; }
#mediaPanel .media-list-table td:first-child img {
  width: 44px; height: 44px; min-width: 44px; max-width: 44px;
}
@media (max-width: 640px) {
  #mediaPanel .media-list-table { width: 100%; }
  #mediaPanel .media-list-table th:nth-child(n+3),
  #mediaPanel .media-list-table td:nth-child(n+3) { display: none; }
  #mediaPanel .media-list-table td:nth-child(2) { min-width: 0; }
  #mediaPanel .media-list-table td:nth-child(2) > .flex { flex-wrap: wrap; }
  /* ...and the name may use the width the dropped columns freed. */
  #mediaPanel .media-list-table td .truncate { max-width: none !important; flex: 1 1 auto; min-width: 0; }
  #mediaPanel .media-grid { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); }
}

/* ---- Inline "Edit Photo" (Quick Post composer) ----------------------------- */
.qpe-step-on { border-color: var(--brand-500, #6366f1) !important; color: var(--brand-700, #4f46e5) !important; background: var(--brand-50, #eef2ff) !important; }
.qpe-on { border-color: var(--brand-500, #6366f1) !important; background: var(--brand-50, #eef2ff) !important; color: var(--brand-700, #4f46e5) !important; }
.qpe-stage {
  position: relative; width: 100%; height: 260px; border-radius: 12px; overflow: hidden;
  background: repeating-conic-gradient(#eef2f7 0 25%, #ffffff 0 50%) 50%/22px 22px;
  border: 1px solid var(--border); display: flex; align-items: center; justify-content: center;
}
.qpe-stage img { max-width: 100%; max-height: 260px; object-fit: contain; transition: filter .12s linear; }
.qpe-section {
  border: 1px solid var(--border); border-radius: var(--r-md); background: #fafbff;
  padding: .55rem .6rem;
}
.qpe-section .section-title { font-size: .72rem; letter-spacing: .02em; color: var(--text-2); margin-bottom: .4rem; }
.qpe-slider { margin: .45rem 0; }
.qpe-slider > div { font-size: .85rem; color: var(--text-2); }
.qpe-slider input[type=range] { width: 100%; accent-color: var(--brand-500, #6d5cff); }
.qpe-slider-val { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--brand-600, #6d5cff); }

/* ---- Upload busy overlay (loading gif) ------------------------------------ */
.upload-busy {
  position: fixed; inset: 0; z-index: 9999; background: rgba(15,23,42,.55);
  display: none; align-items: center; justify-content: center; padding: 20px;
}
.upload-busy.show { display: flex; }
.upload-busy-box {
  background: #fff; padding: 30px 44px; border-radius: 16px;
  text-align: center; box-shadow: 0 20px 50px rgba(15,23,42,.3);
}
.upload-busy-box img { width: 64px; height: 64px; display: block; margin: 0 auto; }
.upload-busy-box p { margin: 12px 0 0; font-weight: 600; color: var(--text, #1e293b); }
.upload-busy-box p::after { content: "…"; }

/* ---- Upload progress overlay (file counter + bar) -------------------------
   Separate from .upload-busy above: that one is a bare "busy" gif reused by AI,
   watermark, export and project-load. This one is specifically for FILE UPLOADS
   and adds the two things users actually read while waiting — how many files are
   done, and a bar. The gif is kept (smaller) because a percentage alone can sit
   still for a long time while the server compresses/queues, which reads as a
   hang; the motion is what says "still working". */
.up-prog {
  position: fixed; inset: 0; z-index: 10000; background: rgba(15,23,42,.55);
  display: none; align-items: center; justify-content: center; padding: 20px;
}
.up-prog.show { display: flex; }
.up-prog-box {
  background: #fff; padding: 26px 34px; border-radius: 16px; min-width: 300px;
  max-width: min(92vw, 420px); text-align: center;
  box-shadow: 0 20px 50px rgba(15,23,42,.3);
}
.up-prog-box img.up-prog-gif {
  width: 44px; height: 44px; display: block; margin: 0 auto 4px;
}
.up-prog-count {
  margin: 6px 0 0; font-weight: 700; font-size: 1.05rem;
  color: var(--text, #1e293b); font-variant-numeric: tabular-nums;
}
.up-prog-msg {
  margin: 4px 0 0; font-size: .82rem; color: var(--text-2, #64748b);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; direction: ltr;
}
/* Persian/Arabic file names should read RTL. */
[dir="rtl"] .up-prog-msg { direction: rtl; }
.up-prog-track {
  margin: 14px 0 0; width: 100%; height: 8px; border-radius: 999px;
  background: var(--bg-2, #f1f5f9); overflow: hidden; position: relative;
}
.up-prog-fill {
  height: 100%; width: 0%; border-radius: 999px;
  background: linear-gradient(90deg, var(--brand-500, #6d5cff), #8b5cf6);
  transition: width .25s ease;
}
/* Indeterminate: when we genuinely cannot know the percentage (e.g. the final
   send request, where upload + job creation are one atomic call). An animated
   bar already signals liveness, so the gif is hidden in this state. */
.up-prog.is-indeterminate .up-prog-fill {
  width: 40%; transition: none; animation: upProgSlide 1.2s infinite ease-in-out;
}
.up-prog.is-indeterminate img.up-prog-gif { display: none; }
@keyframes upProgSlide { 0% { margin-inline-start: -40%; } 100% { margin-inline-start: 100%; } }
.up-prog-pct {
  margin: 8px 0 0; font-size: .78rem; font-weight: 700;
  color: var(--text-2, #64748b); font-variant-numeric: tabular-nums;
}

/* ---- Inputs ---------------------------------------------------------------- */
.inp-c {
  width: 100%; border: 1px solid var(--border-2); border-radius: var(--r-md);
  padding: .55rem .7rem; font-size: .9rem; background: #fff; color: var(--text);
  /* Keep password-manager / Chrome autofilled fields white instead of flashing
     Chrome's default grey/blue fill. The background-color transition pins the
     white fill while the autofill is applied. */
  -webkit-box-shadow: 0 0 0 1000px #fff inset;
  -webkit-text-fill-color: var(--text);
  transition: border-color .15s, box-shadow .15s, background-color 5000s ease-in-out 0s;
}
.inp-c:focus { outline: none; border-color: var(--brand-500); box-shadow: 0 0 0 3px var(--brand-100); }
.inp-c:-webkit-autofill,
.inp-c:-webkit-autofill:hover,
.inp-c:-webkit-autofill:focus {
  -webkit-box-shadow: 0 0 0 1000px #fff inset;
  -webkit-text-fill-color: var(--text);
  caret-color: var(--text);
  transition: background-color 5000s ease-in-out 0s;
}

/* Red highlight for missing / invalid required auth fields (signup, etc.) */
.inp-err,
.inp-err.inp-c {
  border-color: #e74c3c !important;
  box-shadow: 0 0 0 3px rgba(231, 76, 60, .15) !important;
}


/* ---- Admin → Payments: on/off toggles & one-of-N radio choices ------------- */
/* NOTE: never put .inp-c on a checkbox/radio. Its `width:100%`, its padding and
   its `0 0 0 1000px #fff inset` shadow squeeze the control to an empty white
   square and paint over the accent fill + tick, so a ticked box looked
   identical to an unticked one. These classes are the safe replacement. */
.pay-bool {
  display: flex; gap: 10px; align-items: flex-start; cursor: pointer;
  border: 1px solid var(--border-2); border-radius: var(--r-md);
  background: #fff; padding: 10px 12px; margin: 0 0 10px;
  transition: border-color .15s, background-color .15s, box-shadow .15s;
}
.pay-bool:hover { border-color: var(--brand-400); }
.pay-bool.is-on {
  border-color: var(--brand-500); background: var(--brand-50);
  box-shadow: 0 0 0 3px var(--brand-100);
}
.pay-bool > input[type=checkbox] {
  flex: 0 0 auto; width: 18px; height: 18px; margin: 1px 0 0;
  accent-color: var(--brand-600); cursor: pointer;
}
.pay-bool-txt { flex: 1 1 auto; min-width: 0; }
.pay-bool-title { display: block; font-size: 13px; font-weight: 600; color: var(--text); }
.pay-bool-help { display: block; font-size: 11.5px; color: var(--text-3); margin-top: 2px; }
/* Explicit On/Off pill so the state is readable even at a glance. */
.pay-state {
  flex: 0 0 auto; font-size: 11px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; border-radius: var(--r-pill); padding: 3px 10px;
  border: 1px solid var(--border-2); color: var(--text-3); background: #fff;
}
.pay-bool.is-on .pay-state {
  border-color: var(--brand-500); background: var(--brand-500); color: #fff;
}

.pay-choice {
  border: 1px solid var(--border-2); border-radius: var(--r-md);
  background: #fff; padding: 10px 12px; margin: 0 0 10px;
}
.pay-choice-title { display: block; font-size: 13px; font-weight: 600; color: var(--text); }
.pay-choice-help { display: block; font-size: 11.5px; color: var(--text-3); margin-top: 2px; }
.pay-choice-opts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 9px; }
.pay-opt {
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  border: 1px solid var(--border-2); border-radius: var(--r-pill);
  padding: 6px 14px 6px 11px; background: #fff; font-size: 12.5px;
  font-weight: 600; color: var(--text-2); user-select: none;
  transition: border-color .15s, background-color .15s, color .15s;
}
.pay-opt:hover { border-color: var(--brand-400); }
.pay-opt:has(input:checked) {
  border-color: var(--brand-500); background: var(--brand-50); color: var(--brand-700);
}
.pay-opt input[type=radio] {
  width: 15px; height: 15px; margin: 0; flex: 0 0 auto;
  accent-color: var(--brand-600); cursor: pointer;
}
.pay-opt-help { font-size: 11.5px; font-weight: 400; color: var(--text-3); }


/* ---- Drop zone -------------------------------------------------------------- */
.drop-zone {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .25rem; text-align: center; border: 2px dashed var(--border-2);
  border-radius: var(--r-lg); padding: 1.5rem 1rem; color: var(--text-2);
  transition: border-color .15s, background .15s;
}
.drop-zone:hover { border-color: var(--brand-400); background: var(--brand-50); cursor: pointer; }
.drop-zone.dragover { border-color: var(--brand-500); background: var(--brand-50); }

/* ---- Log box ---------------------------------------------------------------- */
.log-box {
  background: #0f172a; color: #e2e8f0;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .75rem; line-height: 1.5; border-radius: var(--r-md);
  padding: .75rem; height: 12rem; overflow-y: auto; white-space: pre-wrap; word-break: break-word;
}
.log-box .ok-line { color: #34d399; }
.log-box .err-line { color: #f87171; }

/* ---- Activity page: Status & log + Last posted -------------------------------
   Stack vertically on phones; go side-by-side only once there is room. */
.activity-grid { display: grid; grid-template-columns: 1fr; gap: 18px; }
@media (min-width: 860px) { .activity-grid { grid-template-columns: 1fr 1fr; } }

/* ---- Account cards & badges ------------------------------------------------- */
.account-card {
  display: flex; align-items: center; gap: .7rem;
  border: 1px solid var(--border); border-radius: var(--r-md); padding: .7rem .85rem;
  background: #fff; box-shadow: var(--shadow-sm);
}
.account-card .acc-badge {
  font-size: .6rem; font-weight: 700; text-transform: uppercase; letter-spacing: .02em;
  padding: .18rem .5rem; border-radius: var(--r-pill); white-space: nowrap;
}
.badge-telegram { background: #dbeafe; color: #1e40af; }
.badge-bale { background: #dbeafe; color: #1d4ed8; }
.badge-eitaa { background: #dcfce7; color: #15803d; }
.badge-rubika { background: #fef3c7; color: #b45309; }
.badge-youtube { background: #fee2e2; color: #b91c1c; }
.badge-aparat { background: #fce7f3; color: #be185d; }
.badge-wordpress { background: #e0eef6; color: #155e75; }
/* Soroush Plus — its brand blue (#1b74bc); the red in its logo is reserved for
   the destructive/urgent accents elsewhere in the UI. */
.badge-soroush { background: #dbeafe; color: #1b74bc; }

/* account toggle rows in Send-to */
.acc-toggle {
  display: flex; align-items: center; gap: .6rem;
  border: 1px solid var(--border-2); border-radius: var(--r-md); padding: .6rem .8rem;
  background: #fff; cursor: pointer; transition: background .15s, border-color .15s;
}
.acc-toggle:hover { border-color: var(--brand-400); }
.acc-toggle.on { background: var(--brand-50); border-color: var(--brand-500); }
.acc-toggle .sig-dot { font-size: .8rem; }
.acc-toggle .acc-ico {
  width: 34px; height: 34px; flex: none; border-radius: 10px; background: var(--surface-2);
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.acc-toggle .acc-ico img { width: 22px; height: 22px; object-fit: contain; }

/* Bulk row account picker: platform icon, selected = brand halo ring (no tick box) */
.bulk-acc {
  display: inline-flex; align-items: center; gap: 7px;
  border: 2px solid var(--border-2); border-radius: 999px;
  padding: 5px 11px 5px 6px; background: #fff; cursor: pointer;
  font-size: 12px; font-weight: 600; color: var(--text-2);
  transition: border-color .15s, box-shadow .15s, background .15s;
}
.bulk-acc img { width: 20px; height: 20px; object-fit: contain; border-radius: 50%; }
.bulk-acc .bulk-acc-name { max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bulk-acc:hover { border-color: var(--brand-400); }
.bulk-acc.on {
  border-color: var(--brand-500);
  background: var(--brand-50);
  box-shadow: 0 0 0 3px var(--brand-100), 0 2px 8px rgba(79,70,229,.18);
}
/* Smart Publishing rule ROW: the same pill, used as a read-only label (source →
   destinations) rather than a control, so it must not look clickable. */
.bulk-acc.mirror-pill { cursor: default; }
.bulk-acc.mirror-pill:hover { border-color: var(--border-2); }

/* ---- Smart Publishing: searchable rule list ---------------------------------- */
.mirror-search-row { display: flex; align-items: center; gap: 10px; margin: 0 0 10px; flex-wrap: wrap; }
.mirror-search {
  flex: 1; min-width: 180px; max-width: 320px; box-sizing: border-box;
  border: 1px solid var(--border-2); border-radius: 10px;
  padding: 7px 12px; font-size: 13px; font-family: inherit;
  color: var(--text); background: var(--surface, #fff);
}
.mirror-search:focus { outline: none; border-color: var(--brand-500); box-shadow: 0 0 0 3px var(--brand-100); }
.mirror-list { display: flex; flex-direction: column; gap: 8px; }
.mirror-flow { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.mirror-flow .mirror-arrow { color: var(--text-3); font-weight: 700; padding: 0 2px; }
/* Right-to-left: the arrow must point the way the text flows (destination on the
   left), which a mirrored glyph cannot do on its own. */
[dir="rtl"] .mirror-flow .mirror-arrow { transform: scaleX(-1); }

/* ---- Schedule fields ---------------------------------------------------------- */
.schedule-field {
  display: flex; align-items: center; gap: .6rem;
  border: 1px solid var(--border-2); border-radius: var(--r-md); padding: .65rem .8rem; background: #fff;
}
.schedule-field .sf-icon { font-size: 1.4rem; }
.schedule-field .sf-label { display: block; font-size: .7rem; color: var(--text-3); font-weight: 600; text-transform: uppercase; }
.sf-input { border: none; outline: none; font-size: 1rem; font-weight: 600; color: var(--text); background: transparent; width: 100%; }
.schedule-field:focus-within { border-color: var(--brand-500); box-shadow: 0 0 0 3px var(--brand-100); }

/* ---- Scheduled / misc ---------------------------------------------------------- */
.sched-item { border: 1px solid var(--border); border-radius: var(--r-md); padding: .65rem .8rem; background: #fff; box-shadow: var(--shadow-sm); }
.sched-countdown { font-size: .8rem; font-weight: 600; color: var(--brand-600); font-variant-numeric: tabular-nums; }

.attach-chip {
  display: flex; align-items: center; gap: .5rem;
  border: 1px solid var(--border); border-radius: var(--r-md); padding: .5rem .75rem; background: #fff;
}
/* Thumbnail preview in the composer attachment tray (photo/video). */
.attach-chip .attach-thumb {
  flex: none; width: 44px; height: 44px; border-radius: 6px; overflow: hidden;
  background: var(--surface-2, #f1f5f9); border: 1px solid var(--border);
}
.attach-chip .attach-thumb img,
.attach-chip .attach-thumb video { width: 100%; height: 100%; object-fit: cover; display: block; }
.attach-chip .kind-badge {
  font-size: .65rem; font-weight: 700; text-transform: uppercase;
  padding: .15rem .4rem; border-radius: var(--r-pill); background: var(--brand-100); color: var(--brand-700);
}

/* ---- Attachment upload state (background upload queue) -------------------------
   A file uploads as soon as it is SELECTED, so the chip has to say what is
   happening to it. The bar is thin and the label short on purpose: it sits in a
   row with the filename and must not push the ✕ away on a phone. */
.attach-up { display: flex; align-items: center; gap: .4rem; flex: none; }
.attach-up-bar {
  width: 54px; height: 4px; border-radius: var(--r-pill); overflow: hidden;
  background: var(--surface-2, #f1f5f9); border: 1px solid var(--border);
}
.attach-up-fill {
  height: 100%; width: 0%; border-radius: var(--r-pill);
  background: linear-gradient(135deg, var(--brand-500, #6366f1), var(--accent-500, #06b6d4));
  transition: width .18s linear;
}
.attach-up-bar.up-fail { background: #fee2e2; border-color: #fecaca; }
.attach-up-bar.up-fail .attach-up-fill { background: #dc2626; width: 100% !important; }
.attach-up-lbl { font-size: .68rem; font-weight: 700; color: var(--text-3); white-space: nowrap; }
.attach-up-lbl.up-ok { color: #059669; }
.attach-up-lbl.up-fail { color: #dc2626; }
.attach-up-retry {
  flex: none; font-size: .68rem; font-weight: 700; cursor: pointer; font-family: inherit;
  padding: .15rem .5rem; border-radius: var(--r-pill);
  border: 1px solid #fecaca; background: #fff1f2; color: #b91c1c;
}
.attach-chip-failed { border-color: #fecaca; background: #fff7f7; }

/* ---- Send queue (Composer) ----------------------------------------------------
   "Sending" is something you START. Pressing Send snapshots the message, clears
   the composer and continues in the background, so this strip is where that work
   reports back — one row per message, newest activity at the bottom. */
.sendq {
  display: flex; flex-direction: column; gap: .35rem;
  margin: .75rem 0 0; padding: .6rem .7rem;
  border: 1px solid var(--border); border-radius: var(--r-md); background: var(--surface, #f8fafc);
}
/* Tailwind's .hidden is injected at runtime, so order is not guaranteed. */
.sendq.hidden, .send-pill.hidden { display: none !important; }
.sendq-head {
  display: flex; align-items: center; justify-content: space-between;
  font-size: .68rem; font-weight: 800; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-3);
}
.sendq-clear {
  font-family: inherit; font-size: .68rem; font-weight: 700; cursor: pointer;
  border: none; background: none; color: var(--brand-600);
}
.sendq-row {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  font-size: .8rem; padding: .3rem .4rem; border-radius: .45rem; background: #fff;
  border: 1px solid var(--border);
}
.sendq-lbl { font-weight: 700; white-space: nowrap; }
.sendq-det { font-size: .72rem; color: var(--text-3); flex: 1 1 auto; min-width: 0; }
.sendq-bar { flex: 1 1 70px; min-width: 50px; height: 4px; border-radius: var(--r-pill); overflow: hidden; background: var(--surface-2, #f1f5f9); }
.sendq-fill {
  height: 100%; width: 0%; border-radius: var(--r-pill);
  background: linear-gradient(135deg, var(--brand-500, #6366f1), var(--accent-500, #06b6d4));
  transition: width .2s linear;
}
.sendq-sent { border-color: #bbf7d0; background: #f0fdf4; }
.sendq-failed, .sendq-held { border-color: #fecaca; background: #fff7f7; }
.sendq-held .sendq-lbl, .sendq-failed .sendq-lbl { color: #b91c1c; }
.sendq-cancelled { opacity: .6; }
/* The pill's click lands here — flash the strip so the eye finds it. */
.sendq-flash { animation: sendqflash 1.4s ease; }
@keyframes sendqflash {
  0%, 100% { box-shadow: none; }
  20%, 60% { box-shadow: 0 0 0 3px var(--brand-100, #e0e7ff); border-color: var(--brand-500, #6366f1); }
}

/* ---- Send pill (everywhere except the Composer) -------------------------------
   z-index 70 clears the mobile bottom nav (64). safe-area keeps it off the
   gesture bar on a phone.

   Reported twice: it "sits on top of the next button", "takes me away from my
   workflow" and "does not disappear after a few seconds". Two causes, both here
   and in paintSendPill(): the label was painted over the whole button, so there
   was nowhere for a ✕ to live, and a finished send is kept in state for five
   minutes, so the notice simply stayed. The label and the ✕ are now separate
   elements: the label is rewritten in place, the ✕ closes, and the pill's own
   click still opens the queue. */
.send-pill {
  position: fixed; z-index: 70;
  right: max(12px, env(safe-area-inset-right));
  bottom: calc(70px + env(safe-area-inset-bottom, 0px));
  font-family: inherit; font-size: .8rem; font-weight: 700; cursor: pointer;
  padding-block: .35rem; padding-inline: .85rem .4rem;
  border-radius: var(--r-pill); color: #fff;
  background: linear-gradient(135deg, var(--brand-600, #4f46e5), var(--accent-500, #06b6d4));
  border: 1px solid rgba(255, 255, 255, .25);
  box-shadow: 0 8px 22px rgba(15, 23, 42, .28);
  display: inline-flex; align-items: center; gap: .5rem;
}
.send-pill:hover { filter: brightness(1.06); }
.send-pill.pill-failed { background: linear-gradient(135deg, #dc2626, #b91c1c); }
.send-pill-txt { white-space: nowrap; }
/* The ✕. A 28px disc with a 44px touch target: the pill opens the queue when a tap
   lands anywhere else, so the ✕ has to be the easier thing to hit with a thumb. */
.send-pill-x {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px;
  margin-block: -.35rem; margin-inline: 0 -.15rem;
  border-radius: 50%; background: rgba(255, 255, 255, .18);
  font-size: 13px; line-height: 1; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.send-pill-x::after { content: ""; position: absolute; inset: -8px; }
.send-pill-x:hover { background: rgba(255, 255, 255, .34); }
[dir="rtl"] .send-pill { right: auto; left: max(12px, env(safe-area-inset-left)); }

.send-retry-row { display: flex; align-items: center; gap: .5rem; border: 1px solid var(--border); border-radius: var(--r-md); padding: .5rem .6rem; }

.bulk-row { border: 1px solid var(--border); border-radius: var(--r-md); padding: .6rem; background: #fff; }
.bulk-row .row-status { font-size: .7rem; font-weight: 600; }
.bulk-row .row-status.ok { color: #059669; }
.bulk-row .row-status.fail { color: #dc2626; }
.bulk-row .row-status.pending { color: #94a3b8; }

/* ---- Auth modal (login/signup popup) ---------------------------------------------
   Added to #modalRoot (in app.js showAuthOverlay) while the auth popup is open.
   - Restores the brand indigo-tinted gradient backdrop (what the login screen
     used to look like) instead of the flat grey scrim used by other modals.
   - Top-anchors the card (align-items:flex-start) so switching between the
     shorter Log in form and the taller Sign up form does NOT make the popup
     re-center and jump vertically. Content grows downward from a fixed top. */
/* ---- Generic modal safety: sit above the mobile bottom nav -------------------
   The bottom nav bar uses z-index 64. Ensure the shared modal overlay always
   renders above it so its buttons (e.g. "Confirm send") are never hidden behind
   the sticky menu, and center the card on small screens. */
#modalRoot { z-index: 80; align-items: center; }
#modalRoot > #modalCard { border-radius: 16px; }
#modalRoot.auth-modal {
  /* Brand wash + the tinted mosaic as grain + the ink Tehran skyline along the
     bottom, so the login/register screen belongs to the landing page instead of
     being a flat scrim over a plain white card. Both decorations are absolutely
     positioned pseudo-elements on purpose: #modalRoot is a flex container, and an
     in-flow ::before would become a flex ITEM and shove the card around.
     NB the two artwork URLs carry no ?v= — a background written in CSS cannot take
     the template's asset_v (the stats strip does this with an inline style instead,
     see static/landing.css). */
  background:
    radial-gradient(900px 520px at 85% -12%, rgba(79,70,229,.18), transparent 60%),
    radial-gradient(760px 460px at 4% 104%, rgba(6,182,212,.16), transparent 55%),
    linear-gradient(135deg, #eef2ff 0%, #f8fafc 60%);
  align-items: flex-start;
  padding-top: 9vh;
  padding-bottom: 4vh;
  /* NOT `position: relative` — that overrode the overlay's `position: fixed` (the
     Tailwind `fixed inset-0` on #modalRoot) and collapsed the login screen to the
     height of its content, leaving the page's white background below it. A fixed
     element is already a containing block for these absolutely positioned layers. */
  overflow: hidden;
}
#modalRoot.auth-modal::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: url("/images/iran/brand/colours.svg") repeat;
  background-size: 300px auto;
  opacity: .06;
}
#modalRoot.auth-modal::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: min(42vh, 320px); pointer-events: none;
  /* `contain` and not `cover`: cover-cropping a skyline to a band slices the tower
     tops off (the lesson the hero learned), and this is a background so it cannot
     be given a natural height. */
  background: url("/images/iran/landscapedark.svg") no-repeat center bottom;
  background-size: contain;
  opacity: .14;
}
/* The card itself sits ABOVE both decorations. */
#modalRoot.auth-modal #modalCard { position: relative; z-index: 1; }
/* Auth card hero band: the logo sits on a brand wash with the hand-drawn swoosh
   behind it. The negative margins undo the card's own padding (p-5 = 20px) so the
   band bleeds to the card's edges, and the radius matches the card's rounded-2xl —
   without it the login card is a plain white sheet next to a decorated page. */
.auth-hero {
  position: relative; overflow: hidden; text-align: center;
  margin: -20px -20px 16px; padding: 20px 18px 16px;
  border-radius: 16px 16px 0 0;
  background: linear-gradient(180deg, #eef2ff 0%, rgba(255,255,255,0) 100%);
  border-bottom: 1px solid var(--border);
}
.auth-hero-art {
  position: absolute; left: 50%; top: 50%; width: 150%; max-width: none;
  transform: translate(-50%, -50%); opacity: .5; pointer-events: none;
}
.auth-hero .auth-home-link { position: relative; z-index: 1; }
#modalRoot.auth-modal #modalCard {
  box-shadow: 0 20px 50px rgba(15,23,42,.16);
  border: 1px solid var(--border);
}

/* ---- Language toggle on the auth/forgot modal (EN/FA) ----------------------- */
.auth-modal .lang-toggle {
  position: absolute;
  top: -0.25rem;
  right: 0;
  width: 2.1rem;
  height: 2.1rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  /* A step stronger than --border: the button now sits ON the card's tinted band
     (#eef2ff), where the old #e2e8f0 outline all but disappeared. */
  border: 1px solid var(--brand-200, #c7d2fe);
  background: #fff;
  color: var(--text-2, #475569);
  font-weight: 700;
  font-size: 0.95rem;
  cursor: pointer;
  transition: all .15s;
  box-shadow: 0 1px 3px rgba(15,23,42,.08);
  /* ABOVE the .auth-hero band below it. The toggle sits in the top corner, which is
     exactly where the hero's tinted band bleeds (its negative margin undoes the
     card's padding), and .auth-hero comes later in the DOM — so without a z-index it
     was painted UNDER that semi-transparent wash AND the hero swallowed the clicks:
     the button looked greyed out and dead, which is why the login page could not be
     switched to English. A positioned sibling with an explicit z-index paints (and
     hit-tests) above a z-index:auto sibling. */
  z-index: 2;
}
.auth-modal .lang-toggle:hover {
  border-color: var(--brand-500, #6366f1);
  color: var(--brand-600, #4f46e5);
}
[dir="rtl"] .auth-modal .lang-toggle { right: auto; left: 0; }

/* ---- Password action buttons (👁️ reveal / 🎲 generate) — square boxes ------
   Placed beside the password input with a small gap, as clean little boxes
   instead of half-pills fused to the field. */
.pw-action {
  flex: 0 0 auto;
  width: 2.4rem;
  height: 2.4rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border, #e2e8f0);
  background: #fff;
  color: var(--text-2, #475569);
  border-radius: .5rem;
  cursor: pointer;
  font-size: 1.05rem;
  line-height: 1;
  padding: 0;
  transition: border-color .15s, color .15s, background .15s;
}
.pw-action:hover {
  background: #f8fafc;
  border-color: var(--brand-500, #6366f1);
  color: var(--brand-600, #4f46e5);
}


/* ---- Password requirements (signup + forgot password) ------------------------ */
.password-requirements { color: var(--text-2, #64748b); }
.password-requirements .req-item { transition: color .12s, opacity .12s; }
.password-requirements .req-item.passed { color: #16a34a; opacity: .85; }
.password-requirements .req-item.failed { color: #dc2626; }
.password-requirements .req-item:not(.passed):not(.failed) { opacity: .7; }

/* ---- Forgot-password method selection ---------------------------------------- */
#forgotMethods .method-option {
  display: flex; align-items: center; gap: .75rem; padding: .8rem 1rem;
  border: 2px solid var(--border, #e2e8f0); border-radius: .7rem; cursor: pointer;
  transition: border-color .15s, background .15s;
}
#forgotMethods .method-option.selected { border-color: var(--brand-600, #4f46e5); background: var(--brand-50, #eef2ff); }

/* ---- Toasts -------------------------------------------------------------------- */
.socials-toast {
  position: fixed; top: 14px; left: 50%; transform: translateX(-50%);
  color: #fff; font-size: 14px; padding: 10px 18px; border-radius: var(--r-pill);
  box-shadow: var(--shadow-lg); z-index: 100; animation: ss-toast-in .18s ease;
}
.socials-toast.ok { background: #16a34a; }
.socials-toast.err { background: #dc2626; }
.socials-toast.info { background: #4f46e5; }
@keyframes ss-toast-in { from { opacity: 0; transform: translate(-50%, -8px); } to { opacity: 1; transform: translate(-50%, 0); } }

/* ---- Notification dialog --------------------------------------------------------
   Replaces the red/green pills for anything that REPORTS AN OUTCOME. A pill
   disappears after 2.8 s whether or not it was read, which is fine for "Link
   copied" and wrong for "There is no SRT content to translate." — the user is
   left staring at an unchanged screen with no idea why. This is a real dialog:
   a tick or a cross, the reason in words, and an OK button, so the message
   cannot be missed and the user chooses when to carry on.

   z-index 200: above #modalRoot (80) and .socials-toast (100), below the Photo
   Editor's full-screen shell (10000) — a notification should sit on top of a
   form the user is filling in, but must not float over a dedicated full-screen
   editor. */
.notify-root {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  padding: 16px; background: rgba(15, 23, 42, .55);
  animation: notify-fade .14s ease;
}
.notify-root.hidden { display: none; }
@keyframes notify-fade { from { opacity: 0; } to { opacity: 1; } }
.notify-card {
  width: 100%; max-width: 27rem; background: #fff;
  border-radius: 18px; padding: 24px 22px 18px;
  box-shadow: 0 24px 60px rgba(15, 23, 42, .28);
  text-align: center;
  animation: notify-pop .18s cubic-bezier(.2, .9, .3, 1.2);
  position: relative;                /* anchors the ✕ */
}
/* The ✕. A message now takes itself away after 5 s, and this is how it is waved
   off in the meantime — so closing a message never means finding the OK button
   first. */
.notify-x {
  position: absolute; top: 8px; inset-inline-end: 8px;
  width: 32px; height: 32px; padding: 0;
  border: none; border-radius: 50%; cursor: pointer;
  background: #f1f5f9; color: #64748b;
  font-family: inherit; font-size: 17px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
}
.notify-x:hover { background: #e2e8f0; color: #0f172a; }
/* The transient status pill (toast): same ✕ idea, sized for a pill. */
.ss-toast-x {
  border: none; background: transparent; color: inherit; opacity: .75;
  font-family: inherit; font-size: 15px; line-height: 1; cursor: pointer;
  padding: 0 2px; margin: 0 -2px 0 0;
}
.ss-toast-x:hover { opacity: 1; }
@keyframes notify-pop { from { opacity: 0; transform: scale(.94) translateY(8px); } to { opacity: 1; transform: none; } }
/* Drawn as SVG rather than an emoji: ✅/❌ render as a different picture on every
   platform, and the whole point of this dialog is that the symbol is unambiguous. */
.notify-icon { width: 58px; height: 58px; margin: 2px auto 14px; }
.notify-icon svg { display: block; width: 100%; height: 100%; }
.notify-title { font-size: 17px; font-weight: 800; color: var(--text, #0f172a); margin: 0 0 6px; }
.notify-msg { font-size: 14.5px; line-height: 1.55; color: var(--text-2, #334155); margin: 0; }
.notify-detail {
  margin: 12px 0 0; padding: 10px 12px; text-align: start;
  background: var(--surface-2, #f1f5f9); border: 1px solid var(--border, #e2e8f0);
  border-radius: 10px; font-size: 13px; line-height: 1.6; color: var(--text-2, #475569);
  white-space: pre-wrap; word-break: break-word;
}
.notify-detail a { color: var(--brand-600, #4f46e5); font-weight: 600; }
.notify-count { margin-top: 8px; font-size: 12px; color: var(--text-3, #94a3b8); }
.notify-foot { margin-top: 18px; display: flex; gap: 10px; justify-content: center; }
.notify-foot .btn { min-width: 8.5rem; justify-content: center; }
@media (max-width: 420px) {
  .notify-card { padding: 20px 16px 14px; border-radius: 16px; }
  .notify-foot .btn { width: 100%; }
}

/* ---- "Work in progress" overlay --------------------------------------------------
   Shown while TRANSCRIBING or TRANSLATING, which are the two Studio operations
   that can run for minutes. Before this the only sign of life was a button
   label, so a long transcript looked exactly like a hang. */
.work-root {
  position: fixed; inset: 0; z-index: 190;
  display: flex; align-items: center; justify-content: center;
  padding: 16px; background: rgba(15, 23, 42, .5);
  animation: notify-fade .14s ease;
}
.work-root.hidden { display: none; }
.work-card {
  width: 100%; max-width: 25rem; background: #fff;
  border-radius: 18px; padding: 26px 22px 22px; text-align: center;
  box-shadow: 0 24px 60px rgba(15, 23, 42, .28);
  animation: notify-pop .18s cubic-bezier(.2, .9, .3, 1.2);
}
.work-gif { width: 84px; height: 84px; object-fit: contain; margin: 0 auto 12px; display: block; }
.work-title { font-size: 16.5px; font-weight: 800; color: var(--text, #0f172a); margin: 0 0 4px; }
.work-note { font-size: 13px; line-height: 1.5; color: var(--text-2, #475569); margin: 0; min-height: 2.6em; }
.work-track {
  margin-top: 16px; height: 8px; border-radius: 999px; overflow: hidden;
  background: var(--surface-2, #e2e8f0);
}
.work-fill {
  height: 100%; width: 0; border-radius: 999px;
  background: linear-gradient(90deg, var(--brand-500, #6366f1), var(--accent-500, #06b6d4));
  transition: width .35s ease;
}
/* No denominator available (a single blocking request): a moving stripe, which
   says "working" without pretending to know how far along it is. */
.work-track.is-indeterminate .work-fill {
  width: 40%; transition: none;
  background: linear-gradient(90deg, transparent, var(--brand-500, #6366f1), var(--accent-500, #06b6d4), transparent);
  animation: work-slide 1.15s linear infinite;
}
@keyframes work-slide { from { transform: translateX(-110%); } to { transform: translateX(280%); } }
.work-meta {
  margin-top: 10px; display: flex; justify-content: space-between; gap: 10px;
  font-size: 12px; font-weight: 600; color: var(--text-3, #94a3b8);
}
.work-pct { font-variant-numeric: tabular-nums; color: var(--brand-600, #4f46e5); }

/* ---- Watermark position grid & colour control ----------------------------------- */
.position-cell {
  height: 2.1rem; border: 1px solid var(--border-2); border-radius: .6rem; cursor: pointer;
  color: var(--text-2); font-weight: 600; background: #fff; transition: all .12s;
}
.position-cell:hover { border-color: var(--brand-400); }
.position-cell.active { background: var(--brand-600); border-color: var(--brand-600); color: #fff; }

.color-control { display: flex; align-items: center; gap: .5rem; width: 100%; }
.color-control .color-swatch {
  width: 2rem; height: 2rem; border-radius: .5rem; border: 1px solid var(--border-2);
  cursor: pointer; flex-shrink: 0; transition: transform .1s;
}
.color-control .color-swatch:hover { transform: scale(1.05); }
.color-control .color-hex {
  flex: 1; min-width: 0; border: 1px solid var(--border-2); border-radius: var(--r-md);
  padding: .45rem .55rem; font-size: .85rem; font-variant-numeric: tabular-nums;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.color-control .color-hex:focus { outline: none; border-color: var(--brand-500); box-shadow: 0 0 0 3px var(--brand-100); }
.color-control .color-native {
  width: 2.4rem; height: 2rem; border: 1px solid var(--border-2); border-radius: .5rem;
  padding: 0; background: transparent; cursor: pointer; flex-shrink: 0;
}

/* ---- KPIs / dashboard overview (Phase 2) ------------------------------------ */
.kpi-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 16px; }
/* The dashboard launchpad tiles. 2px and a mid-grey rather than the app's 1px
   hairline: these ten ARE the dashboard, and they have to read as ten buttons at
   a glance instead of as ten panels. `grid-auto-rows: 1fr` gives every row the
   height of the tallest tile, so all ten boxes are the SAME size at every width
   instead of one per row-height. */
.quick-actions { grid-auto-rows: 1fr; }
/* The row/icon layout is ALSO stated here, not only in the tile's inline style:
   anything that writes `el.style.display` on a tile (show/hide by plan) would
   otherwise drop the inline `display:flex` and the icon would jump on top of the
   label — which is exactly what happened to the plan-gated Watch Now tile. */
.quick-chip { border: 2px solid #cbd5e1 !important; box-shadow: var(--shadow-sm);
  display: flex; flex-direction: row; align-items: center; }
.quick-chip:hover { box-shadow: 0 10px 26px rgba(79,70,229,.2); }
.quick-ico { box-shadow: inset 0 0 0 1px rgba(79,70,229,.08); }
.chip-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 11px; border-radius: var(--r-pill);
  font-size: 12px; font-weight: 600; white-space: nowrap;
  background: var(--brand-50); color: var(--brand-600);
}
@media (max-width: 700px) {
  .dash-grid, #dashboardView > div:last-child { grid-template-columns: 1fr !important; }
}
/* Dashboard launchpad: on phones show a dense 2-column quick-tile grid so a
   writer can reach Compose / Photo Studio / Video Studio in one glance. */
@media (max-width: 560px) {
  .quick-actions {
    grid-template-columns: repeat(2, 1fr) !important;
    gap: 10px !important;
  }
  .quick-actions .quick-chip {
    padding: 12px !important;
    min-height: 112px !important;
    gap: 8px !important;
  }
  /* The icon slot has to be BORDER-box: without it the 40px here was 40px of
     CONTENT plus the 10px padding, i.e. a 60px icon in a 157px tile — the label
     was left ~89px and read as one word per line, which looked like the icon had
     been put on top of the words. `font-size` sizes the emoji to the box it is
     actually in (the glyph inherits it — see dashAction in shell.js). */
  .quick-actions .quick-chip .quick-ico {
    width: 40px !important; height: 40px !important;
    box-sizing: border-box !important;
    padding: 7px !important;
    font-size: 24px !important;
  }
}

/* ---- account platform picker (icon cards) -------------------------------- */
.plat-field .mb-3, .plat-field { display: block; }
.plat-picker { display: grid; grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); gap: 8px; }
.plat-pick {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 10px 6px; border: 1.5px solid var(--border-2); border-radius: var(--r-md);
  cursor: pointer; background: #fff; transition: border-color .15s, background .15s;
}
.plat-pick:hover { border-color: var(--brand-400); }
.plat-pick.selected { border-color: var(--brand-500); background: var(--brand-50); box-shadow: 0 0 0 3px var(--brand-100); }
.plat-pick img { width: 26px; height: 26px; object-fit: contain; }
.plat-pick .plat-pick-label { font-size: 12px; font-weight: 600; color: var(--text-2); }

/* ---- Platform connection guides ----------------------------------------------------
   Collapsible, context-aware "how to connect" panel shown next to each
   platform's connection form inside the Add/Edit account modal. The HTML body
   comes from the admin-editable platform_settings table. -------------------------- */
.platform-guide {
  background: var(--surface-2, #f1f5f9);
  border: 1px solid var(--border, #e2e8f0);
  border-radius: var(--r-md, 10px);
  padding: 12px 14px;
  margin: 0 0 12px;
  font-size: 13.5px;
  color: var(--text-2, #334155);
  line-height: 1.55;
}
.platform-guide h4 {
  margin: 0 0 8px;
  font-size: 14px;
  font-weight: 700;
  color: var(--text-1, #0f172a);
  display: flex;
  align-items: center;
  gap: 6px;
}
.platform-guide ol { margin: 0; padding: 0 0 0 18px; display: flex; flex-direction: column; gap: 4px; }
.platform-guide li { font-size: 13.5px; }
.platform-guide code {
  background: #fff;
  border: 1px solid var(--border, #e2e8f0);
  padding: 1px 6px;
  border-radius: 5px;
  font-size: 12.5px;
  color: var(--brand-600, #6366f1);
}
.platform-guide a { color: var(--brand-600, #6366f1); text-decoration: underline; }
.platform-guide .guide-tip,
.platform-guide .guide-warning {
  margin-top: 9px;
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 13px;
}
.platform-guide .guide-tip {
  background: rgba(99, 102, 241, 0.08);
  border-left: 3px solid var(--brand-500, #6366f1);
  color: var(--text-2, #334155);
}
.platform-guide .guide-warning {
  background: rgba(239, 68, 68, 0.08);
  border-left: 3px solid var(--danger, #dc2626);
  color: var(--danger, #dc2626);
}
.platform-guide-empty { display: none; }
/* "+ Tips" toggler under the platform fields (shows/hides the connection guide) */
.platform-guide-help {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--border, #e2e8f0);
}
.btn-guide-help {
  padding: 6px 14px; background: transparent;
  border: 1px solid var(--border, #e2e8f0); border-radius: 999px;
  font-size: 13px; font-weight: 600; color: var(--text-2, #334155);
  cursor: pointer; transition: all .15s; font-family: inherit;
}
.btn-guide-help:hover { background: var(--surface-2, #f1f5f9); border-color: var(--brand-400); }
.btn-guide-help.open { background: var(--brand-50, #eef2ff); border-color: var(--brand-500); color: var(--brand-600, #6366f1); }
.platform-guide.video-guide + .btn-guide-help { margin-top: 10px; }

/* ---- Floating "Tips" window ---------------------------------------------------
   The connection guide opens here instead of inline: a draggable, always-on-top
   panel the user can park anywhere and keep reading while they work through the
   steps in another tab/app. z-index sits above every modal (#modalRoot is z-80),
   the admin overlays (z-95) and the toasts (z-100). ---------------------------- */
.guide-win {
  position: fixed; left: auto; top: 88px; right: 24px;
  z-index: 130;
  display: none;               /* shown by openGuideWindow() */
  flex-direction: column;
  width: min(380px, calc(100vw - 24px));
  max-height: min(72vh, 560px);
  background: #fff;
  border: 1px solid var(--border, #e2e8f0);
  border-radius: 16px;
  box-shadow: 0 24px 60px rgba(15, 23, 42, .28), 0 2px 8px rgba(15, 23, 42, .12);
  overflow: hidden;
}
.guide-win-head {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px;
  background: linear-gradient(135deg, var(--brand-600, #4f46e5), var(--brand-500, #6366f1));
  color: #fff;
  cursor: grab;
  touch-action: none;          /* drag must not scroll the page on touch */
  user-select: none;
}
.guide-win-head.dragging { cursor: grabbing; }
.guide-win-ico { font-size: 15px; line-height: 1; }
.guide-win-title {
  flex: 1; min-width: 0;
  font-size: 13.5px; font-weight: 700;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.guide-win-close {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  border: none; cursor: pointer; font-size: 13px; line-height: 1;
  background: rgba(255, 255, 255, .18); color: #fff; font-family: inherit;
}
.guide-win-close:hover { background: rgba(255, 255, 255, .32); }
.guide-win-body {
  padding: 12px 14px 4px;
  overflow-y: auto;
  flex: 1; min-height: 0;
  -webkit-overflow-scrolling: touch;
}
.guide-win-body .platform-guide { margin: 0 0 10px; }
.guide-win-foot {
  flex: none;
  padding: 8px 14px 10px;
  border-top: 1px solid var(--border, #e2e8f0);
  background: var(--surface, #f8fafc);
  font-size: 11.5px; color: var(--text-3, #64748b);
}
.guide-win-state { font-size: 13px; color: var(--text-3, #64748b); margin-bottom: 8px; }
.guide-win-retry {
  padding: 5px 14px; border: 1px solid var(--border, #e2e8f0);
  border-radius: 999px; background: var(--surface-2, #f1f5f9);
  color: var(--text-2, #334155); font-size: 12.5px; font-weight: 600;
  cursor: pointer; font-family: inherit;
}
.guide-win-retry:hover { border-color: var(--brand-400); background: #fff; }
.platform-guide-help .btn-guide-help { font-weight: 700; }

/* ---- Pricing / plan cards (matched to the landing front page) --------------------- */
.upg-section-head { text-align: center; max-width: 640px; margin: 0 auto 36px; }
.upg-section-head h2 { font-size: clamp(28px,4vw,38px); letter-spacing:-0.01em; margin: 0 0 14px; }
.upg-section-head p { color: var(--text-2); font-size: 16.5px; margin: 0 0 20px; }
.upg-section-head .chips { display: flex; align-items: center; justify-content: center; gap: 12px; flex-wrap: wrap; }
.upg-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 20px; max-width: 1140px; margin: 0 auto; }
.price-card { background: #fff; border: 1px solid var(--border); border-radius: var(--r-lg); padding: 28px 24px; display: flex; flex-direction: column; gap: 16px; position: relative; box-shadow: var(--shadow-sm); }
.price-card.popular { border: 2px solid var(--brand-500); box-shadow: var(--shadow-brand); }
.popular-badge { position: absolute; top: -14px; left: 50%; transform: translateX(-50%); background: var(--brand-600); color: #fff; font-size: 12px; font-weight: 700; padding: 5px 14px; border-radius: var(--r-pill); }
.price-card .price-name { font-weight: 700; font-size: 17px; }
.price-card .price-amt { font-size: 40px; font-weight: 800; white-space: nowrap; }
.price-card .price-amt span { font-size: 16px; font-weight: 500; color: var(--text-3); }
.price-card ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.price-card ul li { display: flex; gap: 9px; align-items: flex-start; font-size: 14.5px; color: var(--text-2); }
.price-card ul li .tick { color: #16a34a; font-weight: 800; line-height: 1.2; }
.price-card .btn { margin-top: auto; }

/* ---- Admin pricing & tiers editor -------------------------------------------------- */
.tier-admin { width: 100%; min-width: 640px; border-collapse: collapse; table-layout: fixed; }
.tier-admin .cmp-wrap { overflow-x: auto; }
.tier-admin .row-label { white-space: nowrap; font-weight: 700; font-size: 14px; }
/* Keep every column on one line and give them room to breathe. */
.tier-admin th { white-space: nowrap; font-size: 12px; }
.tier-admin td, .tier-admin th { padding: 12px 9px; vertical-align: middle; }
/* Balanced, readable column widths so the table fits without cramping. */
.tier-admin th:nth-child(1), .tier-admin td:nth-child(1) { width: 74px; }
.tier-admin th:nth-child(2), .tier-admin td:nth-child(2) { width: 120px; }
.tier-admin th:nth-child(3), .tier-admin td:nth-child(3) { width: 108px; }
.tier-admin th:nth-child(4), .tier-admin td:nth-child(4) { width: 100px; }
.tier-admin th:nth-child(5), .tier-admin td:nth-child(5) { width: 90px; }
.tier-admin th:nth-child(6), .tier-admin td:nth-child(6) { width: auto; }
/* Medium separator line between each tier row. */
.tier-admin tbody tr { border-bottom: 2px solid var(--border-2); }
.tier-admin tbody tr:last-child { border-bottom: none; }
.tier-admin tbody tr:first-child { border-top: none; }
/* Features cell: a button with the selected-feature chips to its right. */
.tier-admin .tier-feat-wrap { display: flex; align-items: center; gap: 8px; min-width: 0; max-width: 430px; }
.tier-admin .tier-feat-btn {
  white-space: nowrap; flex: none; padding: 5px 10px; font-size: 12.5px;
}
.tier-admin .tier-feat-chips { display: flex; flex-wrap: wrap; gap: 5px; min-width: 0; }
.tier-admin .tier-feat-chip { max-width: 100%; }
.tier-admin .tier-feat-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 600;
  border: 1px solid; border-radius: var(--r-pill); padding: 3px 10px; white-space: nowrap;
}
.tier-admin .tier-feat-chip-check {
  font-style: normal; font-weight: 800; font-size: 11px; line-height: 1;
}
.tier-admin .tier-feat-chip-check::before { content: "✓"; }
.tier-admin .tier-feat-none { color: var(--text-3); font-size: 12.5px; white-space: nowrap; }
/* Feature picker modal body. */
.tier-feat-modal { min-width: 280px; }
.tier-feat-intro {
  margin: 0 0 12px; font-size: 12.5px; color: var(--text-3);
  text-transform: capitalize; font-weight: 600;
}
.tier-feat-actions { display: flex; gap: 10px; margin-top: 16px; }
/* Halo toggle rows (used inside the feature modal). */
.tier-feat-modal .feat-item {
  position: relative; display: flex; align-items: center; gap: 12px;
  font-size: 14px; color: var(--text-2); cursor: pointer; white-space: nowrap;
  padding: 8px 10px; border-radius: var(--r-md);
  transition: background .15s, box-shadow .15s;
}
.tier-feat-modal .feat-item + .feat-item { margin-top: 2px; }
.tier-feat-modal .feat-item:hover { background: var(--brand-50); }
.tier-feat-modal .feat-item .tier-feat {
  position: absolute; opacity: 0; width: 0; height: 0; margin: 0; pointer-events: none;
}
/* Halo indicator ring (mirrors .bulk-acc.on pattern) */
.tier-feat-modal .feat-halo {
  position: relative; flex: none; width: 22px; height: 22px; border-radius: 50%;
  border: 2px solid var(--border-2); background: #fff;
  display: flex; align-items: center; justify-content: center;
  transition: border-color .15s, box-shadow .15s, background .15s, transform .15s;
}
.tier-feat-modal .feat-dot { width: 0; height: 0; border-radius: 50%; background: #fff; transition: all .15s; }
.tier-feat-modal .feat-item:hover .feat-halo { border-color: var(--brand-400); }
.tier-feat-modal .feat-item .tier-feat:focus-visible + .feat-halo { box-shadow: 0 0 0 3px var(--brand-100); }
.tier-feat-modal .feat-item .tier-feat:checked + .feat-halo {
  border-color: var(--brand-600); background: var(--brand-600);
  box-shadow: 0 0 0 3px var(--brand-100), 0 2px 8px rgba(79,70,229,.35);
  transform: scale(1.06);
}
.tier-feat-modal .feat-item .tier-feat:checked + .feat-halo .feat-dot {
  width: 8px; height: 8px; background: #fff;
}
.tier-feat-modal .feat-text { line-height: 1.2; }
.tier-feat-modal .feat-item .tier-feat:checked ~ .feat-text { color: var(--brand-700); font-weight: 600; }

/* ---- Mobile bottom tab bar ----------------------------------------------------------
   Shown only <= 860px (when the left sidebar collapses to an off-canvas drawer).
   Offers instant one-tap access to the highest-value destinations plus a central
   "+ Create" action that opens a Compose / Photo Studio / Video Studio quick sheet. */
.mobile-bottom-nav {
  display: none; /* desktop: never shown */
  flex: none;
}
@media (max-width: 860px) {
  .mobile-bottom-nav {
    display: block;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 64;
    background: rgba(255,255,255,.97);
    -webkit-backdrop-filter: saturate(140%) blur(8px); backdrop-filter: saturate(140%) blur(8px);
    border-top: 1px solid var(--border);
    box-shadow: 0 -6px 18px rgba(15,23,42,.06);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .mb-nav-wrap {
    display: grid;
    grid-template-columns: 1fr 1fr auto 1fr 1fr;
    align-items: stretch;
    max-width: 520px; margin: 0 auto;
  }
  .mb-tab {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 2px; padding: 8px 2px 7px; border: none; background: transparent;
    font-size: 10.5px; font-weight: 600; color: var(--text-3); cursor: pointer;
    line-height: 1.1; transition: color .12s;
  }
  .mb-tab .mb-ico { font-size: 19px; line-height: 1; }
  .mb-tab.active { color: var(--brand-600); }
  .mb-create {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    border: none; cursor: pointer; background: transparent; padding: 4px 0 0;
  }
  .mb-create .mb-create-btn {
    width: 48px; height: 48px; margin-top: -18px; border-radius: 50%;
    border: 4px solid #fff; background: linear-gradient(135deg, var(--brand-500), var(--accent-500, #ec4899));
    color: #fff; font-size: 22px; line-height: 1; display: flex; align-items: center;
    justify-content: center; box-shadow: 0 6px 16px rgba(79,70,229,.35);
  }
  .mb-create:active .mb-create-btn { transform: scale(.95); }
  /* Keep page/layout clear of the fixed bottom bar */
  .app-content { padding-bottom: 96px; }

  /* Compose/Bulk: pin the primary Send/Schedule bar above the bottom nav so a
     mobile writer never has to scroll past accounts to post. Reuses the same
     #sendActions element (single ID, single handler) — desktop stays inline. */
  .app-shell .app-main #sendActions {
    position: fixed;
    left: 0; right: 0;
    bottom: calc(64px + env(safe-area-inset-bottom, 0px));
    z-index: 50;
    margin: 0 !important;
    padding: 10px 14px calc(10px + env(safe-area-inset-bottom, 0px));
    background: rgba(255,255,255,.97);
    -webkit-backdrop-filter: saturate(140%) blur(8px); backdrop-filter: saturate(140%) blur(8px);
    border-top: 1px solid var(--border);
    box-shadow: 0 -6px 18px rgba(15,23,42,.06);
  }
  /* Ensure the last account toggle is never hidden behind the pinned bar. */
  .app-shell .app-main #sendToBody { padding-bottom: 84px; }
  /* Studio step bars (Video .st-navbar / Photo .photos-navbar): lift them above
     the fixed bottom tab bar on phones so Previous/Next stay reachable. */
  .app-main .st-navbar,
  .app-main .photos-navbar {
    bottom: calc(64px + env(safe-area-inset-bottom, 0px));
  }
}

/* "+ Create" quick-action sheet (mobile only) */
.create-sheet-veil {
  display: none; position: fixed; inset: 0; z-index: 70;
  background: rgba(15,23,42,.45);
}
.create-sheet-veil.open { display: block; }
.create-sheet {
  position: absolute; left: 0; right: 0; bottom: 0; max-width: 520px; margin: 0 auto;
  background: #fff; border-radius: 18px 18px 0 0; padding: 8px 16px calc(16px + env(safe-area-inset-bottom,0px));
  box-shadow: 0 -10px 40px rgba(15,23,42,.18);
}
.create-sheet .cs-head {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 15px; font-weight: 800; color: var(--text); padding: 10px 2px 12px;
}
.create-sheet .cs-act {
  display: flex; align-items: center; gap: 14px; width: 100%;
  padding: 12px 14px; margin-bottom: 8px; border: 1px solid var(--border);
  border-radius: 14px; background: #fff; cursor: pointer; text-align: left;
  font: inherit; color: var(--text); transition: background .12s, border-color .12s;
}
.create-sheet .cs-act:active { background: var(--surface-2); border-color: var(--border-2); }
.create-sheet .cs-act .cs-ico {
  width: 42px; height: 42px; border-radius: 12px; flex: none;
  display: flex; align-items: center; justify-content: center; font-size: 20px;
  background: var(--brand-50); color: var(--brand-600);
}
/* Menu-style SVG glyphs inside the Create sheet size bigger than the compact
   shared 22px slot so they read clearly in the 42px rounded icon chip. */
.create-sheet .cs-act .cs-ico img {
  width: 30px; height: 30px; object-fit: contain; display: block; flex: none;
}

/* ---- Media Library bulk action bar ---------------------------------------
   A floating bar that stays in view while the library is scrolled, so acting on a
   selection never means scrolling back to the top to find the buttons.

   `position: sticky` (not fixed) on purpose: it stays IN FLOW, so it cannot cover
   the last row of files the way a fixed bar would, and it needs no spacer element
   to reserve its height.

   Two structural rules make that work, both in shell.js:
     * the bar is a SIBLING of the panel card, inside `.media-bulk-host`. The card is
       `overflow: hidden` to clip its rounded corners, and a sticky child of an
       overflow-hidden box is positioned against a box that never scrolls — it would
       not move at all;
     * the host WRAPS the card as well as the bar, so the bar's containing block is
       taller than the bar. A sticky element can never move outside its containing
       block, so a host holding only the bar could not stick either.

   Layout: the selection PILL on the left, the actions pushed right. The pill is
   the one thing that changes as boxes are ticked, and "3" alone said nothing —
   it reads "3 images selected". */
.media-bulk-bar {
  position: sticky; bottom: 14px; z-index: 22;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 14px 0 2px; padding: 10px 12px;
  border: 1px solid var(--border); border-radius: 18px;
  background: rgba(255,255,255,.96);
  -webkit-backdrop-filter: saturate(160%) blur(10px);
  backdrop-filter: saturate(160%) blur(10px);
  box-shadow: 0 14px 34px rgba(15,23,42,.18);
}
/* The markup sets `hidden` when nothing is ticked; a plain display:flex rule would
   override the browser's [hidden] { display: none }, which is how a "hidden" bar
   ends up on screen. */
.media-bulk-bar[hidden] { display: none; }
.media-sel-pill {
  flex: none; font-size: 12.5px; font-weight: 700; line-height: 1;
  padding: 8px 13px; border-radius: 999px; white-space: nowrap;
  color: var(--brand-700); background: var(--brand-50);
  border: 1px solid var(--brand-100);
}
.media-bulk-actions {
  display: flex; flex-wrap: wrap; gap: 8px;
  /* inline-start, not `left`: the actions belong at the END of the bar in BOTH
     directions, which is the right edge in English and the left edge in Farsi. The
     physical property happens to give the same result today, but it would break the
     moment the bar's own direction differed from the page's. */
  margin-left: auto;
  margin-inline-start: auto;
}
.media-bulk-actions .media-bulk-act {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  white-space: nowrap; min-height: 38px;
}
/* Phones: the words go, the icons stay — and each button keeps a 44px touch
   target. Sitting `bottom` above the fixed bottom tab bar (56px + its safe-area
   inset) is what stops the two bars from stacking on top of each other. */
@media (max-width: 640px) {
  .media-bulk-bar {
    bottom: calc(72px + env(safe-area-inset-bottom, 0px));
    gap: 8px; padding: 8px; border-radius: 16px;
  }
  .media-bulk-act .mb-lbl { display: none; }
  .media-bulk-actions { gap: 6px; }
  .media-bulk-actions .media-bulk-act { min-width: 44px; min-height: 44px; font-size: 17px; padding: 0 10px; }
  .media-sel-pill { font-size: 11.5px; padding: 7px 11px; }
}
.create-sheet .cs-txt { flex: 1; min-width: 0; }
.create-sheet .cs-txt b { font-size: 14.5px; display: block; }
.create-sheet .cs-txt span { font-size: 12px; color: var(--text-3); }

/* ---- Responsive ------------------------------------------------------------------- */
/* Mobile: off-canvas drawer + a scrim to close it, and clearance so the
   drawer's Logout (and other bottom items) sit above the fixed bottom nav. */
.sidebar-scrim {
  display: none; position: fixed; inset: 0; z-index: 56;
  background: rgba(15,23,42,.4); backdrop-filter: blur(1px);
  -webkit-backdrop-filter: blur(1px);
}
@media (max-width: 860px) {
  .sidebar { transform: translateX(-100%); z-index: 62; }
  .sidebar.open { transform: translateX(0); z-index: 62; }
  .app-main { margin-left: 0; }
  /* RTL: the drawer is anchored to the RIGHT (see the [dir="rtl"] rule above), so
     it must slide in from that edge — translateX(-100%) would fling it further off
     the LEFT and out of view, leaving a menu that never appears. */
  [dir="rtl"] .sidebar { transform: translateX(100%); }
  [dir="rtl"] .sidebar.open { transform: translateX(0); }
  [dir="rtl"] .app-main { margin-right: 0; }
  /* Compact sides/top, but keep a generous bottom so content (lists, Logout,
     studio cards, "Clear All") always scrolls clear of the fixed bottom nav
     and the sticky studio step bars instead of being clipped underneath. */
  .app-content { padding: 18px 18px 120px; }
  .hamburger { display: inline-flex !important; z-index: 65; position: relative; }
  .sidebar.open ~ .sidebar-scrim { display: block; }
  /* Let the drawer's bottom actions scroll clear of the fixed bottom tab bar. */
  #sidebar .sb-foot {
    padding-bottom: calc(70px + env(safe-area-inset-bottom, 0px));
  }
  /* Extra safe cushion at the very bottom of tall scrollables so the last row
     of a Video Studio project grid / Photo selection is never covered. */
  .studio-grid, #photoEditorView .pe-grid { padding-bottom: 12px; }
  /* Dashboard: split "Upcoming scheduled posts" / "Recent activity" 50/50 on
     mobile (desktop keeps its 2/3–1/3 emphasis on upcoming). */
  .dash-bottom-grid { grid-template-columns: 1fr 1fr !important; }
}

/* ---- i18n / language toggle + RTL ------------------------------------------------ */
.i18n-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 34px; height: 34px; padding: 0 8px; border: 1px solid var(--border-2);
  border-radius: var(--r-pill); background: #fff; cursor: pointer;
  font-size: 14px; font-weight: 700; color: var(--text-2);
  transition: all .15s; line-height: 1;
}
.i18n-toggle:hover { border-color: var(--brand-400); color: var(--brand-600); box-shadow: var(--shadow-sm); }

body.is-fa { letter-spacing: 0 !important; }
body.is-fa .price-amt, body.is-fa .kpi-row, body.is-fa .price-amt span { letter-spacing: 0 !important; }

[dir="rtl"] .plan-strip { flex-direction: row-reverse; }

/* =========================================================================
   Unified Inbox — premium two-panel design (Hootsuite/Buffer-inspired)
   ========================================================================= */
.skeleton {
  display: inline-block; border-radius: 6px;
  background: linear-gradient(90deg, #eef2f7 25%, #f6f8fb 37%, #eef2f7 63%);
  background-size: 400% 100%;
  animation: inbox-shimmer 1.2s ease infinite;
}
@keyframes inbox-shimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

/* Filter tabs (All / Open / Resolved) */
.inbox-tabs { display: flex; gap: 2px; }
.inbox-tab {
  position: relative; background: none; border: none; padding: 8px 6px 10px;
  font-size: 13px; font-weight: 600; color: var(--text-3); cursor: pointer;
  transition: color .12s; display: inline-flex; align-items: center; gap: 5px;
}
.inbox-tab:hover { color: var(--text-2); }
.inbox-tab.active { color: var(--brand-600); }
.inbox-tab.active::after {
  content: ""; position: absolute; left: 4px; right: 4px; bottom: -1px; height: 2px;
  background: var(--brand-600); border-radius: 2px;
}

/* Platform dot filters */
.inbox-plat {
  width: 28px; height: 28px; border-radius: 50%!important; border: 1px solid var(--border)!important;
  background: #fff!important; display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; padding: 0; transition: all .12s;
}
.inbox-plat:hover { box-shadow: 0 0 0 2px var(--border-2); }
.inbox-plat.active { border-color: var(--brand-600)!important; box-shadow: 0 0 0 2px var(--brand-100); background: var(--brand-50)!important; }

/* Platform filter pills on the Accounts page (under "Connected Accounts") */
.acct-fplat {
  border: 1px solid var(--border); background: #fff; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px;
  border-radius: 999px; font-size: 13px; font-weight: 600; color: var(--text-2);
  font-family: inherit; transition: all .12s; line-height: 1;
}
.acct-fplat img { width: 16px; height: 16px; object-fit: contain; flex: none; }
.acct-fplat:hover { border-color: var(--border-2); box-shadow: 0 0 0 2px var(--border-2); }
.acct-fplat.active { border-color: var(--brand-600)!important; box-shadow: 0 0 0 2px var(--brand-100); background: var(--brand-50)!important; color: var(--brand-600)!important; }

/* Conversation list */
.inbox-2pane { height: calc(100vh - 230px); }
.inbox-2pane > .card { min-height: 0; }
.inbox-list { background: #fff; }
.inbox-row:hover { background: var(--surface-2); }
.inbox-row { position: relative; }
.inbox-row:hover .inbox-more { opacity: 1 !important; }

/* Thread bubbles area scaffold */
.inbox-thread { }
.inbox-thread > [data-thread-sticky] { position: sticky; top: 0; z-index: 5; background: #fff; }

/* Empty-state inner */
.inbox-empty-pad { padding: 48px 16px; }

/* Chat scrollbar (subtle) */
.inbox-list::-webkit-scrollbar, .inbox-thread::-webkit-scrollbar { width: 6px; }
.inbox-list::-webkit-scrollbar-thumb, .inbox-thread::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 999px; }

/* Responsive: tablet → list narrower; mobile → single column/tap-to-thread */
@media (min-width: 768px) and (max-width: 1024px) {
  .inbox-2pane { grid-template-columns: minmax(220px, 25%) minmax(0, 1fr) !important; }
}
@media (max-width: 767px) {
  .inbox-2pane { grid-template-columns: 1fr !important; }
  /* Left panel full width; right thread hidden until a conversation is tapped.
     On mobile we simply stack them (thread below) so nothing is lost. */
  .inbox-list-card { max-height: 46vh !important; }
}

/* RTL: flip bubble corners + alignment naturally via flex; ensure text-align */
[dir="rtl"] .inbox-row { text-align: right; }

[dir="rtl"] .quick-actions { direction: rtl; }

/* ---- Sticky red-circle close for modals / popups ------------------------- */
/* Makes the header (and its X close) stick to the top of the scrollable
   popup so it stays visible when the content is scrolled down. */
.modal-head {
  position: sticky;
  top: 0;
  z-index: 30;                 /* stays above the scrolling body */
  background: #fff;            /* opaque so body text scrolls beneath it */
  border-radius: 16px 16px 0 0;
}
/* The X close button: a red circle with a white cross */
.modal-close {
  display: inline-flex; align-items: center; justify-content: center;
  flex: none; width: 28px; height: 28px; border: none; border-radius: 50%;
  background: #ef4444; color: #fff;
  font-size: 15px; font-weight: 700; line-height: 1; cursor: pointer;
  transition: background .15s, transform .15s;
  padding: 0;
}
.modal-close:hover { background: #dc2626; transform: scale(1.08); }
.modal-close:active { transform: scale(.96); }

/* ---- Admin Users list: hide the secondary "phone · joined · sent · tier"
   meta line on small screens so RTL rows stay tidy ------------------------ */
@media (max-width: 700px) {
  .au-meta { display: none !important; }
}

/* =========================================================================
   Pricing & Tiers admin — modern plan-card dashboard (dynamic tiers)
   ========================================================================= */
.btn-pill { border-radius: 999px !important; padding: 8px 18px !important; font-weight: 700 !important; }
.btn-pill small { font-weight: 500; opacity: .8; }

/* Row of plan cards + trailing "Add plan" tile */
.tcard-row {
  display: flex; gap: 16px; align-items: stretch;
  overflow-x: auto; padding: 6px 2px 16px;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
}
@media (min-width: 860px) {
  .tcard-row { flex-wrap: wrap; }
}
.tcard {
  flex: 0 0 auto; width: 280px; max-width: 92vw;
  min-height: 300px; scroll-snap-align: start;
  background: #fff; border: 1px solid var(--border);
  border-radius: 18px; padding: 16px 16px 14px;
  box-shadow: 0 1px 2px rgba(15,23,42,.05);
  display: flex; flex-direction: column; gap: 10px;
  transition: transform .14s ease, box-shadow .16s ease, opacity .15s ease;
  position: relative;
}
.tcard.dragging { opacity: .45; }
.tcard:hover { transform: translateY(-3px); box-shadow: 0 10px 24px rgba(15,23,42,.1); }
.tcard.muted { opacity: .55; }
.tcard-active { border-color: #1b74bc; box-shadow: 0 4px 16px rgba(27,116,188,.14); }
.tcard-free { border-color: #27ae60; }
.tcard.custom { border-style: dashed; }
.tcard .tcard-drag { position: absolute; top: 10px; left: 10px; cursor: grab; color: #cbd5e1; font-size: 14px; user-select: none; }
.tcard .tcard-badge-top { position: absolute; top: 10px; right: 10px; }
.tcard-popular-badge {
  display: inline-block; background: linear-gradient(135deg, #ffb347, #ff8c1a);
  color: #fff; font-size: 10.5px; font-weight: 800; letter-spacing: .2px;
  padding: 3px 9px; border-radius: 999px; box-shadow: 0 2px 6px rgba(255,140,26,.35);
}
.tcard .tcard-name { font-size: 17px; font-weight: 800; color: var(--text-1,#0f172a); display: flex; align-items: center; gap: 8px; }
.tcard .tcard-price { display: flex; align-items: baseline; gap: 6px; }
.tcard .tcard-price b { font-size: 26px; font-weight: 900; color: #1b74bc; letter-spacing: -.4px; }
.tcard .tcard-price small { color: var(--text-3); font-size: 12px; font-weight: 600; }
.tcard .tcard-pills { display: flex; flex-wrap: wrap; gap: 6px; }
.tcard .tc-pill {
  display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 700;
  padding: 4px 10px; border-radius: 999px; background: var(--surface-2,#f1f5f9);
  color: var(--text-2); border: 1px solid var(--border);
}
.tcard .tc-pill .em { font-size: 13px; }
.tcard-feats { margin-top: 2px; border-top: 1px dashed var(--border); padding-top: 8px; }
.tcard-feat {
  display: flex; align-items: center; gap: 9px; font-size: 12.5px; color: var(--text-2);
  padding: 3px 6px; border-radius: 7px; cursor: pointer; user-select: none;
}
.tcard-feat:hover { background: var(--surface); }
.tcard-feat .tmark { width: 17px; height: 17px; flex: none; display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; font-size: 11px; font-weight: 800; }
.tcard-feat.on .tmark { background: #27ae60; color: #fff; }
.tcard-feat.off { color: #cbd5e1; }
.tcard-feat.off .tmark { background: #eef2f6; color: #c0c7d1; }
.tcard-foot { margin-top: auto; display: flex; gap: 6px; flex-wrap: wrap; }
.tcard-foot .btn { flex: 1 1 auto; }
.tcard-add {
  flex: 0 0 auto; width: 200px; min-height: 300px; align-items: center; justify-content: center;
  border: 2px dashed var(--border-2); background: transparent; border-radius: 18px;
  color: var(--text-2); cursor: pointer; display: flex; flex-direction: column; gap: 8px;
  font-weight: 800; font-size: 15px; transition: all .15s;
}
.tcard-add:hover { border-color: #27ae60; color: #27ae60; background: rgba(39,174,96,.05); }
.tcard-add .plus { font-size: 30px; line-height: 1; }

/* Inline small number nudges on cards */
.tcard .tcard-bar .tc-big { font-weight:800; color: var(--text-1); }

/* Switch used on tier cards (kept inline for state, this adds polish) */
.tcard-sw {
  width: 44px; height: 24px; border-radius: 999px; border: none; display: inline-block;
  position: relative; cursor: pointer; vertical-align: middle; transition: background .15s;
}
.tcard-sw .knob { position: absolute; top: 2px; width: 20px; height: 20px; border-radius: 50%; background:#fff; box-shadow: 0 1px 2px rgba(0,0,0,.2); }
.tcard-sw[data-on="1"] { background: linear-gradient(180deg,#22c55e,#16a34a); }
.tcard-sw[data-on="1"] .knob { right: 2px; }
.tcard-sw[data-on="0"] { background: #e2e8f0; }
.tcard-sw[data-on="0"] .knob { left: 2px; }

/* =========================================================================
   Admin Users — mobile-first card dashboard
   ========================================================================= */
.au-toolbar {
  position: sticky; top: 62px; z-index: 20;
  background: #f8fafc;
  padding: 10px 0 4px;
  display: flex; flex-direction: column; gap: 8px;
}
.au-toolbar-main { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.au-toolbar-main input#adminUsersSearch { flex: 1; min-width: 150px; }
.au-toolbar-main .spacer { flex: 1; }
.au-toolbar-filters { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.au-toolbar-filters .au-res-count { font-size: 12px; color: var(--text-3); margin-inline-start: auto; white-space: nowrap; }
.au-fsel { font-size: 13px; padding: 6px 9px; border: 1px solid var(--border); border-radius: 999px; background: #fff; color: var(--text-1); cursor: pointer; }

/* ---- multi-column sort button + its popover ------------------------------
   The panel is positioned by JS in VIEWPORT coordinates (position:fixed) and
   only its INSIDE is styled here: the filters row wraps, so the button can land
   at either edge and an `inset-inline-end` anchor would run off the screen. */
.au-sortbtn { display: inline-flex; align-items: center; gap: 6px; max-width: 240px; }
.au-sortbtn-i { font-size: 12px; flex: none; }
.au-sortbtn #adminUsersSortLabel { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.au-sortbtn.on { border-color: var(--brand-600, #4f46e5); color: var(--brand-600, #4f46e5); font-weight: 700; }
.au-sortpop { position: fixed; z-index: 90; background: #fff; border: 1px solid var(--border);
  border-radius: 14px; box-shadow: 0 12px 32px rgba(15, 23, 42, .16); padding: 8px;
  font-size: 13px; overflow-y: auto; }
.au-sortpop-h { font-size: 11px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text-3); padding: 3px 8px 2px; }
.au-sortpop-note { font-size: 11.5px; line-height: 1.45; color: var(--text-3); padding: 0 8px 7px; }
.au-sortpop-list { display: flex; flex-direction: column; gap: 2px; }
.au-sortrow { display: flex; align-items: center; gap: 6px; padding: 5px 8px; border-radius: 9px;
  background: var(--brand-50, #eef2ff); }
.au-sortadd { display: flex; align-items: center; gap: 6px; padding: 6px 8px; border-radius: 9px;
  background: none; border: none; font: inherit; color: var(--text-1); text-align: start; cursor: pointer; }
.au-sortadd:hover { background: #f1f5f9; }
.au-sortrank { flex: none; width: 20px; height: 20px; border-radius: 50%; background: var(--brand-600, #4f46e5);
  color: #fff; font-size: 11px; font-weight: 800; display: flex; align-items: center; justify-content: center; }
.au-sortrank.au-plus { background: #e2e8f0; color: var(--text-3); font-weight: 700; }
.au-sortname { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.au-sortdef { flex: none; font-size: 12px; color: var(--text-3); }
.au-sortdir, .au-sortmv, .au-sortdel { flex: none; border: 1px solid var(--border); background: #fff;
  color: var(--text-2); border-radius: 7px; cursor: pointer; font-size: 11px; line-height: 1; padding: 3px 6px; }
.au-sortdir[aria-pressed="true"] { color: var(--brand-600, #4f46e5); border-color: var(--brand-600, #4f46e5); }
.au-sortmv:disabled { opacity: .35; cursor: default; }
.au-sortdel:hover { color: #b91c1c; border-color: rgba(185, 28, 28, .5); }
.au-sortpop-sep { height: 1px; background: var(--border); margin: 6px 4px; }
.au-sortpop-empty { font-size: 12px; color: var(--text-3); padding: 6px 8px; }
.au-sortpop-f { display: flex; justify-content: flex-end; padding: 6px 4px 2px; }
.au-sortreset { border: none; background: none; font: inherit; font-size: 12px; font-weight: 700;
  color: var(--brand-600, #4f46e5); padding: 4px 7px; border-radius: 7px; cursor: pointer; }
.au-sortreset:hover { background: var(--brand-50, #eef2ff); }

.au-grid {
  display: grid; gap: 12px;
  grid-template-columns: 1fr;
}
@media (min-width: 640px) { .au-grid { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (min-width: 1080px) { .au-grid { grid-template-columns: repeat(3, minmax(0,1fr)); } }
@media (min-width: 1500px) { .au-grid { grid-template-columns: repeat(4, minmax(0,1fr)); } }

.au-card {
  background: #fff; border: 1px solid var(--border); border-radius: 16px;
  padding: 14px; display: flex; flex-direction: column; gap: 10px;
  box-shadow: 0 1px 2px rgba(15,23,42,.04);
  transition: box-shadow .15s ease, transform .12s ease;
}
.au-card:hover { box-shadow: 0 8px 22px rgba(15,23,42,.10); transform: translateY(-1px); }
.au-card.suspended { opacity: .62; }
.au-card-top { display: flex; align-items: center; gap: 12px; }
.au-avatar {
  width: 44px; height: 44px; border-radius: 50%; flex: none;
  background: linear-gradient(135deg, #1b74bc, #2f8fd6); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 17px; letter-spacing: .3px;
}
.au-id { }
.au-id .nm { font-weight: 800; font-size: 15px; color: var(--text-1,#2c3e50); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.au-id .em { font-size: 12.5px; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.au-status { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 700; }
.au-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }

/* ---- "logged in right now" ------------------------------------------------
   The headline count doubles as the filter: the pill above the toolbar shows how
   many sessions are live and toggles the list down to those users, so the figure
   an admin wants to act on IS the control that shows it. Same green as the
   Active dot, so "online" and "active" read as related but not identical. */
.au-online-bar { margin: 0 0 10px; }
.au-online-chip {
  display: inline-flex; align-items: center; gap: 7px;
  font: inherit; font-size: 13px; font-weight: 700; color: var(--text-1);
  background: #fff; border: 1px solid var(--border); border-radius: 999px;
  padding: 6px 13px; cursor: pointer;
  transition: background .12s, border-color .12s, box-shadow .12s;
}
.au-online-chip b { font-variant-numeric: tabular-nums; font-size: 14px; }
.au-online-chip:hover { border-color: rgba(39,174,96,.6); background: #f2fbf5; }
.au-online-chip.on {
  color: #14663a; background: #e8f8ee; border-color: #27ae60;
  box-shadow: inset 0 0 0 1px rgba(39,174,96,.35);
}
/* The inline pill inside a row / card. Same shape as `.au-status` so a row does
   not grow a second kind of blob, but green-tinted so it is not mistaken for the
   Active/Suspended status next to it. */
.au-online {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; font-weight: 700; color: #14663a;
  background: #e8f8ee; border: 1px solid rgba(39,174,96,.35);
  border-radius: 999px; padding: 1px 8px; white-space: nowrap; margin-inline-start: 6px;
}
/* The list row was tuned to keep a whole user on one 60px line (see the
   `.au-row` note), and this pill is one more thing in that line, so it is trimmed
   there: same word, less padding. Below ~845px the row's own flex-wrap moves the
   actions to a second line — the designed degradation. */
.au-row .au-online { font-size: 10.5px; padding: 0 6px; margin-inline-start: 4px; gap: 4px; }
.au-stats { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 12px; color: var(--text-2); }
.au-stats b { color: var(--text-1); }
.au-foot { display: flex; flex-wrap: wrap; gap: 6px; margin-top: auto; }
.au-foot .btn { flex: 1 1 auto; }

/* The two counters an admin scans for — ✉ messages sent and 📷 media processed.
   Drawn as inline SVG (not emoji) so they sit optically level with the label at
   any font size, and use the brand colour so each figure reads as one unit. */
.au-i { vertical-align: -2px; flex: none; }
.au-stat { display: inline-flex; align-items: center; gap: 4px; font-size: 12.5px; color: var(--text-2); white-space: nowrap; }
.au-stat b { color: var(--text-1); font-variant-numeric: tabular-nums; }
.au-stat .au-i { color: #1b74bc; }
.au-stat-l { font-size: 11.5px; color: var(--text-3); }
.au-stats-counts { gap: 6px 18px; }
.au-stats-counts .au-stat { font-size: 13px; }

/* ---- how the list is laid out: card grid <-> one user per line ----------- */
.au-view {
  display: inline-flex; border: 1px solid var(--border); border-radius: 999px;
  overflow: hidden; background: #fff;
}
.au-view-btn {
  border: 0; background: transparent; color: var(--text-2); font: inherit;
  font-size: 13px; line-height: 1; padding: 6px 11px; cursor: pointer;
  transition: background .12s, color .12s;
}
.au-view-btn + .au-view-btn { border-inline-start: 1px solid var(--border); }
.au-view-btn:hover { background: var(--surface); color: #1b74bc; }
.au-view-btn.on { background: linear-gradient(135deg, #1b74bc, #2f8fd6); color: #fff; font-weight: 700; }

/* ---- list view: the same rows, stacked ----------------------------------- */
.au-list { display: flex; flex-direction: column; gap: 8px; }
.au-row {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: #fff; border: 1px solid var(--border); border-radius: 14px;
  padding: 10px 14px; box-shadow: 0 1px 2px rgba(15,23,42,.04);
  transition: box-shadow .15s ease, transform .12s ease;
}
.au-row:hover { box-shadow: 0 6px 18px rgba(15,23,42,.09); transform: translateY(-1px); }
.au-row.suspended { opacity: .62; }
.au-avatar-sm { width: 38px; height: 38px; font-size: 15px; }
.au-row-id { flex: 1 1 150px; min-width: 120px; }
.au-row-id .nm { font-weight: 800; font-size: 14px; color: var(--text-1); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.au-row-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.au-row-id .em { font-size: 12.5px; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.au-row-status { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.au-row-stats { display: flex; align-items: center; gap: 12px; flex: 0 0 auto; }
/* In the list the ICONS carry the meaning: the word labels would double the
   width of the two counters a scanner is reading, and there is a tooltip on each.
   The card view keeps them, where there is room to spell them out. */
.au-row .au-stat-l { display: none; }
.au-row-meta { display: flex; flex-direction: column; gap: 2px; font-size: 11.5px; color: var(--text-3); flex: 0 0 auto; min-width: 126px; }
.au-row-meta span { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.au-row-acts { display: flex; align-items: center; gap: 6px; margin-inline-start: auto; }
/* Narrow: the line becomes two or three lines rather than squeezing the
   counters into an unreadable column. */
@media (max-width: 860px) {
  .au-row { align-items: flex-start; }
  .au-row-meta { flex-direction: row; gap: 12px; min-width: 0; }
  .au-row-acts { margin-inline-start: 0; }
}

/* Plan badge colors (Free gray / paid blue-purple / advanced gold / ent dark) */
.au-pill { font-size: 10.5px; font-weight: 800; border-radius: 999px; padding: 2px 9px; white-space: nowrap; }
/* The plan's expiry date, beside the badge. Red on purpose: a subscription about
   to lapse is the one thing on the row an admin should notice unprompted. Only
   drawn when the server sent a date, so a free plan shows the bare badge. */
.au-exp { color: #dc2626; font-size: 11px; font-weight: 800; white-space: nowrap; }

.au-pager { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 14px; }
.au-pager .p-btn {
  border: 1px solid var(--border); background: #fff; color: var(--text-2);
  border-radius: 8px; padding: 5px 11px; font-size: 13px; cursor: pointer;
}
.au-pager .p-btn.on { background: #1b74bc; color: #fff; border-color: #1b74bc; font-weight: 700; }
.au-pager .p-btn:disabled { opacity: .4; cursor: default; }

.autofab {
  position: fixed; right: 18px; bottom: 76px; z-index: 55;
  width: 54px; height: 54px; border-radius: 50%;
  background: linear-gradient(135deg, #1b74bc, #2f8fd6); color: #fff; border: none;
  font-size: 26px; line-height: 1; display: none; align-items: center; justify-content: center;
  box-shadow: 0 6px 18px rgba(27,116,188,.4); cursor: pointer;
}
@media (max-width: 700px) { .autofab { display: flex; } }

/* =========================================================================
   Admin → Orders

   One table, built to be scanned: the person's name leads, the money shows the
   discount rather than hiding it, and the row's own action is the only colour on
   it. Colours come from the tokens so this follows an admin theme change.
   ========================================================================= */
.ord-stats {
  display: grid; gap: 10px; margin: 0 0 14px;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
.ord-stat {
  background: #fff; border: 1px solid var(--border); border-radius: 14px;
  padding: 12px 14px; box-shadow: 0 1px 2px rgba(15,23,42,.04);
  border-inline-start: 4px solid var(--brand-500, #6366f1);
}
.ord-stat.warn { border-inline-start-color: #d97706; }
.ord-stat.ok { border-inline-start-color: #16a34a; }
.ord-stat-l { font-size: 11.5px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; color: var(--text-3); }
.ord-stat-v { font-size: 22px; font-weight: 800; line-height: 1.15; margin-top: 3px; color: var(--text-1); }
.ord-stat-s { font-size: 11.5px; color: var(--text-3); margin-top: 3px; line-height: 1.35; }

.ord-bar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin: 0 0 12px; }
.ord-filters { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.ord-chip {
  border: 1px solid var(--border); background: #fff; color: var(--text-2);
  border-radius: 999px; padding: 5px 12px; font-size: 12.5px; cursor: pointer;
  font-family: inherit; transition: background .12s, border-color .12s;
}
.ord-chip:hover { border-color: var(--brand-500, #6366f1); }
.ord-chip b { font-weight: 800; margin-inline-start: 2px; }
.ord-chip.active { background: var(--brand-600, #4f46e5); border-color: var(--brand-600, #4f46e5); color: #fff; font-weight: 700; }
.ord-search { position: relative; flex: 1; min-width: 190px; }
.ord-search-ico { position: absolute; inset-inline-start: 10px; top: 50%; transform: translateY(-50%); color: var(--text-3); font-size: 13px; }
.ord-search input {
  width: 100%; box-sizing: border-box; border: 1px solid var(--border); border-radius: 10px;
  padding: 7px 11px 7px 32px; font-size: 13px; background: #fff; color: var(--text-1);
  font-family: inherit;
}
.ord-search input:focus { outline: none; border-color: var(--brand-500, #6366f1); }
.ord-del { border: 1px solid rgba(225,29,72,.45) !important; color: #be123c !important; background: #fff5f7 !important; font-weight: 700; white-space: nowrap; }
.ord-del:disabled { opacity: .45; cursor: not-allowed; }

.ord-count {
  padding: 10px 14px; font-size: 12.5px; color: var(--text-2);
  border-bottom: 1px solid var(--border);
}
.ord-table { width: 100%; border-collapse: collapse; font-size: 13px; min-width: 940px; }
.ord-th {
  text-align: start; padding: 9px 10px; color: var(--text-3); font-size: 11.5px;
  font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
  border-bottom: 1px solid var(--border); white-space: nowrap; user-select: none;
}
.ord-th[data-osort] { cursor: pointer; }
.ord-th[data-osort]:hover { color: var(--brand-600, #4f46e5); }
.ord-th-cb { width: 34px; }
.ord-th-cb2 { width: 62px; }
.ord-td { padding: 10px; border-bottom: 1px solid var(--border); vertical-align: top; }
.ord-td-cb { width: 34px; padding-inline-end: 0; }
.ord-td-cb input, .ord-th-cb input { width: 16px; height: 16px; cursor: pointer; accent-color: var(--brand-500, #6366f1); }
.ord-td-id { color: var(--text-3); font-variant-numeric: tabular-nums; white-space: nowrap; }
.ord-td-date { white-space: nowrap; color: var(--text-2); }
.ord-td-acts { white-space: nowrap; }
.ord-td-acts .btn { margin-inline-end: 4px; }
.ord-row-on { background: var(--brand-50, #eef2ff); }
.ord-name { font-weight: 700; color: var(--text-1); }
.ord-contact { font-size: 11.5px; color: var(--text-3); margin-top: 2px; word-break: break-word; }
.ord-contact a { color: var(--brand-600, #4f46e5); text-decoration: none; }
.ord-contact a:hover { text-decoration: underline; }
.ord-susp {
  font-size: 10px; font-weight: 800; color: #fff; background: #dc2626;
  border-radius: 999px; padding: 1px 7px; vertical-align: 1px;
}
.ord-code {
  font-size: 12px; background: var(--surface-2, #f1f5f9); border: 1px solid var(--border);
  border-radius: 6px; padding: 1px 6px; direction: ltr; display: inline-block;
}
.ord-amt { font-weight: 700; color: var(--text-1); white-space: nowrap; }
.ord-amt-sub { font-size: 11.5px; color: var(--text-3); white-space: nowrap; }
.ord-amt-sub b { color: #15803d; }
.ord-st { font-weight: 700; white-space: nowrap; }
.ord-pay { font-size: 11px; color: var(--text-3); margin-top: 3px; }
.ord-pay-ref { font-size: 10.5px; color: var(--text-3); margin-top: 1px; }
.ord-ok { background: #16a34a !important; border-color: #16a34a !important; color: #fff !important; font-weight: 700; }
.ord-done { font-size: 12px; color: #15803d; font-weight: 600; }
.ord-del-row { border: 1px solid var(--border) !important; color: #be123c !important; background: #fff !important; }
.ord-del-row:hover { background: #fff5f7 !important; border-color: rgba(225,29,72,.45) !important; }

/* ===========================================================================
   ADMIN → BROADCAST

   Built from the same pieces as the rest of the admin area, not a new visual
   language: white cards with a hairline border and a soft shadow (`.au-card`),
   the admin blue gradient `#1b74bc → #2f8fd6` for the primary action, and the
   `--r-*` / `--text-*` / `--border` tokens for everything else.

   The one deliberate exception is the primary button's GRADIENT: the rest of the
   app uses the indigo/cyan brand ramp, but the admin area's "do the thing"
   buttons (the FAB, the users pager, the avatars) use this blue, and Broadcast
   sits in the admin area. It is written once, here, as `.bc-btn-primary`.
   =========================================================================== */
.bc-wrap { display: flex; flex-direction: column; gap: 16px; }

/* ---- card ---------------------------------------------------------------- */
.bc-card {
  background: #fff; border: 1px solid var(--border); border-radius: 16px;
  padding: 18px 18px 16px; box-shadow: 0 1px 2px rgba(15,23,42,.04);
}
.bc-head {
  display: flex; align-items: center; gap: 9px;
  font-weight: 800; font-size: 15px; color: var(--text);
  margin: 0 0 14px;
}
.bc-head .bc-ico { font-size: 17px; line-height: 1; }
/* A right-hand slot in the header for a small control (e.g. the preview toggle) */
.bc-head .bc-head-end { margin-inline-start: auto; font-weight: 600; }

/* ---- fields -------------------------------------------------------------- */
.bc-field { display: flex; flex-direction: column; gap: 5px; margin-bottom: 14px; }
.bc-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }
.bc-label { font-size: 12.5px; font-weight: 600; color: var(--text-2); }
.bc-input, .bc-select, .bc-textarea {
  width: 100%; box-sizing: border-box; font: inherit; font-size: 14px;
  color: var(--text); background: #fff; border: 1px solid var(--border);
  border-radius: 10px; padding: 9px 12px; transition: border-color .15s, box-shadow .15s;
}
.bc-input:focus, .bc-select:focus, .bc-textarea:focus {
  outline: none; border-color: #2f8fd6; box-shadow: 0 0 0 3px rgba(47,143,214,.16);
}
.bc-textarea { resize: vertical; min-height: 132px; line-height: 1.6; }

/* ---- rich-text announcement editor --------------------------------------- */
/* The message box is a contenteditable now, so it needs its own frame: the
   toolbar owns the top border, the editor owns the rest, and the focus ring
   wraps BOTH (a ring around the text alone would read as a different field). */
.bc-editor-wrap {
  border: 1px solid var(--border); border-radius: 10px; overflow: hidden;
  background: #fff; transition: border-color .15s, box-shadow .15s;
}
.bc-editor-wrap:focus-within { border-color: #2f8fd6; box-shadow: 0 0 0 3px rgba(47,143,214,.16); }
/* Visual / HTML — the same segmented pill the Users list uses for its layouts,
   so "choose how you see this" looks the same everywhere in the admin. */
.bc-tabs {
  display: inline-flex; border: 1px solid var(--border); border-radius: 999px;
  overflow: hidden; background: #fff; margin-bottom: 8px;
}
.bc-tab {
  border: 0; background: transparent; color: var(--text-2); font: inherit;
  font-size: 12.5px; font-weight: 700; line-height: 1; padding: 7px 16px; cursor: pointer;
  transition: background .12s, color .12s;
}
.bc-tab + .bc-tab { border-inline-start: 1px solid var(--border); }
.bc-tab:hover { background: var(--surface); color: #1b74bc; }
.bc-tab.on { background: linear-gradient(135deg, #1b74bc, #2f8fd6); color: #fff; }
/* `hidden` must win over these elements' own `display` (the toolbar is flex, the
   source is block), or the code view would show the formatting buttons that
   cannot apply to it and the editor would show alongside the source. */
.bc-toolbar[hidden], .bc-editor[hidden], .bc-source[hidden] { display: none; }
/* The HTML source view. Always LTR and monospaced — a code editor laid out
   right-to-left (which the Farsi UI would otherwise do) puts `<td>` and its
   closing `>` in the wrong visual order and is genuinely hard to read. */
.bc-source {
  display: block; width: 100%; box-sizing: border-box;
  min-height: 190px; max-height: 420px; resize: vertical;
  border: 0; outline: none; padding: 12px 14px; margin: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Courier New", monospace;
  font-size: 12.5px; line-height: 1.6; tab-size: 2;
  color: var(--text); background: #fff;
  direction: ltr; text-align: left;
}
.bc-toolbar {
  position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: 4px;
  padding: 6px 8px; border-bottom: 1px solid var(--border); background: var(--surface);
}
.bc-tb {
  font: inherit; font-size: 13px; line-height: 1; min-width: 30px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center; gap: 4px;
  border: 1px solid transparent; border-radius: 8px; background: transparent;
  color: var(--text-2); cursor: pointer; padding: 0 7px;
  transition: background .12s, color .12s, border-color .12s;
}
.bc-tb:hover { background: #eef6fc; color: #1b74bc; border-color: #d6e8f6; }
/* The caret's own state, not the last click: the button reads "on" when the
   selection is already bold, exactly like a word processor's toolbar. */
.bc-tb.on { background: linear-gradient(135deg, #1b74bc, #2f8fd6); color: #fff; }
.bc-tb-sep { width: 1px; height: 18px; background: var(--border); margin: 0 3px; }
.bc-editor {
  min-height: 132px; max-height: 420px; overflow-y: auto;
  padding: 10px 12px; font-size: 14px; line-height: 1.65;
  color: var(--text); outline: none; word-break: break-word;
}
.bc-editor:empty:before { content: attr(data-bc-ph); color: var(--text-3); }
.bc-editor img { max-width: 100%; height: auto; border-radius: 8px; }
.bc-editor blockquote {
  margin: 6px 0; padding: 2px 12px; color: var(--text-2);
  border-inline-start: 3px solid var(--border-2);
}
/* ===========================================================================
   Admin → Blog — only what the ARTICLE editor adds on top of the broadcast
   editor it reuses (`bc-editor`, `bc-tabs`, `bc-toolbar`, `bc-source` are all
   shared, so the two admin composers cannot drift apart visually).
   =========================================================================== */
/* Each language is a full edition of the same article, so the English and Farsi
   forms are sibling panes and only one is ever shown. */
.bl-pane[hidden] { display: none; }
/* Headings, lists and code, SCOPED to `.bl-pane`: the broadcast editor only ever
   had to style a short announcement, and an article is mostly headings,
   paragraphs and lists. Scoping means the broadcast composer's appearance is
   untouched by these rules. */
.bl-pane .bc-editor h1, .bl-pane .bc-editor h2, .bl-pane .bc-editor h3,
.bl-pane .bc-editor h4 {
  margin: .7em 0 .3em; line-height: 1.3; font-weight: 700;
}
.bl-pane .bc-editor h1 { font-size: 21px; }
.bl-pane .bc-editor h2 { font-size: 18px; }
.bl-pane .bc-editor h3 { font-size: 16px; }
.bl-pane .bc-editor h4 { font-size: 15px; }
.bl-pane .bc-editor p { margin: .45em 0; }
.bl-pane .bc-editor ul, .bl-pane .bc-editor ol { margin: .5em 0; padding-inline-start: 1.6em; }
.bl-pane .bc-editor li { margin: .2em 0; }
/* A code block is LTR even in the Farsi editor — code is code, and an RTL block
   reorders the punctuation of something like `enc:v1:...`. */
.bl-pane .bc-editor pre {
  margin: .6em 0; padding: 10px 12px; border-radius: 8px;
  background: #0f172a; color: #e2e8f0; overflow-x: auto;
  direction: ltr; text-align: start; font-size: 12.5px;
}
.bl-pane .bc-editor hr { border: 0; border-block-start: 1px solid var(--border); margin: 1em 0; }
/* A pasted article can carry a table (the security post does). */
.bl-pane .bc-editor table { border-collapse: collapse; margin: .6em 0; font-size: 13px; }
.bl-pane .bc-editor th, .bl-pane .bc-editor td {
  border: 1px solid var(--border); padding: 6px 8px; text-align: start;
}
/* The "not written in this language" hint above the Farsi form. */
.bl-lang-note {
  margin: 0 0 10px; padding: 8px 12px; border-radius: 8px;
  background: #fff7ed; border: 1px solid #fed7aa; color: #9a3412;
  font-size: 12.5px;
}
/* Cover image row: a fixed-ratio preview so the admin sees the crop the blog
   index and the Open Graph card will use. */
.bl-cover-row { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; }
.bl-cover-preview {
  width: 168px; height: 96px; flex: 0 0 auto; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  border: 1px dashed var(--border-2); border-radius: 10px; background: var(--surface);
}
.bl-cover-preview img { width: 100%; height: 100%; object-fit: cover; }
.bl-cover-empty { font-size: 26px; opacity: .5; }
.bl-cover-actions { display: flex; flex-wrap: wrap; gap: 8px; }
/* Emoji picker: a small grid anchored to the toolbar button, not a modal — it
   must not take the caret away from the message the emoji goes into. */
.bc-emoji-pop {
  position: absolute; top: calc(100% + 4px); inset-inline-end: 8px; z-index: 30;
  display: grid; grid-template-columns: repeat(10, 1fr); gap: 2px;
  width: 288px; max-height: 190px; overflow-y: auto; padding: 6px;
  background: #fff; border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 12px 30px rgba(15,23,42,.18);
}
.bc-emoji {
  font-size: 17px; line-height: 1; border: 0; background: transparent;
  border-radius: 6px; padding: 5px 0; cursor: pointer;
}
.bc-emoji:hover { background: var(--surface-2); }

/* The live audience count under the target dropdown. */
.bc-audience {
  display: inline-flex; align-items: center; gap: 7px; margin-top: 7px;
  font-size: 12.5px; font-weight: 600; color: #1b74bc;
  background: #eef6fc; border: 1px solid #d6e8f6; border-radius: 999px;
  padding: 4px 12px;
}
.bc-audience.bc-audience-warn { color: #b45309; background: #fffbeb; border-color: #fde68a; }

/* ---- delivery-method checkboxes + tier checkboxes ------------------------ */
/* Three INDEPENDENT channels, and a multi-select tier list. Both are the same
   control: a wrapped row of pill checkboxes, so a long tier label never crushes
   the layout. */
.bc-checks { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 2px; }
.bc-check {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 600; color: var(--text-2); cursor: pointer;
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
  padding: 8px 12px; transition: border-color .12s ease, background .12s ease;
}
.bc-check:hover { border-color: var(--border-2); background: #fff; }
.bc-check input { width: 16px; height: 16px; accent-color: #1b74bc; cursor: pointer; }
/* The inline "select at least one" warning (req 4) and the tier equivalent. */
.bc-inline-warn {
  margin-top: 8px; font-size: 12.5px; font-weight: 600; color: #b45309;
  background: #fffbeb; border: 1px solid #fde68a; border-radius: 9px;
  padding: 7px 11px;
}
/* The SMS recipient-count / estimated-cost note (req 5), inline under the
   checkboxes while SMS is ticked. */
.bc-sms-note {
  margin-top: 8px; font-size: 12.5px; font-weight: 600; color: #1b74bc;
  background: #eef6fc; border: 1px solid #d6e8f6; border-radius: 9px;
  padding: 7px 11px;
}
.bc-sms-note.on { display: block; }
/* The bulk confirmation modal's cost line reuses the same look, in amber. */
.bc-modal .bc-sms-note.on { color: #b45309; background: #fffbeb; border-color: #fde68a; margin: 12px 0 0; }


/* ---- character budget: a bar, not a whisper ------------------------------ */
.bc-count-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.bc-count { font-size: 12px; font-weight: 700; color: var(--text-3); font-variant-numeric: tabular-nums; }
.bc-count.warn { color: #b45309; }
.bc-count.over { color: #dc2626; }
.bc-bar { height: 6px; border-radius: 999px; background: var(--surface-2); overflow: hidden; margin: 7px 0 14px; }
.bc-bar-fill {
  height: 100%; width: 0; border-radius: 999px;
  background: linear-gradient(135deg, #1b74bc, #2f8fd6);
  transition: width .18s ease, background .18s ease;
}
/* Near the limit it turns amber, past it red — the two states the operator has to
   be able to see without reading the number. */
.bc-bar-fill.warn { background: linear-gradient(135deg, #f59e0b, #fbbf24); }
.bc-bar-fill.over { background: linear-gradient(135deg, #dc2626, #ef4444); }

/* ---- buttons (Halo style) ------------------------------------------------ */
.bc-actions { display: flex; flex-wrap: wrap; gap: 9px; align-items: center; }
.bc-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  font: inherit; font-size: 13.5px; font-weight: 700; line-height: 1;
  border-radius: 999px; padding: 10px 18px; cursor: pointer;
  border: 1px solid transparent; background: var(--surface-2); color: var(--text-2);
  transition: transform .12s ease, box-shadow .15s ease, background .15s ease, color .15s;
  white-space: nowrap;
}
.bc-btn:hover { transform: translateY(-1px); }
.bc-btn:active { transform: translateY(0); }
.bc-btn:disabled { opacity: .55; cursor: default; transform: none; box-shadow: none; }
.bc-btn-primary {
  background: linear-gradient(135deg, #1b74bc, #2f8fd6); color: #fff;
  box-shadow: 0 2px 8px rgba(27,116,188,.28);
}
.bc-btn-primary:hover:not(:disabled) { box-shadow: 0 8px 20px rgba(27,116,188,.42); }
.bc-btn-ghost { background: #fff; border-color: var(--border); color: var(--text-2); }
.bc-btn-ghost:hover:not(:disabled) { background: var(--surface); border-color: var(--border-2); color: var(--text); }
.bc-btn-danger { background: #fff; border-color: #fecaca; color: #dc2626; }
.bc-btn-danger:hover:not(:disabled) { background: #fef2f2; box-shadow: 0 4px 14px rgba(220,38,38,.16); }
.bc-hint { font-size: 12px; color: var(--text-3); }

/* ---- send-later toggle --------------------------------------------------- */
.bc-toggle { display: inline-flex; align-items: center; gap: 9px; font-size: 13px; font-weight: 600; color: var(--text-2); cursor: pointer; }
.bc-toggle input { width: 16px; height: 16px; accent-color: #1b74bc; cursor: pointer; }
.bc-later { display: none; margin-top: 12px; }
.bc-later.on { display: block; }

/* ---- preview: what the user actually sees -------------------------------- */
.bc-preview { display: none; margin-top: 4px; }
.bc-preview.on { display: block; }
.bc-preview-label { font-size: 11.5px; font-weight: 700; color: var(--text-3); text-transform: uppercase; letter-spacing: .04em; margin-bottom: 8px; }
/* A mock of the in-app notification row, so it reads as "the user's inbox". */
.bc-inbox { background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 10px; }
.bc-inbox-top { display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--text-3); padding: 2px 4px 8px; }
.bc-inbox-dot { width: 7px; height: 7px; border-radius: 50%; background: #1b74bc; flex: none; }
.bc-inbox-row {
  background: #fff; border: 1px solid var(--border); border-radius: 12px;
  padding: 12px 14px; display: flex; gap: 12px; align-items: flex-start;
  box-shadow: 0 1px 2px rgba(15,23,42,.05);
}
.bc-inbox-ico {
  width: 38px; height: 38px; border-radius: 50%; flex: none;
  background: linear-gradient(135deg, #1b74bc, #2f8fd6); color: #fff;
  display: flex; align-items: center; justify-content: center; font-size: 18px;
}
.bc-inbox-title { font-weight: 800; font-size: 13.5px; color: var(--text); }
/* `white-space: normal`, not pre-wrap: an announcement is HTML now (blocks are
   <div>/<br>), and pre-wrap would render every newline and indent in a PASTED
   email's source as a blank gap. The box scrolls so a 600px-wide pasted layout
   cannot stretch the composer. */
.bc-inbox-body {
  font-size: 13px; color: var(--text-2); line-height: 1.6;
  white-space: normal; word-break: break-word; margin-top: 3px;
  max-height: 420px; overflow: auto;
}
.bc-inbox-meta { font-size: 11.5px; color: var(--text-3); margin-top: 6px; }

/* ---- recent broadcasts table -------------------------------------------- */
.bc-table-wrap { overflow-x: auto; }
.bc-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.bc-table th {
  text-align: start; font-size: 11px; font-weight: 800; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-3); padding: 0 10px 9px;
  border-bottom: 1px solid var(--border); white-space: nowrap;
}
.bc-table td { padding: 11px 10px; border-bottom: 1px solid var(--surface-2); color: var(--text-2); vertical-align: middle; }
.bc-table tr:last-child td { border-bottom: none; }
.bc-table tbody tr:hover { background: var(--surface); }
.bc-table .bc-subject { font-weight: 700; color: var(--text); }
.bc-table .bc-subject .bc-body-hint { display: block; font-weight: 400; font-size: 11.5px; color: var(--text-3); margin-top: 2px; max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bc-num { font-variant-numeric: tabular-nums; }
.bc-row-actions { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.bc-row-actions .bc-btn { padding: 6px 12px; font-size: 12px; }

/* ---- status pill --------------------------------------------------------- */
.bc-status {
  display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px;
  font-weight: 800; border-radius: 999px; padding: 3px 10px; white-space: nowrap;
}
.bc-status-sent { background: #ecfdf5; color: #047857; }
.bc-status-scheduled { background: #eef6fc; color: #1b74bc; }
.bc-status-draft { background: var(--surface-2); color: var(--text-2); }
.bc-status-failed { background: #fef2f2; color: #dc2626; }

.bc-empty { text-align: center; color: var(--text-3); font-size: 13px; padding: 26px 10px; }

/* ---- pagination (same shape as the users page pager) --------------------- */
.bc-pager { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 14px; }
.bc-pager .p-btn {
  border: 1px solid var(--border); background: #fff; color: var(--text-2);
  border-radius: 8px; padding: 5px 11px; font-size: 13px; cursor: pointer;
}
.bc-pager .p-btn.on { background: #1b74bc; color: #fff; border-color: #1b74bc; font-weight: 700; }
.bc-pager .p-btn:disabled { opacity: .4; cursor: default; }

/* ---- confirmation modal -------------------------------------------------- */
.bc-modal-back {
  position: fixed; inset: 0; z-index: 90; background: rgba(15,23,42,.5);
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.bc-modal {
  background: #fff; border-radius: 16px; padding: 22px; width: 100%; max-width: 460px;
  box-shadow: 0 24px 60px rgba(15,23,42,.32);
}
.bc-modal h3 { margin: 0 0 8px; font-size: 17px; font-weight: 800; color: var(--text); }
.bc-modal p { margin: 0; font-size: 13.5px; line-height: 1.7; color: var(--text-2); }
.bc-modal .bc-quote {
  margin: 12px 0; padding: 10px 13px; border-radius: 10px;
  background: var(--surface); border: 1px solid var(--border);
  font-size: 13px; color: var(--text); font-weight: 600;
}
.bc-modal-actions { display: flex; gap: 9px; justify-content: flex-end; margin-top: 18px; }

/* ---- narrow screens: one column ----------------------------------------- */
@media (max-width: 820px) {
  .bc-grid2 { grid-template-columns: 1fr; }
  .bc-card { padding: 15px; border-radius: 14px; }
  .bc-actions .bc-btn { flex: 1 1 auto; }
  .bc-row-actions { justify-content: flex-start; }
  .bc-table th:nth-child(2), .bc-table td:nth-child(2) { display: none; }  /* the date column */
}
