@font-face {
  font-family: Vazirmatn;
  src: url('/admin/fonts/Vazirmatn-Regular.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: Vazirmatn;
  src: url('/admin/fonts/Vazirmatn-Medium.woff2') format('woff2');
  font-weight: 500;
  font-display: swap;
}
@font-face {
  font-family: Vazirmatn;
  src: url('/admin/fonts/Vazirmatn-Bold.woff2') format('woff2');
  font-weight: 700;
  font-display: swap;
}

:root {
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --bg: #fbf7f1;
  --surface: #ffffff;
  --surface-2: #f6efe6;
  --text: #2e2119;
  --muted: #7a6a5d;
  --line: #eadfd3;
  --primary: #8a716d;
  --primary-ink: #ffffff;
  /* brand gold, lifted from the Tailor design system (--color-gold) - warm,
     close to orange; it is the only colour in the field halo */
  --gold: #fcd7b3;
  /* THE FIELD HALO - one token, read by every focused input. Copied verbatim
     from Tailor's --field-halo: two blurred layers, NO solid core, so the glow
     hugs the 1px line instead of floating 1px away from it. */
  --field-halo:
    0 0 4px 1px color-mix(in srgb, var(--gold) 33%, transparent),
    0 0 8px 2px color-mix(in srgb, var(--gold) 13.2%, transparent);
  --ok: #2f7a5b;
  --warn: #a06a1f;
  --err: #a33a3a;
  --radius: 14px;
  --shadow: 0 1px 2px rgba(46, 33, 25, 0.05), 0 8px 24px rgba(46, 33, 25, 0.06);
  /* campaign form: the panel sits one notch darker than the app bg, and its
     secondary buttons are cream instead of white so they read as buttons
     next to the pure-white input fields */
  --form-bg: #f9f4ee;
  /* button chips inside the DM preview: grey, so they don't read as text */
  --preview-btn: #e8e8e8;
}

html[data-theme='dark'] {
  --bg: #17130f;
  --surface: #211b16;
  --surface-2: #2a231d;
  --text: #f3eae0;
  --muted: #b3a394;
  --line: #332a23;
  --primary: #8a716d;
  --primary-ink: #ffffff;
  --gold: #fcd7b3;
  --ok: #6fbf97;
  --warn: #d9a45c;
  --err: #e08585;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 8px 24px rgba(0, 0, 0, 0.35);
  --form-bg: #17130f;
  --preview-btn: #3b3531;
}

* { box-sizing: border-box; }

/* the canvas itself must always paint the theme background, edge to edge */
html { background: var(--bg); }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: Vazirmatn, system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: 14px;
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
}

:root { --app-pad: 16px; }
.app { max-width: 1080px; margin: 0 auto; padding: 6px var(--app-pad) 80px; }

/* upper rows bleed to the screen edges so no see-through gutters remain
   beside them; the compensating padding keeps the content width unchanged */
.bleed { margin-inline: calc(var(--app-pad) * -1); padding-inline: var(--app-pad); background: var(--bg); }

/* header — stays pinned on scroll and FULLY covers the content under it */
.topbar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px var(--app-pad) 12px;
  margin-inline: calc(var(--app-pad) * -1); /* cream reaches the screen edges */
  position: sticky;
  top: 0;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  z-index: 20;
}
.brand { display: flex; align-items: center; gap: 8px; margin-inline-end: auto; min-width: 0; }
.brand img { width: 46px; height: 46px; border-radius: 50%; object-fit: cover; }
.brand b { font-weight: 700; font-size: 18.5px; white-space: nowrap; }

.tabs { display: flex; gap: 4px; background: var(--surface-2); padding: 4px; border-radius: 12px; overflow-x: auto; }
.tabs a {
  /* a step darker than the muted fine print, regular weight - the nav reads as
     labels, and the active tab is the one that steps up to medium */
  color: color-mix(in srgb, var(--text) 62%, var(--muted));
  text-decoration: none;
  padding: 7px 14px;
  border-radius: 9px;
  font-size: 14px;
  font-weight: 400;
  white-space: nowrap;
}
.tabs a.active { background: var(--surface); color: var(--text); box-shadow: var(--shadow); font-weight: 500; }

/* generic */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.pad { padding: 16px; }
.row { display: flex; align-items: center; gap: 10px; }
.row.wrap { flex-wrap: wrap; }
.spacer { margin-inline-start: auto; }
.muted { color: var(--muted); }
.small { font-size: 12px; }
h1 { font-size: 19px; margin: 0 0 4px; font-weight: 700; }
h2 { font-size: 15px; margin: 0; font-weight: 500; }
p.lead { margin: 0 0 18px; color: var(--muted); font-size: 13px; }

button, .btn {
  font-family: inherit;
  font-size: 13px;
  border-radius: 10px;
  border: 1px solid var(--primary);
  background: var(--surface);
  color: var(--text);
  padding: 8px 14px;
  cursor: pointer;
  transition: transform 0.06s ease, background 0.15s ease;
}
button:hover { background: var(--surface-2); }
button:active { transform: scale(0.985); }
button.primary { background: var(--primary); border-color: var(--primary); color: var(--primary-ink); font-weight: 500; }
button.primary:hover { filter: brightness(1.05); }
button.ghost { background: transparent; color: var(--muted); }
button.danger { color: var(--err); border-color: color-mix(in srgb, var(--err) 55%, transparent); }
button.danger:hover { background: color-mix(in srgb, var(--err) 9%, var(--surface)); }
button:disabled { opacity: 0.55; cursor: default; }
button.icon { padding: 7px 9px; }
button.wide { width: 100%; padding-block: 10px; }

input, select, textarea {
  font-family: inherit;
  font-size: 13px;
  width: 100%;
  padding: 9px 12px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--text);
  transition: border-color 150ms ease, box-shadow 150ms ease;
}
/* Tailor's active signal, not a ring: the 1px line darkens to full brown and a
   soft two-layer gold halo sits on the border itself (no gap, no core) */
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: var(--field-halo);
}
textarea { resize: vertical; min-height: 74px; line-height: 1.9; }

/* custom dropdown chevron: the native RTL arrow sits glued to the left edge */
select {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%237a6a5d' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: left 12px center;
  padding-inline-end: 34px;
}
html[data-theme='dark'] select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%23b3a394' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
label.field, div.field { display: block; margin-bottom: 14px; }
label.field > span, div.field > span { display: block; font-size: 12px; color: var(--muted); margin-bottom: 6px; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 14px; }
.grid2 label.field, .grid2 div.field { margin-bottom: 0; }
@media (max-width: 640px) { .grid2 { grid-template-columns: 1fr; } }

.chip { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; padding: 3px 9px; border-radius: 999px; background: var(--surface-2); color: var(--muted); }
.chip.ok { color: var(--ok); }
.chip.err { color: var(--err); }
.chip.warn { color: var(--warn); }

/* posts: three-up grid, like the Instagram profile (the profile grid is
   portrait 3:4, not square, since Instagram's 2025 redesign) */
.ptabs { display: flex; border-bottom: 1px solid var(--line); margin-bottom: 2px; }
.ptab {
  flex: 1;
  height: 46px;
  display: grid; place-items: center;
  padding: 0;
  border: 0; border-bottom: 1.5px solid transparent; border-radius: 0;
  background: transparent; color: var(--muted);
}
.ptab:hover { background: transparent; color: var(--text); }
.ptab.active { color: var(--text); border-color: var(--text); }
.ptab svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linejoin: round; }
.posts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 3px; margin-inline: calc(var(--app-pad) * -1); }
.tile { display: block; padding: 0; border: 0; background: var(--surface-2); border-radius: 0; overflow: hidden; cursor: pointer; aspect-ratio: 3 / 4; }
.tile img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tile:active { transform: none; opacity: 0.92; }

.modal-bg { position: fixed; inset: 0; background: rgba(20, 14, 10, 0.5); z-index: 45; display: flex; align-items: center; justify-content: center; padding: 16px; }
.sheet { width: min(420px, 100%); max-height: 92vh; overflow-y: auto; background: var(--bg); border-radius: 16px; padding: 12px 14px 16px; box-shadow: var(--shadow); }

/* only the close button rides above the scroll (titles scroll away with the
   content): a zero-height sticky strip whose button floats on the left */
.sheet-close {
  position: sticky;
  top: 10px;
  z-index: 6;
  height: 0;
  display: flex;
  justify-content: flex-end; /* RTL inline-end: the button sits on the left */
  align-items: flex-start; /* the zero-height strip must not squash the button */
}
.sheet-close > button { background: var(--bg); box-shadow: 0 1px 5px rgba(20, 14, 10, 0.22); }
.sheet-close > button:hover { background: var(--surface-2); }

/* POST SHEET: one header row - campaign title on the right, square close button
   on the left - then the photo, with a small gap above it. The row keeps its
   height when there is no campaign, so both states start the photo at the same
   place. */
.sheet-post { padding: 0 0 16px; }
.sheet-head {
  position: sticky;
  top: 0;
  z-index: 6;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 10px 8px;
  background: var(--bg);
}
.sheet-head .sheet-title { flex: 1; min-width: 0; }
.sheet-post .sheet-img { border-radius: 0; }
.sheet-body { padding: 12px 14px 0; }
.sheet-x {
  width: 32px;
  height: 32px;
  padding: 0;
  display: grid;
  place-items: center;
  border-radius: 8px;
  font-size: 14px;
  line-height: 1;
  background: var(--bg);
  box-shadow: 0 1px 5px rgba(20, 14, 10, 0.22);
}
.sheet-x:hover { background: var(--surface-2); }
.sheet-title-row {
  display: flex;
  align-items: center;
  min-height: 34px;
  margin-bottom: 10px;
  padding-inline-end: 46px; /* keep the title clear of the floating button */
}
.sheet-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13.5px; font-weight: 600; }

/* the edit/delete pair under the wide CTA: one row, each half its width */
.pair-btns { display: flex; gap: 8px; }
.pair-btns > button { flex: 1; min-width: 0; padding-block: 9px; }

.sheet-img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; border-radius: 16px 16px 0 0; display: block; }
.sheet-cap { font-size: 13px; margin-top: 10px; line-height: 1.9; white-space: pre-wrap; }
.cta-wide svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

/* list rows */
.list { display: flex; flex-direction: column; gap: 10px; }
.item { display: flex; gap: 8.4px; align-items: flex-start; padding: 12px 14px; }
.item .grow { flex: 1; min-width: 0; }
.item .title { font-weight: 500; font-size: 13.5px; }
.item .sub { color: var(--muted); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* the three row actions are 10% narrower (padding only - the height and the
   type scale stay exactly as they were) and ride the vertical middle of the
   card like the switch does */
.item > button { padding-inline: 10.5px; align-self: center; }

/* switch */
.switch { position: relative; width: 40px; height: 22px; flex: none; }
.switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.switch i { position: absolute; inset: 0; background: var(--line); border-radius: 999px; transition: background 0.15s; }
.switch i::after { content: ''; position: absolute; width: 16px; height: 16px; border-radius: 50%; background: #fff; top: 3px; inset-inline-start: 3px; transition: inset-inline-start 0.15s; }
.switch input:checked + i { background: var(--primary); }
.switch input:checked + i::after { inset-inline-start: 21px; }

/* in a campaign row the same switch stands upright: it takes 22px of width
   instead of 40, which is what lets the three actions breathe - and it always
   sits in the vertical middle of the card, however tall the title gets. The
   extra inline margin makes the gap to the text equal the card's own 14px
   padding, so the switch has the same air on both sides. */
.item .switch { width: 22px; height: 40px; align-self: center; margin-inline-end: 5.6px; }
.item .switch i::after { top: 3px; inset-inline-start: 3px; transition: top 0.15s; }
.item .switch input:checked + i::after { top: 21px; inset-inline-start: 3px; }

/* drawer */
.drawer-bg { position: fixed; inset: 0; background: rgba(20, 14, 10, 0.45); z-index: 40; display: flex; justify-content: flex-start; }

/* closing: fade the dark backdrop out (and let the drawer drift away) instead
   of cutting straight to the bright page in one frame - that cut was the blink
   after saving or closing a campaign */
.drawer-bg.closing,
.modal-bg.closing { opacity: 0; transition: opacity 0.18s ease-out; pointer-events: none; }
.drawer-bg.closing .drawer { transform: translateX(-16px); transition: transform 0.18s ease-out; }
.drawer {
  width: min(560px, 100%);
  height: 100%;
  overflow-y: auto;
  background: var(--form-bg);
  padding: 16px 18px 36px;
  animation: slide 0.18s ease-out;
}
@keyframes slide { from { transform: translateX(-18px); opacity: 0.6; } to { transform: none; opacity: 1; } }
/* a drawer that was already on screen (the form rebuilding itself after adding
 * a button or a photo) must NOT slide in again - that replay read as the page
 * blinking on every tap */
.drawer-bg.quiet .drawer { animation: none; }

/* the form's secondary actions (ثبت / بستن / ایجاد دکمه / افزودن عکس) share the
   same cream fill used as a background elsewhere in the app (preview box, tab
   strip, image tiles) - not white, so they don't read as input fields */
.drawer [data-action='resolve-post'],
.drawer [data-action='add-button'],
.drawer [data-action='pick-file'],
.drawer .drawer-actions [data-action='close-drawer'] {
  background: var(--surface-2);
}
.drawer [data-action='resolve-post']:hover,
.drawer [data-action='add-button']:hover,
.drawer [data-action='pick-file']:hover,
.drawer .drawer-actions [data-action='close-drawer']:hover {
  background: color-mix(in srgb, var(--surface-2) 88%, var(--text));
}

/* drawer footer: optional delete, then the save/close pair */
.drawer-foot { margin-top: 16px; }
.drawer-foot > button.danger { width: 100%; margin-bottom: 10px; }
.drawer-actions { display: flex; gap: 10px; }
/* one shared metric for the primary actions: the campaign drawer footer
   (بستن / ایجاد کمپین) and the «ذخیره» of the defaults card stay the same
   height and type scale wherever they appear */
.drawer-actions > button,
[data-action='save-defaults'] { padding-block: 11px; font-size: 14px; }
.drawer-actions > button { flex: 1; min-width: 0; }

/* images */
.thumbs { display: flex; gap: 8px; flex-wrap: wrap; }
.thumbs figure { position: relative; margin: 0; }
.thumbs img { width: 72px; height: 72px; object-fit: cover; border-radius: 10px; border: 1px solid var(--line); }
.thumbs button { position: absolute; top: -6px; inset-inline-end: -6px; border-radius: 50%; padding: 2px 6px; font-size: 11px; background: var(--surface); }
.upload { display: flex; width: 100%; }
.upload button { width: 100%; padding-block: 10px; }

/* preview */
.preview { background: var(--surface-2); border: 1px solid var(--line); border-radius: 14px; padding: 12px; }
/* the preview's own caption - a step larger and darker than the muted fine
   print right under it, so the block is titled, not whispered */
.preview-cap { font-size: 13px; font-weight: 500; color: var(--text); margin-bottom: 8px; }
.chat { display: flex; flex-direction: column; gap: 6px; align-items: flex-end; }
.msg { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 7px 11px; font-size: 12.5px; line-height: 1.8; max-width: 86%; white-space: pre-wrap; overflow-wrap: anywhere; }
.msg.out { background: var(--primary); color: var(--primary-ink); border-color: transparent; border-radius: 12px 12px 4px 12px; }
/* the public comment reply wears the add-photo card's clothes: white fill and
   the 1px primary border, so it reads as an outline instead of a solid block */
.msg.out.pub { background: var(--surface); color: var(--primary); border-color: var(--primary); }
.msg.pic { padding: 3px; background: var(--surface); border-color: var(--line); }
.msg.pic img { display: block; max-width: 190px; border-radius: 9px; }

/* logs */
table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
th, td { text-align: start; padding: 9px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
th { color: var(--muted); font-weight: 500; font-size: 11.5px; }
td.detail { color: var(--muted); max-width: 320px; }

.empty { text-align: center; padding: 40px 16px; color: var(--muted); }

/* login */
/* THE LOGIN SCREEN OWNS THE VIEWPORT: the app's content padding would shrink
   the card for no reason, so it is dropped while the login card is on screen */
.app:has(.login-wrap) { padding: 0; }
.login-wrap { min-height: 100dvh; display: grid; place-items: center; padding: 20px 14px; }
/* THE LOGIN CARD CARRIES NO WHITE OF ITS OWN: it sits on the page's cream and
   is held up by a light drop shadow instead, so the panel reads as one soft
   surface rather than a white box pasted onto the background */
.login {
  width: min(460px, 100%);
  padding: 30px 26px 26px;
  background: var(--bg);
  border-color: transparent;
  border-radius: 20px;
  box-shadow:
    0 1px 2px rgba(46, 33, 25, 0.04),
    0 10px 28px -6px rgba(46, 33, 25, 0.14);
}
.login img { width: 62px; height: 62px; border-radius: 50%; object-fit: cover; margin-bottom: 10px; }
.login h1 { font-weight: 500; color: #423024; }
/* THE FIELD AND THE SUBMIT ARE THE «به‌روزرسانی» BUTTON: full width, 48px tall,
   6px corners, 15px label - one control language across the panel. Both keep a
   FIXED height, so the card cannot grow when the field gets focus or autofill
   swaps the input font. */
.login input {
  height: 48px;
  padding-block: 0;
  border-radius: 6px;
  font-size: 15px;
}
.login button.primary {
  width: 100%;
  height: 48px;
  padding: 0;
  border-radius: 6px;
  font-size: 15px;
  font-weight: 500;
}
.login input:-webkit-autofill,
.login input:-webkit-autofill:hover {
  font-family: inherit;
  /* the browser's autofill patch used to force 13px here, which shrank the
     dots the moment Chrome filled the password - the field keeps its own size */
  font-size: inherit;
  -webkit-text-fill-color: var(--text);
  box-shadow: inset 0 0 0 100px var(--surface);
}
/* an autofilled + focused field keeps the fill AND the halo */
.login input:-webkit-autofill:focus {
  box-shadow: inset 0 0 0 100px var(--surface), var(--field-halo);
}

/* toast */
.toast {
  position: fixed;
  bottom: 18px;
  inset-inline-start: 50%;
  transform: translateX(-50%);
  background: var(--text);
  color: var(--bg);
  padding: 9px 16px;
  border-radius: 10px;
  font-size: 12.5px;
  z-index: 60;
  box-shadow: var(--shadow);
}
.toast.err { background: var(--err); color: #fff; }

@media (max-width: 560px) {
  :root { --app-pad: 12px; }
  .app { padding: 2px var(--app-pad) 70px; }
  .topbar { flex-wrap: wrap; gap: 6px; padding: 2px var(--app-pad) 8px; }
  .tabs { order: 3; width: 100%; justify-content: space-between; padding: 3px; }
  .tabs a { padding: 6px 9px; font-size: 13.5px; }
  .icon-btn { width: 32px; height: 32px; border-radius: 9px; }
  .brand img { width: 40px; height: 40px; }
}

/* report + leads */
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(116px, 1fr)); gap: 10px; margin-bottom: 14px; }
.kpi { display: flex; flex-direction: column; gap: 2px; }
.kpi b { font-size: 21px; font-weight: 700; }
.kpi span { font-size: 11.5px; color: var(--muted); }
.chart { display: flex; align-items: flex-end; gap: 6px; height: 120px; padding-top: 8px; }
.bar-col { flex: 1; min-width: 10px; display: flex; flex-direction: column; align-items: center; gap: 4px; height: 100%; justify-content: flex-end; }
.bars { display: flex; gap: 2px; align-items: flex-end; height: 100%; width: 100%; justify-content: center; }
.bars i { width: 6px; border-radius: 3px 3px 0 0; display: block; min-height: 2px; }
.b1 { background: var(--muted); opacity: 0.5; }
.b2 { background: var(--primary); }
.bar-col span { font-size: 9px; color: var(--muted); }
.mono { font-family: ui-monospace, SFMono-Regular, monospace; font-size: 11.5px; }

/* ordered image list + campaign action-buttons list */
.img-list, .btn-list { display: flex; flex-direction: column; gap: 8px; }
.btn-list .row { gap: 8px; }
.btn-list .row input { min-width: 0; }
.btn-list + button { margin-top: 10px; }
.img-row { display: flex; align-items: center; gap: 8px; width: 100%; padding: 6px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface-2); }
.img-row img { width: 48px; height: 48px; object-fit: cover; border-radius: 8px; border: 1px solid var(--line); flex: none; }
.img-row .num { font-size: 11px; color: var(--muted); min-width: 14px; text-align: center; }
.img-row button { padding: 4px 9px; }

/* header action buttons */
.actions { display: flex; align-items: center; gap: 6px; flex: none; }
.icon-btn {
  width: 34px; height: 34px;
  display: grid; place-items: center;
  padding: 0;
  border-radius: 10px;
  border: 1px solid var(--primary);
  background: var(--surface);
  color: var(--muted);
}
.icon-btn:hover { background: var(--surface-2); color: var(--text); }
.icon-btn.danger { border-color: var(--err); color: var(--err); }
.icon-btn.danger:hover { color: var(--err); }
.icon-btn svg { width: 14.4px; height: 14.4px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }

/* visually hidden but present for landmarks */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

main > .sr-only + .row, main > .sr-only + * { margin-top: 0; }
main { padding-top: 2px; }

/* wide submit bar (same shape as the Taroya «ثبت درخواست» bar) */
.cta-wide {
  width: 100%;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 0;
  border-radius: 6px;
  background: var(--primary);
  color: var(--primary-ink);
  font-family: inherit;
  font-size: 15px;
  font-weight: 500;
  padding: 0;
}
/* label and glyph flow together, centered - the icon sits right next to the
 * text (to its left in RTL), never pinned to the button edge */
.cta-wide > svg,
.cta-wide .plus {
  flex: none;
}
.cta-wide:hover { background: var(--primary); filter: brightness(1.04); }
.cta-wide:active { transform: scale(0.995); }
.cta-wide .plus { font-size: 15px; line-height: 1; }

/* same wide shape, but the plain white button look */
.cta-wide.light {
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--text);
}
.cta-wide.light:hover { background: var(--surface-2); filter: none; }

.lead-avatar { width: 28px; height: 28px; border-radius: 50%; object-fit: cover; border: 1px solid var(--line); flex: none; }
.lead-name { font-size: 12.5px; font-weight: 500; direction: ltr; unicode-bidi: plaintext; text-align: start; }
.clip { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* LEADS: one tool bar that reads in three tidy rows on a phone, and a card list
   instead of the ten-column table below 720px */
.lead-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 12px; }
.lead-search { flex: 1 1 220px; min-width: 160px; max-width: 320px; }
.lead-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.lead-chips > button { flex: 0 0 auto; }
.lead-bulk { display: flex; gap: 8px; margin-inline-start: auto; }
.leads-cards { display: none; }

.lead-card { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 12px; display: flex; flex-direction: column; gap: 8px; }
.lead-top { display: flex; align-items: center; gap: 9px; }
.lead-id { flex: 1; min-width: 0; }
.lead-id .lead-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lead-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: 11.5px; color: var(--muted); }
.lead-meta .dot { opacity: 0.55; }
.lead-src { font-size: 12.5px; line-height: 1.7; display: flex; flex-direction: column; gap: 1px; }
.lead-actions { display: flex; align-items: center; gap: 6px; margin-top: 2px; }
.lead-actions select { flex: 1; min-width: 0; padding: 7px 10px; font-size: 12px; }
.lead-actions > button { flex: 0 0 auto; padding: 7px 10px; font-size: 12px; }

@media (max-width: 720px) {
  .lead-tools { display: grid; gap: 8px; }
  .lead-search { width: 100%; max-width: none; }
  .lead-chips { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
  .lead-chips::-webkit-scrollbar { display: none; }
  .lead-bulk { margin: 0; }
  .lead-bulk > * { flex: 1; text-align: center; }
  .leads-table { display: none; }
  .leads-cards { display: flex; flex-direction: column; gap: 8px; }
}

/* button chips in the preview */
.msg.btn-preview { display: flex; flex-direction: column; gap: 4px; padding: 0; background: transparent; border: 0; max-width: 86%; }
.msg.btn-preview > * { border: 1px solid var(--line); background: var(--surface); color: var(--text); border-radius: 9px; padding: 6px 12px; text-align: center; font-size: 12.5px; }
/* only the button chips (spans) get the grey fill - the message text above
   them stays a white bubble, so the two are told apart at a glance */
.msg.btn-preview > span { background: var(--preview-btn); }

/* Tailor-style campaign image picker: square tiles with an X, plus the
   chocolate add-photo card (84.6 x 103.5, 1px primary border) */
.img-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.img-tile { position: relative; width: 84.6px; height: 103.5px; flex: none; border-radius: 8px; overflow: hidden; border: 1px solid var(--line); background: var(--surface-2); }
.img-tile img { width: 100%; height: 100%; object-fit: cover; display: block; }
.img-x { position: absolute; top: 4px; left: 4px; width: 20px; height: 20px; padding: 0; display: grid; place-items: center; border-radius: 50%; font-size: 11px; line-height: 1; background: rgba(0, 0, 0, 0.55); color: #fff; border: 0; cursor: pointer; }
.img-x:hover { background: rgba(0, 0, 0, 0.72); }
.img-add {
  width: 84.6px; height: 103.5px; flex: none; padding: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px;
  border: 1px solid var(--primary); border-radius: 8px;
  background: var(--surface); color: var(--primary); cursor: pointer;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
  transition: box-shadow 0.15s ease, transform 0.06s ease;
}
.img-add:hover { box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); }
.img-add:active { transform: scale(0.97); }
.img-add svg { width: 27.2px; height: 27.2px; }
.img-add svg.plus { width: 12px; height: 12.8px; }
.img-add span { font-size: 12px; font-weight: 500; line-height: 1; }


/* THE ONE CROP WINDOW - the Tailor app's photo-crop-dialog, ported 1:1
   (PWA/Tailor src/components/ui/photo-crop-dialog.tsx): black/95 surface,
   5 percent side bands, 90 percent photo wrapper, the 80px + safe-bottom
   reserve, the two floating buttons at the bottom 2 percent (confirm filled
   brown on the RIGHT, cancel outlined on the LEFT), and the 6px white corner
   brackets centred on the frame's edges (sizes come inline from crop.js). */
.tcd {
  position: fixed; inset: 0; z-index: 80;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  overflow: hidden; overscroll-behavior: none;
  background: rgba(0, 0, 0, 0.95);
  padding: 0 5% calc(80px + var(--safe-bottom));
  touch-action: none; user-select: none; -webkit-user-select: none;
}
.tcd-photo-wrap { position: relative; z-index: 0; flex: 1 1 auto; min-height: 0; height: 90%; width: 100%; }
.tcd-photo { display: block; height: 100%; width: 100%; object-fit: contain; user-select: none; -webkit-user-drag: none; }
.tcd-photo.invisible { visibility: hidden; }
.tcd-unreadable { pointer-events: none; position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; padding: 0 24px; text-align: center; }
.tcd-unreadable p { margin: 0; color: #fff; font-size: 13px; font-weight: 700; line-height: 24px; }
.tcd-frame { position: absolute; touch-action: none; cursor: move; }
.tcd-grip { position: absolute; z-index: 10; width: 28px; height: 28px; border-style: solid; border-color: #ffffff; touch-action: none; }
.tcd-actions { pointer-events: none; position: absolute; left: 0; right: 0; bottom: 2%; z-index: 10; display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 12px 12px calc(var(--safe-bottom) + 12px); }
/* THE RATIO ROW: Instagram's post-crop ratios as floating capsules (the
   request-type sheet's own capsule shape), sitting just above the confirm and
   cancel pair. "اصلی" is the photo's own shape - the opening, uncropped state. */
.tcd-ratios { pointer-events: auto; display: flex; align-items: center; justify-content: center; gap: 8px; max-width: 100%; }
.tcd-chip {
  height: 36px; padding: 0 14px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px; border: 1.5px solid rgba(255, 255, 255, 0.35);
  background: transparent; color: #ffffff;
  font-family: inherit; font-size: 12.5px; font-weight: 600; line-height: 1;
  cursor: pointer; -webkit-tap-highlight-color: transparent; outline: none;
}
.tcd-chip:active { transform: scale(0.97); }
.tcd-chip.active { background: #8a716d; border-color: #8a716d; }
.tcd-error { margin: 0; color: #ffffff; font-size: 12px; font-weight: 700; }
.tcd-row { pointer-events: auto; width: 100%; max-width: 384px; display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.tcd-row > * { width: 100%; }
.tcd-btn, .tcd-btn-primary {
  display: flex; height: 48px; width: 100%; align-items: center; justify-content: center;
  border-radius: 12px; font-family: inherit; font-size: 17px; font-weight: 600;
  cursor: pointer; -webkit-tap-highlight-color: transparent; outline: none;
}
.tcd-btn { background: #ffffff; border: 1.5px solid #8a716d; color: #8a716d; }
.tcd-btn-primary { background: #8a716d; border: 0; color: #ffffff; }
.tcd-btn:disabled, .tcd-btn-primary:disabled { opacity: 0.6; cursor: default; }


/* the pinned page head (posts: sync bar + tabs, campaigns: new bar + tabs)
   stays visible while the content under it scrolls - top = the sticky topbar
   height, measured live by render() */
.posts-head,
.page-head {
  position: sticky;
  top: var(--topbar-h, 58px);
  z-index: 5;
  background: var(--bg);
  /* bleed to the screen edges: the gutters beside the bar and the tabs fill
     with cream; inner padding keeps the widths */
  margin: 0 calc(var(--app-pad) * -1) 0;
  padding: 2px var(--app-pad) 12px;
  /* the bar sticks directly under the topbar: the upward shadow paints the
     hairline above it, so the grid can no longer peek through the seam */
  box-shadow: 0 -6px 0 0 var(--bg);
}

/* text variant of the section tabs (campaigns: پست‌ها / عمومی) */
.ptab.ptab-txt { font-family: inherit; font-size: 13px; font-weight: 500; }
