/* پوسته‌ی جیبوک.
   رنگ‌ها از tokens.css می‌آیند — همان فایلی که سایت و آیکون اپ از آن ساخته
   شده‌اند. چیدمان و اجزا از روی اسکرین‌شات‌های خودِ اپ بازسازی شده‌اند، نه
   از روی حافظه. */

/* بلندی نوار تب و فاصله‌اش از کف: دکمه‌ی ثبت و فاصله‌ی پایینِ محتوا هم
   از همین‌ها حساب می‌شوند، وگرنه با هر تغییر یکی‌شان جا می‌ماند. */
:root { --tabbar-h: 82px; --tabbar-bottom: 8px; }

*, *::before, *::after { box-sizing: border-box; }

/* حرکت تک‌انگشتی آزاد است؛ pinch و double-tap نباید قاب اپ را زوم کنند. */
* { touch-action: pan-x pan-y; }

/* یک کلاس با display صریح بر [hidden] پیش‌فرض مرورگر غلبه می‌کند و عنصر
   پنهان روی صفحه می‌ماند. این خط باید قبل از همه‌ی کلاس‌ها بیاید. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  /* کشیدن صفحه به پایین در PWA نصب‌شده، شبیه باگ به‌نظر می‌رسد نه رفرش. */
  overscroll-behavior-y: none;
}

body {
  margin: 0;
  background: var(--bg-subtle);
  color: var(--text);
  /* زنجیره‌ی جایگزین برای همان لحظه‌ای که فونت هنوز نیامده: تاهوما روی
     ویندوز و بقیه‌ی این‌ها فارسی را درست‌تر از Segoe UI می‌کشند. */
  font-family: Vazirmatn, Tahoma, 'Iranian Sans', 'Noto Naskh Arabic', system-ui, -apple-system, sans-serif;
  font-size: 15px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

button { font: inherit; color: inherit; }

/* هیچ ورودی‌ای نباید فونت زیر ۱۶ پیکسل داشته باشد.
   ────────────────────────────────────────────────
   سافاری آیفون وقتی فوکوس روی ورودی‌ای با فونت کوچک‌تر از ۱۶ می‌رود، کل
   صفحه را زوم می‌کند — و آن زوم می‌ماند، پس بقیه‌ی محتوا از قاب بیرون
   می‌افتد و کاربر فکر می‌کند اپ خراب شده.
   بدنه ۱۵ پیکسل است و `font: inherit` روی فیلدها دقیقاً همان زیرِ آستانه
   را می‌داد. این قاعده سراسری است تا هیچ ورودی تازه‌ای از قلم نیفتد؛
   کنترل ژست‌های زوم جداست؛ اندازهٔ ورودی جلوی زوم هنگام فوکوس را می‌گیرد. */
input, select, textarea { font-size: max(16px, 1rem); }

/* آیکون‌های اپ توپرند نه خطی. پیش‌فرض همان است و هر svg که خط لازم دارد
   کلاس ln می‌گیرد. */
svg { width: 100%; height: 100%; fill: currentColor; stroke: none; }
svg.ln { fill: none; stroke: currentColor; stroke-width: 1.9; }

/* ── بارگذاری ─────────────────────────────────────────────────────────── */

.boot {
  position: fixed; inset: 0;
  display: grid; place-content: center; justify-items: center; gap: 18px;
  background: var(--bg-subtle);
}
.boot__msg { margin: 0; color: var(--text-muted); font-size: 14px; max-width: 32ch; text-align: center; }
.boot--error .boot__msg { color: var(--negative); }

/* ── چیدمان ───────────────────────────────────────────────────────────── */

.app {
  min-height: 100dvh;
  display: flex; flex-direction: column;
  /* جا برای نوار و ناحیه‌ی امن. صفحه‌هایی که دکمه‌ی ثبت دارند کلاس app--fab
     می‌گیرند و جای دکمه هم اضافه می‌شود؛ تنظیمات و گزارش دکمه ندارند و آن
     فضای خالی فقط ته صفحه را بی‌دلیل بلند می‌کرد. */
  padding-bottom: calc(var(--tabbar-bottom) + var(--tabbar-h) + 28px + env(safe-area-inset-bottom));
}

/* صفحه‌هایی که دکمه‌ی ثبت دارند، به اندازه‌ی خودِ دکمه و فاصله‌اش بیشتر جا
   می‌گذارند تا آخرین ردیف زیر آن گم نشود. */

.app--fab { padding-bottom: calc(var(--tabbar-bottom) + var(--tabbar-h) + 12px + 54px + 28px + env(safe-area-inset-bottom)); }
/* عنوانِ کوچکِ چسبیده.
   ───────────────────
   تاپ‌بار حذف شد: تنها محتوایش یک کلیدِ تمِ دوحالته بود که هم شصت پیکسل از
   ارتفاعِ همیشگیِ صفحه می‌گرفت، و هم سه‌حالتِ واقعیِ تم (سیستم/روشن/تیره)
   را به دوحالت تقلیل می‌داد — کسی که یک بار می‌زد، دیگر راهی به «تبعیت از
   سیستم» نداشت. جایش در تنظیمات است، با هر سه گزینه.

   جای خالی‌اش را این می‌گیرد: با اسکرول، عنوانِ بزرگ که بالا رفت، اینجا
   کوچک ظاهر می‌شود. */
.minihead {
  position: fixed; inset-inline: 0; top: 0; z-index: 40;
  padding: calc(8px + env(safe-area-inset-top)) 18px 8px;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  border-bottom: 1px solid transparent;
  text-align: center;
  opacity: 0; transform: translateY(-6px);
  pointer-events: none;
  transition: opacity .18s, transform .18s, border-color .18s;
}
.minihead b { font-size: 1rem; font-weight: 700; }
.minihead.is-on { opacity: 1; transform: none; border-bottom-color: var(--border); }
.view {
  flex: 1;
  /* ناحیه‌ی امنِ بالا اینجاست، چون تاپ‌بار — که پیش‌تر آن را نگه می‌داشت —
     حذف شد. بدون این، عنوانِ بزرگ می‌رود زیر ساعت و آنتنِ خودِ گوشی. */
  padding: calc(10px + var(--safe-top, env(safe-area-inset-top))) 18px 16px;
  max-width: 640px; width: 100%; margin-inline: auto;
  outline: none;
}

.h1 { margin: 6px 0 16px; font-size: 1.75rem; font-weight: 800; }

/* ── تب‌بار شناور ─────────────────────────────────────────────────────── */

/* نوار تب و دکمه‌ی ثبت — چیدمانشان از MainTabContainer آمده:
   دکمه بالای نوار با ۱۲ پیکسل فاصله، و نوار با ۸ پیکسل از کف. */

.tabbar {
  position: fixed; z-index: 30;
  inset-inline: 12px;
  bottom: calc(var(--tabbar-bottom) + env(safe-area-inset-bottom));
  max-width: 480px; margin-inline: auto;
  display: flex; gap: 2px; padding: 10px 8px;
  background: color-mix(in srgb, var(--surface) 86%, transparent);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
  border: 1px solid var(--border);
  border-radius: 999px;
  box-shadow: 0 8px 20px rgba(0,0,0,.16), 0 2px 6px rgba(5,46,41,.06);
}
/* قرصِ فعال، یکی برای کل نوار — با translateX جابه‌جا می‌شود تا از تبی به
   تب دیگر بلغزد. جای آن را app.js از خودِ آیکون می‌خواند. */
.tabbar__pill {
  position: absolute; z-index: 0;
  top: 10px; left: 0;
  width: 54px; height: 36px;
  border-radius: 999px;
  background: var(--primary);
  box-shadow: 0 4px 12px -2px color-mix(in srgb, var(--primary) 55%, transparent);
  transition: transform .3s cubic-bezier(.2,.8,.2,1), width .3s cubic-bezier(.2,.8,.2,1);
  pointer-events: none;
}

.tab {
  position: relative; z-index: 1;
  flex: 1;
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 0;
  border: 0; background: none; cursor: pointer;
  /* ۱۱ پیکسل برای فارسی کوچک بود. رنگ همان کم‌رنگ می‌ماند: کنتراستش روی
     هر دو پس‌زمینه بالای ۷ به ۱ است، و پررنگ‌کردنش تفاوتِ تبِ فعال و
     غیرفعال را از بین می‌برد. */
  color: var(--text-muted);
  font-size: 12px; font-weight: 600;
  border-radius: 18px;
}
.tab__ic {
  display: grid; place-items: center;
  width: 54px; height: 36px; max-width: 100%;
  border-radius: 999px;
  transition: color .22s;
}
.tab svg { width: 20px; height: 20px; }
.tab[aria-current="page"] { color: var(--primary); font-weight: 700; }
.tab[aria-current="page"] .tab__ic { color: var(--primary-text); }
.tab:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; }

/* ── دکمه‌ی ثبت ──────────────────────────────────────────────────────── */

.fab {
  position: fixed; z-index: 25;
  /* در RTL، inset-inline-end لبه‌ی چپ است. دکمه باید سمت راست بنشیند —
     جایی که شست دست راست می‌رسد و اپ هم همان‌جا گذاشته — پس start. */
  inset-inline-start: 20px;
  /* ۸ (فاصله‌ی نوار از کف) + ۵۸ (بلندی نوار) + ۱۲ (فاصله‌ی همان VStack در
     اپ). چسبیدنش به نوار، هر دو را شبیه یک تکه‌ی به‌هم‌ریخته نشان می‌داد. */
  bottom: calc(var(--tabbar-bottom) + var(--tabbar-h) + 12px + env(safe-area-inset-bottom));
  display: inline-flex; align-items: center; gap: 8px;
  height: 52px; padding: 0 20px;
  border: 0; border-radius: 999px;
  background: var(--primary); color: var(--primary-text);
  font-weight: 700; font-size: .9375rem;
  box-shadow: 0 8px 22px -6px rgba(1,70,62,.45);
  cursor: pointer;
  transition: transform .16s cubic-bezier(.34,1.4,.64,1);
}
.fab svg { width: 19px; height: 19px; flex: none; }

.fab:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; }

/* ── اجزای مشترک ─────────────────────────────────────────────────────── */

.card {
  background: var(--surface); border-radius: 22px;
  padding: 18px; margin-bottom: 12px;
  box-shadow: 0 1px 3px rgba(5,46,41,.06);
}
.card--flush { padding: 4px 16px; }

.section-title {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  margin: 20px 2px 10px;
  font-size: 1.0625rem; font-weight: 700;
}
.section-title span { font-size: .8125rem; font-weight: 500; color: var(--text-muted); }

.muted { color: var(--text-muted); }
.small { font-size: .8125rem; }
/* عدد و علامتش، یک واحدِ مستقل.
   ─────────────────────────────
   در بافتِ راست‌به‌چپ، علامتِ چسبیده به عدد بسته به همسایه‌هایش می‌تواند
   آن‌طرفِ عدد بنشیند. در یک دفترچه‌ی حساب، جابه‌جاییِ منها یعنی کاربر
   نمی‌داند پول رفته یا آمده. isolate آن را از همسایه‌ها جدا می‌کند بدون
   اینکه ترتیبِ فعلی — که همان چیزی است که اپ آیفون هم نشان می‌دهد — عوض
   شود؛ bdi این را عوض می‌کرد، چون بدون حرفِ قوی به چپ‌به‌راست می‌افتد. */
.num { font-variant-numeric: tabular-nums; unicode-bidi: isolate; }
/* ── سه لایه‌ی رنگ ──────────────────────────────────────────────────────
   ۱) ثبت — بی‌قضاوت: مبلغِ یک تراکنش یا قسط رنگ نمی‌گیرد؛ جهت با علامت و آیکون.
   ۲) نتیجه — قضاوتِ مجاز، کم‌شدت: `.pos` برای خوب، `.outcome-bad` (کهربایی)
      برای بد — مثلِ خالصِ منفیِ ماه. نتیجه‌ی بد خطا نیست.
   ۳) اشکال — `.fault` (قرمز)، فقط وقتی کاربر باید کاری بکند: سررسیدِ گذشته،
      چکِ برگشتی، خطای همگام‌سازی.
   پیش از رنگ‌کردنِ هر چیزی: «کاربر باید کاری بکند؟» اگر نه، قرمز نیست. «اپ
   دارد قضاوت می‌کند؟» اگر نه، رنگ نیست.
   (`.neg` قبلاً هر دو معنا را داشت و هیچ توکنی نمی‌توانست نجاتش بدهد.) */
.pos { color: var(--positive); }
.outcome-bad { color: var(--warning); }
.fault { color: var(--negative); }

.empty { text-align: center; padding: 40px 20px; color: var(--text-muted); }
.empty__mark {
  width: 54px; height: 54px; margin: 0 auto 14px; padding: 14px;
  border-radius: 18px; background: var(--primary-subtle); color: var(--primary);
}
.empty b { display: block; color: var(--text); margin-bottom: 5px; }
.empty p { margin: 0; font-size: .9375rem; line-height: 1.9; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 50px; padding: 0 20px;
  border: 0; border-radius: 999px;
  font-weight: 700; font-size: .9375rem; cursor: pointer;
  transition: background .15s, transform .12s;
}

.btn:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.btn--primary { background: var(--primary); color: var(--primary-text); }
.btn--primary:active { background: var(--primary-active); }
/* حاشیه لازم است، سایه کافی نیست.
   ───────────────────────────────
   این دکمه رنگ `surface` دارد و وقتی داخل کارتی با همان رنگ می‌نشیند —
   یعنی تقریباً همه‌جای تنظیمات — فقط سایه‌ی محوی از آن می‌ماند. در حالت
   تاریک آن سایه هم عملاً دیده نمی‌شود و دکمه به یک متن شناور تبدیل
   می‌شود که کاربر نمی‌فهمد قابل زدن است. */
.btn--ghost {
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border);
  box-shadow: 0 1px 3px rgba(5,46,41,.07);
}
/* ⚠️ این کلاس سال‌ها در «confirmSheet» به کار می‌رفت و هیچ‌وقت تعریف نشده بود:
   دکمه‌ی «حذف» با رنگِ پیش‌فرضِ مرورگر (خاکستری) و متنی ناخوانا کشیده می‌شد —
   به‌خصوص در تمِ تاریک (گزارشِ مالک، ۱۴۰۵/۰۶/۳۰). `_test/css.html` حالا
   وجودش را می‌سنجد. */
.btn--danger { background: var(--negative); color: var(--on-negative); }
.btn--danger:active { background: var(--negative-active); }
.btn--block { width: 100%; }
.danger { color: var(--negative); }
/* ⚠️ `minmax(0, 1fr)`، نه ستونِ خودکار: یک متنِ بی‌شکستِ طولانی (زیرعنوانِ
   کارتِ اقساط) ستونِ خودکار را پهن‌تر از صفحه می‌کرد و کارت از لبه‌ی چپ
   بیرون می‌زد — روی گوشیِ مالک دیده شد. */
.stack { display: grid; grid-template-columns: minmax(0, 1fr); gap: 9px; }

/* سگمنت: قرص سفید روی نوار کم‌رنگ */
.seg {
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 3px;
  padding: 3px; margin-bottom: 14px;
  background: var(--bg-subtle); border-radius: 999px;
}
.seg button {
  min-height: 40px; border: 0; border-radius: 999px;
  background: none; color: var(--text-muted);
  font-weight: 600; font-size: .875rem; cursor: pointer;
  transition: background .16s, color .16s;
}
.seg button[aria-selected="true"],
.seg button[aria-checked="true"] {
  background: var(--surface); color: var(--text); font-weight: 700;
  box-shadow: 0 1px 3px rgba(5,46,41,.1);
}

/* ── نان تست ─────────────────────────────────────────────────────────── */

/* نان تست: بالای نوار تب و دکمه‌ی ثبت، از روی همان متغیرها — نه یک عددِ
   ثابت که با هر تغییرِ بلندیِ نوار، زیر دکمه گم شود. */
.toast {
  position: fixed; z-index: 60;
  inset-inline: 16px;
  bottom: calc(var(--tabbar-bottom) + var(--tabbar-h) + 12px + 54px + 14px + env(safe-area-inset-bottom));
  max-width: 420px; margin-inline: auto;
  padding: 13px 16px; border-radius: 16px;
  background: var(--ink-900); color: var(--white);
  font-size: .875rem; text-align: center;
  box-shadow: 0 10px 30px -10px rgba(0,0,0,.5);
  animation: rise .22s ease;
}
.toast--bad { background: var(--negative); }

/* نوار «برگرداندن» عمداً گره‌ی خودش را دارد، نه گره‌ی نان تست.
   ───────────────────────────────────────────────────────────
   «برگرداندن» جایگزینِ پرسیدنِ «مطمئنی؟» است، یعنی تنها تورِ ایمنیِ حذف.
   وقتی هر دو یک گره داشتند، اولین پیامِ بعدی — حتی یک «ذخیره شد» —
   دکمه‌ی برگرداندن را بی‌صدا می‌بلعید. تورِ ایمنی‌ای که ممکن است ناپدید
   شود، تورِ ایمنی نیست. */
.undobar {
  position: fixed; z-index: 61;
  inset-inline: 16px;
  bottom: calc(var(--tabbar-bottom) + var(--tabbar-h) + 12px + 54px + 14px + env(safe-area-inset-bottom));
  max-width: 420px; margin-inline: auto;
  display: flex; align-items: center; gap: 10px;
  padding: 11px 12px 11px 16px; border-radius: 16px;
  background: var(--ink-900); color: var(--white);
  font-size: .875rem;
  box-shadow: 0 10px 30px -10px rgba(0,0,0,.5);
  animation: rise .22s ease;
  touch-action: none;
}
/* وقتی هر دو با هم هستند، پیامِ عادی می‌رود بالاتر تا روی هم نیفتند. */
.toast--stacked { bottom: calc(var(--tabbar-bottom) + var(--tabbar-h) + 12px + 54px + 74px + env(safe-area-inset-bottom)); }
/* روی شیت (shared.js ← toastLayer): نوار تهِ همان شیت می‌نشیند، نه بالای
   نوارِ زبانه‌ها که زیرِ شیت پنهان است. صفحه‌کلید هم بالا می‌بردش. */
.sheet > .toast, .sheet > .undobar {
  bottom: 16px;
}
.sheet > .toast--stacked { bottom: 76px; }
.undobar span { flex: 1; min-width: 0; }
.toast__undo {
  flex: none; padding: 6px 14px;
  border: 0; border-radius: 999px;
  background: rgba(255,255,255,.22); color: inherit;
  font-weight: 700; font-size: .8125rem; cursor: pointer;
}
.toast__close {
  flex: none; width: 44px; height: 44px; padding: 0;
  display: grid; place-items: center;
  border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(255,255,255,.12); color: inherit;
}
.toast__close svg {
  width: 18px; height: 18px; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round;
}
.toast__close:active { background: rgba(255,255,255,.24); }
@keyframes rise { from { opacity: 0; transform: translateY(10px) } }
/* رفتنِ نان تست هم حرکت دارد، نه فقط آمدنش — تند و با ease-in. */
.toast--out { animation: sink var(--dur-1) var(--ease-in) forwards; }
@keyframes sink { to { opacity: 0; transform: translateY(6px) } }

/* ── داشبورد ─────────────────────────────────────────────────────────── */

/* نوار صندوق پیامک: فقط وقتی کاری هست دیده می‌شود. */
.inbox {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 12px 14px; margin-bottom: 12px;
  border: 1px solid var(--primary-border); border-radius: 20px;
  background: var(--primary-subtle); color: var(--text);
  text-align: start; cursor: pointer;
}
.inbox__ic {
  width: 40px; height: 40px; padding: 10px; flex: none;
  border-radius: 50%; background: var(--primary); color: var(--primary-text);
}
.inbox__txt { flex: 1; min-width: 0; }
.inbox__txt b { display: block; font-size: .9375rem; }
.inbox__chev { width: 18px; height: 18px; flex: none; color: var(--text-muted); }

/* کارت‌های حساب: افقی و کشیدنی، مثل اپ. */
.cards {
  display: flex; gap: 10px;
  overflow-x: auto; scroll-snap-type: x mandatory;
  margin: 0 -18px 14px; padding: 2px 0 6px;
  scroll-padding-inline: 18px;
  scrollbar-width: none;
}
.cards::before, .cards::after { content: ''; flex: 0 0 8px; }
.cards::-webkit-scrollbar { display: none; }
.cards > * { scroll-snap-align: end; flex: none; }

.bal {
  width: 100%; padding: 18px; border-radius: 22px;
  background: linear-gradient(155deg, var(--teal-600), var(--teal-900));
  color: var(--white);
}
/* داخل نوارِ افقیِ داشبورد عرض ثابت می‌گیرد تا کارت بعدی از لبه پیدا باشد؛
   جای دیگر (صورت‌حساب) تمام‌عرض است. پیش‌تر عرض ثابت روی خودِ .bal بود و
   کارت موجودی در صورت‌حساب، یک‌سومِ صفحه خالی کنارش می‌گذاشت. */
.cards > .bal { width: 250px; }
.bal__top { display: flex; align-items: center; justify-content: space-between; }
/* svg بدون قید اندازه، کل ظرفش را پر می‌کند. هر آیکون باید ابعاد صریح
   داشته باشد؛ این خط، آن‌هایی را که از قلم می‌افتند می‌گیرد. */
.bal__top svg { width: 19px; height: 19px; flex: none; }
/* ناحیه‌ی لمسی ۴۴ پیکسل است حتی با آیکون ۱۹ پیکسلی — کوچک‌تر از این روی
   گوشی با انگشت زده نمی‌شود. margin منفی جلوی جابه‌جا شدن چیدمان را می‌گیرد. */
.bal__eye {
  display: grid; place-items: center; width: 44px; height: 44px;
  margin: -12px -12px -12px 0; padding: 0;
  background: none; border: 0; color: inherit; cursor: pointer; border-radius: 50%;
}
.bal__eye:hover svg { opacity: 1; }

/* ── سطحِ لمسِ ۴۴ پیکسلی، بدونِ تغییرِ ظاهر ──────────────────────────────
   همان الگوی `.due__tick`: یک `::after` نامرئی که سطحِ ضربه را به آستانه
   می‌رساند و دایره‌ی دیده‌شده همان اندازه‌ی قبلی می‌ماند. `max()` یعنی
   دکمه‌ای که خودش بزرگ‌تر است کوچک نمی‌شود. `_test/css.html` وجودِ این
   قاعده را برای هر کلاس نگه می‌دارد. */
.sheet__close, .catrow__act, .sheetmenu__btn, .monthnav button, .datechip, .quickamt button,
.gs__x, .updbar__x, .instbar__x, .seg--sm button { position: relative; }
.sheet__close::after, .catrow__act::after, .sheetmenu__btn::after, .monthnav button::after,
.bigamt__clear::after, .datechip::after, .quickamt button::after,
.gs__x::after, .updbar__x::after, .instbar__x::after, .seg--sm button::after {
  content: ''; position: absolute; top: 50%; left: 50%;
  width: max(100%, 44px); height: max(100%, 44px);
  transform: translate(-50%, -50%);
}

/* حلقه‌ی فوکوس برای کاربرِ صفحه‌کلید. روی گوشی دیده نمی‌شود (`:focus-visible`
   با لمس روشن نمی‌شود)، پس هزینه‌ای ندارد. `:where` ویژگی را صفر می‌کند تا
   هر حلقه‌ی اختصاصی‌تری که از قبل هست برنده بماند. */
:where(button, a[href], input, select, textarea, summary, [role="tab"], [role="radio"],
       [tabindex]:not([tabindex="-1"])):focus-visible {
  outline: 2px solid var(--focus-ring); outline-offset: 2px;
}

/* فقط برای صفحه‌خوان. */
.sr-only {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* تکانِ یک‌باره‌ی «حذف»، وقتی کاربر کاهشِ حرکت را خواسته. */
.swipetip { margin: 0 0 8px; }

/* شورتکات: پیشنهادِ یک‌باره بعد از دومین چسباندنِ دستی. */
.autohint--nudge { box-shadow: inset 0 0 0 1.5px var(--primary); background: var(--primary-subtle); }

/* نکته‌ها (تنظیمات ← درباره). */
.bal__eye[aria-pressed="true"] svg { opacity: 1; }
/* ⚠️ متنِ کم‌رنگ با `opacity` نه — با رنگِ صریح، و اینجا یعنی سفیدِ کامل.
   سفید با شفافیتِ ۰٫۷۲ روی بالای گرادیان (teal-600) کنتراستِ ۳٫۱ داشت،
   زیرِ آستانه‌ی ۴٫۵. حتی سفیدِ کامل روی همان نقطه ۴٫۵۴ است، یعنی جایی
   برای کم‌رنگ‌کردن نمانده؛ سلسله‌مراتب با اندازه و وزن ساخته می‌شود. */
.bal__top span { font-size: .8125rem; font-weight: 600; }
.bal__amount { margin: 8px 0 4px; font-size: 1.625rem; font-weight: 800; }
.bal__sub { margin: 0; font-size: .75rem; font-weight: 500; }

/* حالا دکمه است نه div — ضربه رویش صورت‌حساب حساب را باز می‌کند. تنظیمات
   پیش‌فرض دکمه‌ی مرورگر (حاشیه، وسط‌چین، فونت خودش) باید صریح پاک شوند،
   وگرنه کارت با کارت‌های دیگر ردیف نمی‌ماند. */
.acct {
  width: 175px; padding: 16px; border-radius: 22px;
  background: var(--surface); box-shadow: 0 1px 3px rgba(5,46,41,.06);
  border: 0; text-align: start; font: inherit; color: inherit;
  cursor: pointer; flex: none; display: block;
  transition: transform .14s;
}

.acct:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.acct__top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.acct__top b { font-size: .875rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acct__ic {
  width: 30px; height: 30px; padding: 7px; flex: none;
  border-radius: 9px; background: var(--primary-subtle); color: var(--primary);
}
.acct__amount { margin: 10px 0 0; font-size: 1.0625rem; font-weight: 700; }

/* فاصله‌ی پایین با بقیه‌ی کارت‌ها یکی است. ۴ پیکسل بود در حالی که هر
   `.card` دوازده دارد — و کارتِ بودجه دقیقاً زیر همین ردیف می‌نشیند و
   چسبیده به‌نظر می‌رسید. */
.monthrow { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 12px; }

/* دکمه‌اند، نه کارتِ ساکن: ضربه، تراکنش‌های همان جهت را باز می‌کند. */
.mcard {
  padding: 15px; border-radius: 20px; width: 100%;
  border: 0; font: inherit; color: inherit; text-align: start; cursor: pointer;
  background: var(--surface); box-shadow: 0 1px 3px rgba(5,46,41,.06);
  transition: transform .12s;
}

.mcard__row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.mcard__go { width: 15px; height: 15px; flex: none; opacity: .45; }
.mcard--in { background: var(--primary-subtle); box-shadow: none; }
.mcard__ic {
  display: block; width: 30px; height: 30px; padding: 7px;
  border-radius: 50%; background: var(--surface); color: var(--primary);
}
.mcard--out .mcard__ic { color: var(--text-muted); background: var(--bg-subtle); }
.mcard span { display: block; font-size: .75rem; color: var(--text-muted); }
.mcard b { font-size: 1rem; font-weight: 700; }

/* کارت‌های ماهِ داشبورد: نوع با رنگ، ضربه‌خوربودن با ردیفِ پیوندِ پایین.
   هر دو کارت هم‌وزن‌اند — قبلاً درآمد پس‌زمینه‌ی رنگی داشت و هزینه نه، و
   همین عدمِ تقارن خودش یک معنای ناخواسته می‌ساخت. */
.mcard--flow {
  display: flex; flex-direction: column; gap: 6px; padding: 14px 15px 0;
  --flow: var(--positive);
  background: color-mix(in srgb, var(--flow) 9%, var(--surface));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--flow) 22%, transparent);
}
.mcard--flow.mcard--out { --flow: var(--outflow); }
.mcard--flow .mcard__label { display: flex; align-items: center; gap: 7px; font-size: .8125rem; }
.mcard__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--flow); flex: none; }
.mcard--flow .mcard__amt { font-size: 1.125rem; color: var(--flow); }
.mcard--flow .mcard__more {
  display: flex; align-items: center; gap: 4px;
  margin: 6px -15px 0; padding: 10px 15px;
  border-top: 1px solid color-mix(in srgb, var(--flow) 18%, transparent);
  font-size: .75rem; font-weight: 700; color: var(--primary);
}
.mcard__more svg { width: 13px; height: 13px; flex: none; }

.monthhead {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  margin: 18px 2px 10px;
}
.monthhead b { font-size: 1rem; }

/* ردیف عمومی با آیکون دایره‌ای */
.irow {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 12px 0; min-height: 60px;
  border: 0; border-top: 1px solid var(--border);
  background: none; text-align: start; cursor: pointer;
}
.irow:first-child { border-top: 0; }
.irow__ic {
  width: 38px; height: 38px; padding: 10px; flex: none;
  border-radius: 50%; background: var(--bg-subtle); color: var(--text-muted);
}
.irow__ic--in { background: var(--primary-subtle); color: var(--primary); }
.irow__main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.irow__main b { font-size: .9375rem; }
.irow__main span { font-size: .75rem; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.irow__amt { font-weight: 700; flex: none; }

/* ── جست‌وجو و ناوبری ماه ────────────────────────────────────────────── */

.search { position: relative; display: block; margin-bottom: 12px; }
.search svg {
  position: absolute; inset-inline-start: 15px; top: 50%; transform: translateY(-50%);
  width: 18px; height: 18px; color: var(--text-muted); pointer-events: none;
  /* آیکونِ ذره‌بین خطی است؛ قاعده‌ی سراسریِ `svg { fill: currentColor }`
     دایره‌اش را پر می‌کرد و در تبِ تراکنش‌ها یک نقطه‌ی توپر دیده می‌شد. */
  fill: none; stroke: currentColor; stroke-width: 2;
}
.search input {
  width: 100%; min-height: 48px; padding-inline: 44px 16px;
  border: 0; border-radius: 999px;
  background: var(--surface); color: var(--text);
  font-family: inherit; font-size: max(16px, 1rem);
  box-shadow: 0 1px 3px rgba(5,46,41,.06);
}
.search input:focus-visible { outline: 2px solid var(--focus-ring); }
.search input::-webkit-search-cancel-button { -webkit-appearance: none; }

.monthnav {
  display: flex; align-items: center; justify-content: space-between;
  padding: 4px; margin-bottom: 14px;
  border-radius: 999px; background: var(--surface);
  box-shadow: 0 1px 3px rgba(5,46,41,.06);
}
.monthnav b { font-size: .9375rem; }
.monthnav button {
  width: 40px; height: 40px; border: 0; border-radius: 50%;
  background: none; color: var(--primary); font-size: 1.375rem; cursor: pointer;
}
.monthnav button:active { background: var(--bg-subtle); }

.daygroup { margin-bottom: 16px; }
.daygroup__head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  margin-bottom: 6px; padding-inline: 4px;
}
.daygroup__head b { font-size: .875rem; }

/* ── گزارش ───────────────────────────────────────────────────────────── */

.stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 12px; }
.stat {
  background: var(--surface); border-radius: 16px;
  padding: 12px 12px;
  box-shadow: 0 1px 3px rgba(5,46,41,.06);
}
.stat span { display: block; margin-bottom: 2px; font-size: .75rem; color: var(--text-muted); }
.stat b { font-size: .9375rem; }

/* سرتیترِ کارتِ دسته‌ها: جمعِ بازه. وسطِ حلقه جای دسته‌ی فعال است، نه جمع. */
.sharehead {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  margin: 0 0 10px; font-size: .8125rem; color: var(--text-muted);
}
.sharehead b { font-size: 1.0625rem; color: var(--text); }

/* حلقه‌ی سهمِ دسته‌ها با دسته‌ی فعال در مرکز (reports.js ← `donut`). */
.donut { position: relative; width: 220px; max-width: 100%; margin: 4px auto 14px; }
.donut svg { display: block; width: 100%; height: auto; overflow: visible; }
/* ضخامت‌ها یک‌جا؛ حرکتِ پررنگ‌شدن از همین‌ها می‌خواند و اگر ضخامت عوض شود
   دروغ نمی‌گوید. */
.donut { --ring: 28px; --ring-on: 38px; }
.donut__arc { stroke-width: var(--ring); transition: opacity 360ms var(--ease-move); }
/* بقیه‌ی برش‌ها کم‌رنگ می‌شوند تا برشِ انتخاب‌شده از دور هم دیده شود. */
.donut__arc:not(.is-on) { opacity: .5; }
.donut__on { stroke-width: var(--ring-on); }
.donut__hit { cursor: pointer; }
.donut__tick {
  fill: none; stroke-width: 2.5; stroke-linecap: round; pointer-events: none;
  stroke-dasharray: 22;
}
.donut__center {
  position: absolute; inset: 0;
  display: grid; place-content: center; justify-items: center; gap: 1px;
  text-align: center; pointer-events: none;
}
.donut__name {
  display: flex; align-items: center; gap: 7px; max-width: 120px;
  font-size: .8125rem; font-weight: 600; color: var(--text);
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.donut__name i { flex: none; width: 9px; height: 9px; border-radius: 50%; box-shadow: 0 0 0 1px var(--border-strong); }
.donut__center b { font-size: 1.375rem; font-weight: 800; line-height: 1.3; }
.donut__amt { font-size: .75rem; color: var(--text-muted); }

/* ⚠️ انتخاب باید «دیده» شود، نه فقط رخ دهد.
   ─────────────────────────────────────
   نسخه‌ی اول ۱۸۰ms بود و ضخامت فقط از ۲۸ به ۳۴ می‌رفت. مالک: «خیلی کوتاه
   است؛ کاربر ممکن است فکر کند باگ است، نه یک نمایشِ زیبا.» حالا برش با یک
   جهشِ کوچک (--ease-pop، مجاز برای آمدنِ چیزِ کوچک) تا ۳۸ بزرگ می‌شود،
   بقیه کم‌رنگ می‌شوند، خط کشیده می‌شود و متنِ مرکز از پایین بالا می‌آید. */
.donut__on--in { animation: donutGrow 440ms var(--ease-pop) both; }
.donut__tick--in { animation: donutTick 360ms var(--ease-out) 120ms both; }
.donut__center--in { animation: donutRise 360ms var(--ease-out) both; }
@keyframes donutGrow { from { stroke-width: var(--ring); } to { stroke-width: var(--ring-on); } }
@keyframes donutTick { from { stroke-dashoffset: 22; } to { stroke-dashoffset: 0; } }
@keyframes donutRise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ورودِ حلقه (بازه یا عدسیِ تازه): برش‌ها یکی‌یکی کشیده می‌شوند (`--d` روی هر
   برش)، بعد برشِ فعال بزرگ می‌شود، خطش کشیده می‌شود و مرکز می‌آید. */
.donut--intro .donut__arc { animation: arcDraw 620ms var(--ease-out) var(--d) both; }
.donut--intro .donut__on { animation: donutGrow 440ms var(--ease-pop) 560ms both; }
.donut--intro .donut__tick { animation: donutTick 360ms var(--ease-out) 820ms both; }
.donut--intro .donut__center { animation: donutRise 420ms var(--ease-out) 320ms both; }
@keyframes arcDraw { from { stroke-dasharray: 0 var(--c); } }

/* `minmax(0, 1fr)` و بی‌پدینگ: ستون‌ها دکمه‌اند و پدینگِ پیش‌فرضِ دکمه به‌علاوه‌ی
   پهنای نامِ ماه، شش ستون را در گوشیِ ۳۲۰ پیکسلی ۲ پیکسل از صفحه بیرون می‌زد —
   و کلِ صفحه کمی به پهلو اسکرول می‌شد. نامِ ماه در صفحه‌ی باریک کوچک‌تر می‌شود. */
.bars { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 8px; align-items: end; }
.bars__col { display: grid; gap: 7px; justify-items: center; min-width: 0; padding: 0; }
/* نامِ ماه بریده نمی‌شود: اگر یکی دو پیکسل از ستون پهن‌تر باشد («اردیبهشت»)،
   در فاصله‌ی بینِ ستون‌ها می‌نشیند. ستون (minmax(0)) با آن پهن نمی‌شود. */
.bars__col > span { white-space: nowrap; }
@media (max-width: 360px) {
  .bars { gap: 6px; }
  .bars__col > span { font-size: .625rem; }
}
.bars__track { width: 100%; height: 104px; display: flex; align-items: flex-end; }
.bars__bar {
  width: 100%; border-radius: 8px 8px 3px 3px;
  background: linear-gradient(180deg, var(--teal-400), var(--teal-700));
  transition: height .3s;
}

/* ── سررسید ──────────────────────────────────────────────────────────── */

.due { display: flex; align-items: center; gap: 12px; padding: 12px 0; border-top: 1px solid var(--border); }
.due:first-child { border-top: 0; }
.due__main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.due__main b { font-size: .9375rem; }
.due__main span { font-size: .75rem; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* مبلغ بالا، دکمه زیرش: کنارِ هم، ستونِ متن روی گوشی به صد پیکسل له می‌شد. */
.due__side { display: flex; flex-direction: column; align-items: flex-end; gap: 7px; flex: none; }
/* ⚠️ دیده‌شدنش ۳۸ پیکسل است، ناحیه‌ی لمسش ۴۴.
   ──────────────────────────────────────────
   این تنها کنترلی است که پول جابه‌جا می‌کند و درست چسبیده به ناحیه‌ی
   قابلِ‌ضربه‌ی خودِ ردیف — یعنی خطای چند پیکسلی، به‌جای تسویه، صفحه‌ی
   ویرایش را باز می‌کند. بزرگ‌کردنِ خودِ دایره ردیف را شلوغ می‌کرد، پس
   `::after` نامرئی سطح را بدونِ تغییرِ ظاهر به آستانه می‌رساند. */
.due__tick {
  position: relative;
  display: inline-flex; align-items: center; gap: 5px;
  min-height: 34px; padding: 0 12px 0 10px; flex: none;
  border: 1px solid var(--primary-border); border-radius: 999px;
  background: var(--primary-subtle); color: var(--primary); cursor: pointer;
  font-family: inherit; font-size: .8125rem; font-weight: 700; white-space: nowrap;
  transition: background .15s, color .15s;
}
.due__tick::after {
  content: ''; position: absolute; top: 50%; left: 50%;
  width: 44px; height: 44px; transform: translate(-50%, -50%);
}
.due__tick svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2.6; }
.due__tick:active { background: var(--primary); color: var(--primary-text); }
/* راهِ برگشتِ همیشگی از یک پرداخت: کم‌وزن‌تر از «پرداخت»، ولی دیده‌شدنی. */
.due__undo {
  position: relative; min-height: 30px; padding: 0 10px;
  border: 1px solid var(--border-strong); border-radius: 999px;
  background: none; color: var(--text-muted); cursor: pointer;
  font-family: inherit; font-size: .75rem; font-weight: 600;
}
.due__undo::after { content: ''; position: absolute; top: 50%; left: 50%; width: max(100%, 44px); height: 44px; transform: translate(-50%, -50%); }
/* زیرعنوانِ کارتِ اقساط می‌شکند، نه اینکه با «…» بریده شود: «۳۳ روز دیگر»
   درست همان تکه‌ای است که بریده می‌شد. */
.plancard .due__main span { white-space: normal; }
/* نوار رنگی لبه‌ی راست است، نه چپ: در راست‌به‌چپ چشم از راست شروع می‌کند
   و box-shadow با آفست مثبت، نوار را روی لبه‌ی چپ می‌گذارد. */
.due--soon { box-shadow: inset -3px 0 0 var(--warning); }
.due--late { box-shadow: inset -3px 0 0 var(--negative); }

/* سه بخشِ سررسید. کارت‌های هم‌اندازه، نه یک نوار قرصی: هرکدام یک صفحه‌ی
   کامل پشتشان است، نه یک فیلتر. */
/* هم‌زبان با بقیه‌ی انتخاب‌گرهای اپ (`.seg`): زمینه‌ی خاکستری و گزینه‌ی
   انتخاب‌شده‌ی برآمده. پیش‌تر سبزِ پررنگِ پُر بود — سه شکلِ متفاوت برای یک
   کار در سه تب. آیکن‌ها می‌مانند، چون هر بخش یک صفحه‌ی کامل است. */
.dtabs {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; margin-bottom: 10px;
  padding: 4px; border-radius: 16px; background: var(--bg-subtle);
}
.dtab {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  min-height: 56px; padding: 8px 4px;
  border: 0; border-radius: 13px;
  background: none; color: var(--text-muted);
  font-size: .8125rem; font-weight: 600; cursor: pointer;
  transition: background .16s, color .16s;
}
.dtab i { display: block; width: 18px; height: 18px; }
.dtab[aria-selected="true"] {
  background: var(--surface-raised); color: var(--text); font-weight: 700;
  box-shadow: 0 2px 6px rgba(0,0,0,.18);
}
.dtab[aria-selected="true"] i { color: var(--primary); }

/* کارت خلاصه: یک عدد که وضعیت همان بخش را می‌گوید. */
.duesum { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 15px 18px; }
.duesum__v { display: block; font-size: 1.25rem; line-height: 1.5; }
.duesum__v--neg { color: var(--negative); }
.duesum__v--warn { color: var(--warning); }
.duesum__v--pos { color: var(--positive); }
.duesum__v--muted { color: var(--text-muted); }
.duesum__v--plain { color: var(--text); }
.latepill {
  flex: none; padding: 5px 10px; border-radius: 999px;
  background: color-mix(in srgb, var(--negative) 13%, transparent);
  color: var(--negative); font-size: .75rem; font-weight: 700;
}

/* برچسب وضعیت، کنار عنوان ردیف. */
.statpill {
  display: inline-block; padding: 1px 7px; border-radius: 999px;
  font-size: .6875rem; font-weight: 700; vertical-align: middle;
}
.statpill--pos { background: color-mix(in srgb, var(--positive) 14%, transparent); color: var(--positive); }
.statpill--warn { background: color-mix(in srgb, var(--warning) 16%, transparent); color: var(--on-warning-wash); }
.statpill--neg { background: color-mix(in srgb, var(--negative) 13%, transparent); color: var(--on-negative-wash); }
.statpill--muted { background: var(--bg-subtle); color: var(--text-muted); }

.due__ic { width: 34px; height: 34px; padding: 8px; flex: none; border-radius: 12px; }
.due__ic--pos { background: color-mix(in srgb, var(--positive) 14%, transparent); color: var(--positive); }
.due__ic--warn { background: color-mix(in srgb, var(--warning) 16%, transparent); color: var(--on-warning-wash); }
.due__ic--neg { background: color-mix(in srgb, var(--negative) 13%, transparent); color: var(--on-negative-wash); }
/* «بدهی» جهت است، نه هشدار: بدهکار بودن حالتِ طبیعیِ مالیِ آدم‌هاست. */
.due__ic--out { background: color-mix(in srgb, var(--outflow) 14%, transparent); color: var(--outflow); }
.due__ic--muted { background: var(--bg-subtle); color: var(--text-muted); }

/* کارت یک برنامه‌ی اقساط. */
.plan {
  display: grid; width: 100%; margin: 0; padding: 16px;
  grid-template-columns: 34px 1fr auto;
  grid-template-areas: "ic main count" "next next amt" "bar bar bar";
  gap: 8px 10px; align-items: center;
  border: 0; text-align: start; cursor: pointer;
  font: inherit; color: inherit;
}
.plan__ic { grid-area: ic; width: 34px; height: 34px; padding: 8px; border-radius: 12px; background: var(--bg-subtle); color: var(--primary); }
.plan__main { grid-area: main; min-width: 0; display: block; }
.plan__main b { display: block; font-size: .9375rem; }
.plan__main span { display: block; }
.plan__count { grid-area: count; }
.plan__next { grid-area: next; color: var(--text-muted); }
.plan__amt { grid-area: amt; font-weight: 700; font-size: .9375rem; }
.plan__bar { grid-area: bar; margin-top: 2px; }

/* ── شیت ─────────────────────────────────────────────────────────────── */

.sheet {
  width: 100%; max-width: 520px;
  padding: 0;
  border: 0; border-radius: 28px 28px 0 0;
  background: var(--bg); color: var(--text);

  /* Anchor to the visible viewport without changing the document scroll. */
  position: fixed; inset: auto 0 var(--vv-bottom, 0px);
  margin: 0 auto;
  /* ⚠️ `env(safe-area-inset-top)` حذف‌شدنی نیست.
     ─────────────────────────────────────────
     بدون آن، وقتی صفحه‌کلید باز است شیت تا خودِ بالای صفحه کش می‌آید و
     عنوان و ضربدرش **روی نوارِ وضعیت** می‌افتند — ساعت و آنتن و باتری از
     زیرِ متنِ فارسی بیرون می‌زنند. روی اسکرین‌شاتِ گوشیِ مالک دیده شد.

     ۸ پیکسلِ اضافه هم هست تا سرِ شیت دقیقاً به مرزِ نوارِ وضعیت نچسبد؛
     چسبیدن، حتی بدونِ همپوشانی، شلوغ به‌نظر می‌رسد. */
  max-height: min(
    92dvh,
    calc(var(--vv-height, 100dvh) - env(safe-area-inset-top, 0px) - 8px)
  );
  overflow: hidden;
  /* یک اعلانِ transition برای شیت، همین‌جا. پیش‌تر دو قاعده‌ی دورافتاده
     بودند و دومی (فقط transform) بی‌صدا این یکی را می‌پوشاند — یعنی
     margin-bottom و max-height هرگز حرکت نداشتند. همان رفتارِ واقعی حفظ شد. */
  transition: transform var(--dur-2) var(--ease-move);
  display: flex; flex-direction: column;
  animation: slideUp var(--dur-2) var(--ease-out);
}
/* استایل مؤلف بر قانون dialog:not([open]) مرورگر غلبه می‌کند، پس دیالوگِ
   بسته روی صفحه می‌ماند. باید صریح خاموشش کنیم. */
.sheet:not([open]) { display: none; }
.sheet::backdrop {
  background: rgba(5,46,41,.4); backdrop-filter: blur(2px);
  animation: backdropIn var(--dur-2) var(--ease-out);
}
@keyframes slideUp { from { transform: translateY(100%) } }

/* حرکتِ عمق (shared.js ← sheet): شیتِ رویی از چپ می‌آید و به چپ برمی‌گردد؛
   شیتِ زیری کمی به راست و عقب می‌رود. پس‌زمینه‌ی دومی کم‌رنگ‌تر است، وگرنه
   دو تیرگیِ روی هم صفحه را سیاه می‌کرد. */
.sheet.sheet--deep { animation: slideDeep var(--dur-3) var(--ease-out); }
.sheet--deep::backdrop { background: rgba(5,46,41,.18); }
@keyframes slideDeep { from { transform: translateX(-100%); } }
.sheet.sheet--under {
  transform: none;
  filter: brightness(.9);
  transition: transform var(--dur-3) var(--ease-out), filter var(--dur-3) var(--ease-out);
}
@keyframes backdropIn { from { opacity: 0 } }

/* Native dialog stays modal during exit; JS releases it after the transition. */
.sheet.sheet--out {
  display: flex; z-index: 90;
  transform: translateY(100%) !important;
  pointer-events: none;
  animation: none;
  transition: transform var(--dur-2) var(--ease-in);
}
.sheet.sheet--deep.sheet--out {
  transform: translateX(-100%) !important;
  animation: none;
  transition: transform var(--dur-2) var(--ease-in);
}
/* Keep the visible-viewport bottom anchor on wider screens too. */
@media (min-width: 560px) { .sheet { margin-top: auto; border-radius: 28px; } }

/* ── صفحه (shared.js ← sheet({ page: true })) ──────────────────────────
   دنگ یک صفحه است، نه شیت: تمام‌قد، از کنار می‌آید (در راست‌به‌چپ «جلو» یعنی
   از چپ) و به همان‌جا برمی‌گردد. قاعده‌ها از `.sheet` پررنگ‌ترند چون `.sheet`
   در ۵۶۰ پیکسل به بالا گوشه و `margin-top: auto` می‌گیرد. قاب صفحه هم با
   فضای قابل‌دیدن تنظیم می‌شود تا فیلدهای صندوق پیامک پشت کیبورد نمانند. */
.sheet.sheet--page {
  width: 100%; max-width: 600px;
  inset: var(--vv-top, 0px) 0 auto;
  height: var(--vv-height, 100dvh); max-height: var(--vv-height, 100dvh);
  margin: 0 auto; border-radius: 0;
  animation: pageIn var(--dur-3) var(--ease-out);
}
.sheet--page::backdrop { background: rgba(5,46,41,.28); backdrop-filter: none; }
.sheet--page .sheet__head {
  padding-top: calc(12px + env(safe-area-inset-top));
  cursor: default; touch-action: auto;
}
@keyframes pageIn { from { transform: translateX(-100%); } }
.sheet.sheet--page.sheet--out {
  margin: 0 auto;
  transform: translateX(-100%) !important;
  animation: none;
  transition: transform var(--dur-2) var(--ease-in);
}
@media (min-width: 560px) { .sheet.sheet--page { margin: 0 auto; border-radius: 0; } }

.sheet__head {
  display: flex; align-items: center; gap: 10px;
  padding: 16px 18px; border-bottom: 1px solid var(--border);
  position: sticky; top: 0; background: var(--bg); z-index: 2;
}
.sheet__head b { font-size: 1.0625rem; font-weight: 700; }
.sheet__close {
  width: 34px; height: 34px; padding: 8px; flex: none;
  border: 0; border-radius: 50%; background: var(--bg-subtle); color: var(--text); cursor: pointer;
}
/* ⚠️ `min-height: 0` لازم است و حذف‌شدنی نیست.
   پیش‌فرضِ یک فرزندِ flex، `min-height: auto` است — یعنی زیرِ اندازه‌ی
   محتوایش کوچک نمی‌شود. بدون این، بدنه به اندازه‌ی کلِ فرم کش می‌آید و
   نوارِ کنش را از تهِ شیت بیرون هل می‌دهد؛ `overflow: hidden` روی شیت هم
   بی‌صدا می‌بُردش. اندازه‌گیری شد: نوار ۱۸۸ پیکسل بیرون از کادر بود. */
.sheet__body { padding: 18px 18px calc(22px + env(safe-area-inset-bottom)); overflow-y: auto; flex: 1 1 auto; min-height: 0; }
.sheet__actions { display: grid; gap: 10px; margin-top: 22px; }

/* ── نوارِ کنش ─────────────────────────────────────────────────────────
 *
 * بیرونِ ناحیه‌ی اسکرول، نه `position: sticky` داخلش — چسبنده در یک ظرفِ
 * اسکرول‌شونده زیرِ صفحه‌کلیدِ سافاری می‌لرزد. چون `.sheet` خودش
 * `flex-direction: column` است و بدنه `flex: 1` گرفت، نوار همیشه ته
 * می‌نشیند و هیچ‌وقت اسکرول نمی‌شود.
 *
 * چرا مهم است: کنشِ اصلی قبلاً در سرِ شیت بود، و سرِ یک شیتِ ۹۲ درصدی
 * روی گوشیِ بزرگ نزدیکِ لبه‌ی بالای صفحه است — با یک دست دست‌نیافتنی.
 * حالا پایین است، جایی که شست بی‌فکر می‌رود.
 */
.sheet__bar {
  flex: 0 0 auto;
  padding: 12px 18px calc(12px + env(safe-area-inset-bottom));
  background: var(--bg);
  border-top: 1px solid var(--border);
}
/* ⚠️ اینجا یک باگ بود که دکمه را می‌چسباند به لبه‌ی پایینِ صفحه.
   ────────────────────────────────────────────────────────────
   انتخابگرِ قبلی `:root[style*="--kb"]` بود. ولی `--kb` **همیشه** روی
   ریشه نوشته می‌شود — حتی وقتی مقدارش `0px` است. پس آن قاعده هیچ‌وقت
   خاموش نبود و `env(safe-area-inset-bottom)` را در حالتِ صفحه‌کلیدِ
   بسته هم برمی‌داشت: دکمه‌ی ذخیره می‌رفت روی نوارِ خانه‌ی آیفون.
   گزارشِ مالک: «خود دکمه ذخیره هم خیلی پایین است.»

   حالا یک کلاسِ صریح که فقط وقتی صفحه‌کلید واقعاً باز است می‌نشیند. */
:root.kb-open .sheet__bar { padding-bottom: 12px; }

.sheet__baractions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

/* ── فیلدها ──────────────────────────────────────────────────────────── */

.field-label { margin: 18px 0 7px; display: block; font-size: .8125rem; font-weight: 600; color: var(--text-muted); }
.field-label:first-child { margin-top: 0; }

.field {
  width: 100%; min-height: 50px; padding: 0 16px;
  border: 0; border-radius: 16px;
  background: var(--bg-subtle); color: var(--text);
  /* font: inherit اینجا اندازه را هم می‌آورد و ۱۵ پیکسل می‌شد — زیر آستانه‌ی
     زومِ سافاری. فقط خانواده به ارث می‌رسد، اندازه صریح است. */
  font-family: inherit; font-size: max(16px, 1rem);
  text-align: start; cursor: pointer;
}
.field:focus-visible { outline: 2px solid var(--focus-ring); }
.field--area { padding: 12px 16px; min-height: 84px; resize: vertical; line-height: 1.8; }
.row2 { display: grid; grid-template-columns: 1fr auto; gap: 8px; }
/* سه فهرستِ هم‌عرض — سال، ماه، روزِ تولد. در RTL اولین فرزند سمت راست
   می‌نشیند، پس ترتیبِ مارک‌آپ همان ترتیبی است که خوانده می‌شود. */
.row3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; }

/* مبلغ هم مثل هر متن دیگری از راست شروع می‌شود؛ واحد بعد از عدد می‌ماند. */
.amount { display: flex; align-items: baseline; justify-content: flex-start; gap: 8px; padding: 16px 0 20px; }
.amount__input {
  width: auto; flex: 0 1 auto; max-width: 250px; min-width: 60px;
  border: 0; background: none; color: var(--text);
  font-family: inherit; font-size: 2.125rem; font-weight: 800; line-height: 1.2; text-align: right;
  font-variant-numeric: tabular-nums;
}
.amount__input:focus { outline: none; }
.amount__input::placeholder { color: var(--ink-300); }
.amount__unit { color: var(--text-muted); font-size: .9375rem; font-weight: 600; flex: none; }

.chips { display: flex; flex-wrap: wrap; gap: 7px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 40px; padding: 0 15px 0 13px;
  border: 0; border-radius: 999px;
  background: var(--bg-subtle); color: var(--text);
  font-size: .875rem; cursor: pointer;
  transition: background .14s, color .14s;
}
/* آیکون کم‌رنگ‌تر از متن است تا اسم دسته اول خوانده شود، نه شکلش. */
.chip__ic { width: 16px; height: 16px; flex: none; opacity: .62; }
.chip--on { background: var(--primary); color: var(--primary-text); font-weight: 700; }
.chip--on .chip__ic { opacity: .95; }

.arow {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  width: 100%; padding: 13px 0;
  border: 0; border-top: 1px solid var(--border); background: none;
  text-align: start;
}
.arow:first-of-type { border-top: 0; }
.arow--btn { cursor: pointer; min-height: 54px; }

.smsres { display: grid; gap: 8px; margin-top: 12px; }
.smsres > div { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }

/* ── تقویم ───────────────────────────────────────────────────────────── */

.cal__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.cal__head b { font-size: 1.0625rem; font-weight: 700; }
.cal__head button {
  width: 40px; height: 40px; border: 0; border-radius: 50%;
  background: var(--bg-subtle); color: var(--primary); font-size: 1.25rem; cursor: pointer;
}
.cal__dow, .cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal__dow { margin-bottom: 6px; }
.cal__dow span { text-align: center; font-size: .75rem; color: var(--text-muted); font-weight: 700; }
.cal__day {
  min-height: 44px; padding: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  border: 0; border-radius: 13px;
  background: none; color: var(--text);
  font-size: .9375rem; cursor: pointer;
  font-variant-numeric: tabular-nums;
}
.cal__day:active { background: var(--bg-subtle); }
.cal__day--today { box-shadow: inset 0 0 0 1.5px var(--primary-border); font-weight: 700; color: var(--primary); }
.cal__day--on { background: var(--primary); color: var(--primary-text); font-weight: 700; box-shadow: none; }
/* جای نقطه همیشه هست، حتی وقتی خالی است — وگرنه عددِ روزهای بدون تراکنش
   نسبت به بقیه بالا و پایین می‌پرید. */
.cal__dot { display: block; width: 5px; height: 5px; border-radius: 50%; background: transparent; }
/* ⚠️ رنگ نباید یگانه حاملِ معنا باشد: این دو نقطه در تمِ تاریک هم‌روشنایی‌اند
   (۱٫۰۰) و برای کسی با نقصِ دیدِ رنگ یکی‌اند. ورودی دایره، خروجی مربع. */
.cal__dot--out { background: var(--outflow); border-radius: 1px; }
.cal__dot--in { background: var(--positive); }
.cal__day--on .cal__dot--out, .cal__day--on .cal__dot--in { background: var(--primary-text); }

/* تاریخِ انتخاب‌شده، زیر تقویم و پیش از دکمه‌ی تأیید. */
.calpick { margin: 14px 0; text-align: center; font-weight: 700; }


/* ── دسکتاپ ──────────────────────────────────────────────────────────── */

@media (min-width: 780px) {
  .view { padding: 4px 20px 24px; }
  .tab { flex-direction: row; gap: 8px; font-size: 12.5px; }
}

/* ── دروازه‌ی نصب (فقط آیفونِ نصب‌نشده) ──────────────────────────────── */

.gate {
  position: fixed; inset: 0; z-index: 100;
  display: grid; place-items: center;
  padding: 28px 24px calc(28px + env(safe-area-inset-bottom));
  background: var(--bg-subtle); color: var(--text);
  overflow-y: auto;
}
.gate__inner { max-width: 380px; width: 100%; text-align: center; }
.gate__logo { border-radius: 20px; box-shadow: 0 8px 24px -8px rgba(5,46,41,.35); }
.gate__title { margin: 20px 0 12px; font-size: 1.375rem; font-weight: 800; line-height: 1.5; }
.gate__why {
  margin: 0 0 28px; font-size: .9375rem; line-height: 1.9;
  color: var(--text-muted);
}

.gate__steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; text-align: start; }
.gate__steps li {
  display: flex; align-items: center; gap: 13px;
  padding: 14px 16px; border-radius: 18px;
  background: var(--surface); box-shadow: 0 1px 3px rgba(5,46,41,.06);
}
.gate__steps li > span:last-child { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.gate__steps b { font-size: .9375rem; }
.gate__steps li span span { font-size: .8125rem; color: var(--text-muted); line-height: 1.8; }
.gate__steps code {
  font-family: inherit; font-weight: 700; color: var(--primary);
  direction: ltr; display: inline-block;
}
.gate__ic {
  width: 40px; height: 40px; padding: 9px; flex: none;
  display: grid; place-items: center;
  border-radius: 12px; background: var(--primary-subtle); color: var(--primary);
}
.gate__ic--brand { padding: 3px; background: none; }
.gate__ic--brand img { border-radius: 10px; }

/* ── دسته‌ها ─────────────────────────────────────────────────────────── */

.catlist { display: grid; gap: 6px; }

.catrow {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; border-radius: 14px;
  background: var(--surface); border: 1px solid var(--border);
  /* موقع کشیدن ترنسفورم می‌گیرد؛ بدون will-change روی گوشی می‌لرزد */
  will-change: transform;
}
.catrow.is-dragging {
  position: relative; z-index: 2;
  box-shadow: 0 10px 24px rgb(0 0 0 / .22);
  border-color: var(--primary);
}
/* بدون این، مرورگر کشیدن انگشت را اسکرول می‌فهمد و جابه‌جایی شروع نمی‌شود. */
.catrow__grip {
  touch-action: none; cursor: grab; flex: none;
  display: grid; place-items: center; width: 32px; height: 40px;
  margin-inline-start: -6px; color: var(--text-muted);
}
.catrow__grip:active { cursor: grabbing; }
.catrow__grip svg { width: 20px; height: 20px; }
.catrow__ic {
  flex: none; display: grid; place-items: center; width: 32px; height: 32px;
  border-radius: 10px; background: var(--bg-subtle); color: var(--primary);
}
.catrow__ic svg { width: 18px; height: 18px; }
.catrow__name { flex: 1; font-size: .875rem; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.catrow__act {
  flex: none; display: grid; place-items: center; width: 36px; height: 36px;
  padding: 0; border: 0; border-radius: 10px; background: none;
  color: var(--text-muted); cursor: pointer;
}
.catrow__act:hover { background: var(--bg-subtle); color: var(--text); }
.catrow__act.danger:hover { color: var(--negative); }
.catrow__act svg { width: 17px; height: 17px; }

.catprev {
  display: flex; align-items: center; gap: 12px;
  padding: 14px; border-radius: 16px; background: var(--bg-subtle); margin-bottom: 4px;
}
.catprev__ic {
  display: grid; place-items: center; width: 44px; height: 44px; flex: none;
  border-radius: 14px; background: var(--surface); color: var(--primary);
}
.catprev__ic svg { width: 24px; height: 24px; }
.catprev b { font-size: 1rem; }

.icongrid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(46px, 1fr)); gap: 8px;
}
.icongrid__b {
  aspect-ratio: 1; display: grid; place-items: center; padding: 0; cursor: pointer;
  border-radius: 12px; border: 1px solid var(--border);
  background: var(--surface); color: var(--text-muted);
}
.icongrid__b svg { width: 20px; height: 20px; }
.icongrid__b.is-on {
  border-color: var(--primary); color: var(--primary); background: var(--primary-subtle);
}

/* ── صندوق پیامک ─────────────────────────────────────────────────────── */

.bulkbar {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px; margin-bottom: 10px;
  border-radius: 14px; background: var(--primary-subtle);
}
.btn--sm { min-height: 38px; padding: 0 14px; font-size: .8125rem; }

.pend {
  display: grid; gap: 10px;
  padding: 12px; margin-bottom: 8px;
  border-radius: 16px; background: var(--surface); border: 1px solid var(--border);
}
.pend.is-on { border-color: var(--primary); background: var(--primary-subtle); }
.pend__top { display: flex; align-items: flex-start; gap: 10px; }
.pend__pick {
  flex: none; width: 24px; height: 24px; margin-top: 3px; padding: 3px;
  border-radius: 8px; border: 1.8px solid var(--border-strong);
  background: var(--surface); color: var(--primary-text); cursor: pointer;
}
.pend.is-on .pend__pick { background: var(--primary); border-color: var(--primary); }
.pend__main { flex: 1; min-width: 0; display: grid; gap: 2px; }
.pend__main b { font-size: 1rem; }
/* متن خام دو خط بیشتر نمی‌گیرد — بعضی پیامک‌ها یک پاراگرافند و کل صندوق را
   می‌بلعند. متن کامل را در فرم ثبت می‌بینی. */
.pend__raw {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; line-height: 1.7;
}

/* دو دکمه‌ی هم‌عرض، زیر محتوا. «ثبت» سهم بیشتری می‌گیرد چون کار اصلی است و
   «رد» نباید به‌اندازه‌ی آن به چشم بیاید. */
.pend__acts { display: flex; gap: 8px; }
.pend__acts .btn { flex: 2; min-width: 0; }
.pend__acts .pend__reject { flex: 1; }
/* روی کارتی که خودش رنگ surface دارد، دکمه‌ی ghost نامرئی می‌شود. این یکی
   حاشیه دارد تا دیده شود بدون اینکه با دکمه‌ی اصلی رقابت کند. */
.pend__reject {
  background: none; color: var(--text-muted);
  border: 1px solid var(--border);
}
.pend__reject:hover { color: var(--negative); border-color: var(--negative); }

/* ── تراکنش‌های ثابت ─────────────────────────────────────────────────── */

.rec { display: flex; align-items: center; gap: 11px; padding: 11px 0; border-top: 1px solid var(--border); }
.rec:first-of-type { border-top: 0; }
.rec.is-off { opacity: .55; }
.rec__ic {
  flex: none; display: grid; place-items: center; width: 36px; height: 36px;
  border-radius: 12px; background: var(--bg-subtle); color: var(--primary);
}
.rec__ic svg { width: 18px; height: 18px; }
.rec__main { flex: 1; min-width: 0; display: grid; gap: 1px; }
.rec__main b { font-size: .875rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rec__side { flex: none; display: flex; align-items: center; gap: 10px; }
.rec__side > b { font-size: .875rem; }
.rec__acts { display: flex; align-items: center; gap: 4px; }

/* دکمه‌ای که مثل پیوند دیده می‌شود. auth.js از روز اول از این کلاس استفاده
   می‌کرد ولی هیچ‌وقت تعریف نشده بود، یعنی «تغییر شماره» شبیه دکمه‌ی خام
   مرورگر درمی‌آمد. */
.linkbtn {
  padding: 0; border: 0; background: none; cursor: pointer;
  color: var(--primary); font-size: .8125rem; font-weight: 600;
  text-decoration: underline; text-underline-offset: 3px;
}
.linkbtn:hover { opacity: .8; }

/* کدِ تخفیف یا معرفی: خودِ کد لاتین و چپ‌به‌راست است، راهنمای خالی‌اش فارسی،
   از راست و کم‌رنگ. */
.refline { display: block; margin: 12px 2px 0; }
.refin { direction: ltr; text-align: left; text-transform: uppercase; letter-spacing: .06em; font-weight: 700; }
.refin:placeholder-shown { direction: rtl; text-align: right; }
.refin::placeholder { text-transform: none; letter-spacing: 0; font-weight: 400; color: var(--text-muted); opacity: .75; }
.refhint { min-height: 1.4em; margin: 8px 2px 0; line-height: 1.7; }
.refhint.pos { color: var(--positive); font-weight: 700; }

/* شیتِ نسخه پرو: وضعیت، بسته‌ها با قیمت، کدِ تخفیف. */
.prostat { display: flex; gap: 10px; align-items: flex-start; margin: 14px 2px 0; line-height: 1.9; font-size: .9375rem; }
.prostat svg { width: 20px; height: 20px; flex: none; margin-top: 4px; color: var(--primary); }
.plancards { display: grid; gap: 12px; margin-top: 16px; }
.plancard { position: relative; display: grid; gap: 6px; justify-items: center; text-align: center;
  padding: 20px 16px 16px; border-radius: 20px; background: var(--surface); border: 1.5px solid var(--border); }
.plancard__badge { position: absolute; top: -11px; padding: 3px 12px; border-radius: 999px;
  background: var(--primary); color: var(--primary-text); font-size: .75rem; font-weight: 700; white-space: nowrap; }
.plancard__title { font-size: 1rem; }
.plancard__price { display: flex; gap: 8px; align-items: baseline; justify-content: center; flex-wrap: wrap; }
.plancard__price s { color: var(--text-muted); font-size: .875rem; }
.plancard__price strong { font-size: 1.375rem; font-weight: 800; }
.plancard .btn { margin-top: 8px; }
.disc { margin-top: 14px; text-align: center; }
.disc--on { display: flex; flex-wrap: wrap; gap: 4px 12px; align-items: center; justify-content: center;
  padding: 12px 14px; border-radius: 16px; background: var(--primary-subtle); border: 1.5px dashed var(--primary); font-size: .9375rem; }
.disc--on .linkbtn { color: var(--text-muted); }
.disc__form { display: flex; gap: 10px; align-items: center; margin-top: 4px; }
.disc__form .field { flex: 1; min-width: 0; }
.disc__form .btn { flex: none; width: auto; padding-inline: 20px; }

.switch { display: flex; align-items: center; gap: 10px; margin: 16px 2px 0; cursor: pointer; }
.switch input { width: 20px; height: 20px; accent-color: var(--primary); flex: none; margin: 0; }
.switch span { font-size: .9375rem; font-weight: 600; }

/* ── ماشین‌حساب وام ──────────────────────────────────────────────────── */

.rateRow { display: flex; align-items: center; gap: 10px; }
.rateRow .field { flex: 1; }
.rateRow__pct { flex: none; color: var(--primary); font-weight: 700; font-size: .9375rem; }

.slider {
  width: 100%; margin: 12px 0 0; accent-color: var(--primary);
  /* بدون این، روی آیفون کشیدن اسلایدر صفحه را اسکرول می‌کند و مقدار عوض
     نمی‌شود. */
  touch-action: none;
}

.loanhero {
  display: grid; gap: 2px; justify-items: center; text-align: center;
  padding: 20px; margin-bottom: 12px;
  border-radius: 22px;
  background: linear-gradient(160deg, var(--teal-600), var(--teal-900));
  color: #fff;
}
.loanhero b { font-size: 1.75rem; font-weight: 800; }
.loanhero span { font-weight: 500; }

.lrow {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 9px 0; border-top: 1px solid var(--border);
}
.lrow:first-child { border-top: 0; padding-top: 0; }
.lrow b { font-size: .9375rem; }

/* جدول بازپرداخت می‌تواند ۱۲۰ ردیف باشد؛ داخل خودش اسکرول می‌شود تا نه
   صفحه دراز شود نه بدنه افقی بلغزد. */
.ltable { max-height: 320px; overflow: auto; border-radius: 16px; border: 1px solid var(--border); margin-top: 10px; }
.ltable table { width: 100%; border-collapse: collapse; font-size: .8125rem; }
.ltable th, .ltable td { padding: 8px 10px; text-align: start; white-space: nowrap; }
.ltable thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--bg-subtle); color: var(--text-muted); font-weight: 600;
}
.ltable tbody tr { border-top: 1px solid var(--border); }
.ltable .num { font-variant-numeric: tabular-nums; }

/* ── گزارش: مقایسه، فهرست دسته، پیشرفت بودجه ─────────────────────────── */

.verdict {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px;
  margin: 0 2px 14px; padding: 12px 14px;
  border-radius: 16px; background: var(--surface);
}
.verdict b { font-size: 1rem; }

.clist { display: grid; gap: 4px; }
.crow {
  display: flex; align-items: center; gap: 11px; width: 100%;
  padding: 10px 0; border: 0; border-top: 1px solid var(--border);
  background: none; color: inherit; font: inherit; text-align: start; cursor: pointer;
}
.crow:first-child { border-top: 0; }
/* ردیفِ برشِ انتخاب‌شده (reports.js ← activeNames): یک **حالت**، نه یک درخشش.
   رنگش رنگِ همان برش است («--c») تا چشم حلقه و فهرست را به هم ببندد؛ جابه‌جایی
   با «--ease-move» می‌لغزد. padding روی ردیف و margin منفی روی **فهرست** با هم
   می‌آیند تا پس‌زمینه جا داشته باشد ولی متن یک پیکسل هم جابه‌جا نشود.
   ⚠️ margin منفی روی خودِ ردیف نه: ردیف «width: 100%» دارد، پس فقط از یک طرف
   ۲۰ پیکسل بیرون می‌زد و کلِ صفحه اسکرولِ افقی می‌گرفت. فهرست عرضِ خودکار دارد
   و با margin منفی از دو طرف یکسان پهن می‌شود. */
.clist { margin-inline: -10px; }
.crow {
  padding-inline: 10px; border-radius: 12px;
  transition: background var(--dur-3) var(--ease-move), border-color var(--dur-3) var(--ease-move);
}
.crow--on { background: color-mix(in srgb, var(--c, var(--primary)) 16%, transparent); }
.crow--on .crow__name { font-weight: 700; }
.crow--on, .crow--on + .crow { border-top-color: transparent; }
/* ⚠️ هر دو ستونِ عددی عرضِ ثابت دارند؛ اگر مبلغ از محتوا عرض بگیرد، ستونِ
   درصد با هر ردیف به پهلو می‌رود و ترازِ عمودی — کلِ فایده‌اش — از بین
   می‌رود. درصد پررنگ و با رنگِ متن، مبلغ کم‌رنگ: سؤالِ این صفحه «چند
   درصد» است. */
.crow__dot { flex: none; width: 10px; height: 10px; border-radius: 50%; box-shadow: 0 0 0 1px var(--border-strong); }
.crow__name { flex: 1; min-width: 0; font-size: .875rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crow__pct {
  flex: none; width: 2.8rem; text-align: end;
  font-size: .9375rem; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums;
}
.crow__amt {
  flex: none; width: 5.5rem; text-align: end;
  font-size: .8125rem; color: var(--text-muted); font-variant-numeric: tabular-nums;
}

.bprog { padding: 10px 0; border-top: 1px solid var(--border); }
.bprog:first-child { border-top: 0; padding-top: 0; }
.bprog__top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.bprog__top b { font-size: .875rem; }
.bprog__track { height: 8px; border-radius: 99px; background: var(--bg-subtle); overflow: hidden; }
/* پر شدنِ نوار با transform، نه width: width در هر فریم چیدمان و رسمِ دوباره
   می‌خواهد، scaleX روی لایه‌ی ترکیب اجرا می‌شود. سهم در `--p` (۰ تا ۱).
   از راست پر می‌شود چون اپ همیشه راست‌به‌چپ است؛ گوشه‌ی گرد را خودِ ظرف
   با overflow می‌بُرد (گوشه‌ی فرزند با مقیاس کش می‌آمد). */
.bprog__track > * {
  display: block; width: 100%; height: 100%;
  transform: scaleX(var(--p, 0)); transform-origin: right;
  transition: transform var(--dur-3) var(--ease-move);
}

/* ورودی سقف داخل ردیف دسته باریک‌تر می‌ماند تا نام دسته جا بماند. */
.catrow .budgetin { flex: none; width: 130px; min-height: 40px; padding: 0 12px; }

/* ردیف سررسید حالا قابل ضربه است — ویرایشش را باز می‌کند. */
.due__main--btn { cursor: pointer; border-radius: 10px; }
.due__main--btn:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }

/* ── خوشامد اولین اجرا ───────────────────────────────────────────────── */

.onb {
  position: fixed; inset: 0; z-index: 60; overflow: auto;
  background: var(--bg-subtle); color: var(--text);
  display: grid; align-items: center;
  padding: calc(24px + env(safe-area-inset-top)) 20px calc(24px + env(safe-area-inset-bottom));
}
.onb__inner { width: 100%; max-width: 420px; margin-inline: auto; }

.onb__hero { text-align: center; margin-bottom: 22px; }
.onb__mark {
  display: block;
  width: 78px; height: 78px; margin: 0 auto 16px; border-radius: 20px;
  box-shadow: 0 12px 30px -10px rgba(1,70,62,.5);
}
.onb__hero h1 { margin: 0 0 6px; font-size: 1.5rem; font-weight: 800; }
.onb__hero p { margin: 0; font-size: .9375rem; line-height: 1.9; }

.onb__q { font-size: 1rem; font-weight: 700; display: block; }
.onb__body .btn { margin-top: 4px; }
.onb__link { display: block; width: 100%; margin-top: 14px; text-align: center; }
.onb__link--dim { color: var(--text-muted); text-decoration: none; font-weight: 500; }

.onbopt {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 14px; border-radius: 16px; cursor: pointer;
  border: 1.6px solid var(--border); background: var(--bg-subtle);
  color: inherit; font: inherit; text-align: start;
  transition: border-color .15s, background .15s;
}
.onbopt.is-on { border-color: var(--primary); background: var(--primary-subtle); }
.onbopt__main { flex: 1; display: grid; gap: 1px; }
.onbopt__main b { font-size: .9375rem; }
/* تیک همیشه جا می‌گیرد، حتی وقتی دیده نمی‌شود — وگرنه انتخاب هر گزینه
   عرض کارت را می‌پراند. */
.onbopt__tick { flex: none; width: 22px; height: 22px; color: var(--primary); opacity: 0; }
.onbopt.is-on .onbopt__tick { opacity: 1; }

.onb__dots { display: flex; justify-content: center; gap: 7px; margin-top: 26px; }
.onb__dots span {
  width: 7px; height: 7px; border-radius: 50%; background: var(--border);
  transition: width .2s, background .2s;
}
.onb__dots span.is-on { width: 20px; border-radius: 99px; background: var(--primary); }

/* ── سه قدم تا شروع ──────────────────────────────────────────────────── */

.gs {
  padding: 16px 18px; margin-bottom: 12px; border-radius: 22px;
  background: var(--primary-subtle); border: 1px solid var(--primary-border);
}
.gs__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.gs__head b { font-size: 1rem; font-weight: 700; }
.gs__x {
  display: grid; place-items: center; width: 30px; height: 30px; padding: 8px;
  margin: -6px -6px -6px 0; border: 0; border-radius: 50%;
  background: none; color: var(--text-muted); cursor: pointer;
}
.gs__x:hover { background: var(--surface); color: var(--text); }

.gs__step {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 9px 0; border: 0; background: none; color: inherit; font: inherit;
  text-align: start; cursor: pointer; font-size: .875rem;
}
.gs__step[disabled] { cursor: default; color: var(--text-muted); }
.gs__step.is-done span:last-child { text-decoration: line-through; }
.gs__tick {
  flex: none; display: grid; place-items: center; width: 22px; height: 22px; padding: 3px;
  border-radius: 50%; border: 1.8px solid var(--primary); color: var(--primary-text);
}
.gs__step.is-done .gs__tick { background: var(--primary); border-color: var(--primary); }

/* ── راهنمای شورتکات ─────────────────────────────────────────────────── */

/* کلید باید کامل دیده شود و قابل انتخاب باشد. `break-all` لازم است چون یک
   رشته‌ی بی‌فاصله است و بدون آن از کارت بیرون می‌زند. */
.tokenbox {
  display: block; padding: 12px 14px; border-radius: 12px;
  background: var(--bg-subtle); border: 1px solid var(--border);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px; line-height: 1.7; direction: ltr; text-align: left;
  word-break: break-all; user-select: all; -webkit-user-select: all;
}

/* ── قدم‌های راه‌اندازی (shortcut.js) ──────────────────────────────────
 *
 * هر قدم یک `details` است: تمام‌شده‌ها جمع و تیک‌خورده، قدمِ فعلی باز. دلیلش
 * در خودِ shortcut.js نوشته شده — رویه‌ای که کاربر سه بار از اپ بیرون می‌رود
 * و برمی‌گردد، باید بگوید «کجا بودی».
 *
 * `details` عمدی است و نه یک آکاردئونِ دست‌ساز: باز و بسته‌شدنش با صفحه‌کلید
 * و صفحه‌خوان از خودِ مرورگر می‌آید. */
.sstep {
  margin-bottom: 10px; border-radius: var(--r-card);
  background: var(--card); border: 1px solid var(--card-edge);
  overflow: hidden;
}
.sstep__h {
  display: flex; align-items: center; gap: 10px;
  padding: 14px; cursor: pointer; list-style: none;
  font-size: .9375rem; font-weight: 700;
}
/* پیکانِ پیش‌فرضِ سافاری و کروم، هر دو. */
.sstep__h::-webkit-details-marker { display: none; }
.sstep__n {
  flex: none; display: grid; place-items: center; width: 26px; height: 26px;
  border-radius: 50%; background: var(--primary); color: var(--primary-text);
  font-size: .8125rem; font-weight: 700;
}
.sstep--done .sstep__n { background: var(--positive); }
.sstep__n svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2.4; }
.sstep__t { flex: 1; min-width: 0; }
.sstep--done .sstep__t { font-weight: 600; color: var(--text-muted); }
.sstep__b { padding: 0 14px 14px; }
.sstep__b > .card:first-child { margin-top: 0; }

/* نوارِ پیشرفت بالای قدم‌ها: «قدم ۲ از ۳». */
.scprog { display: flex; align-items: baseline; gap: 8px; margin: 0 4px 12px; }
.scprog b { font-size: .9375rem; }
.scprog__n { margin-inline-start: auto; font-size: .8125rem; font-weight: 700; color: var(--primary); }

/* وقتی وصل است، همه‌ی قدم‌ها زیرِ یک ردیف جمع می‌شوند. */
.sstack { margin-bottom: 14px; }
.sstack__h {
  padding: 12px 14px; cursor: pointer; list-style: none;
  border-radius: var(--r-card); background: var(--card); border: 1px solid var(--card-edge);
  font-size: .875rem; font-weight: 700; color: var(--text-muted);
}
.sstack__h::-webkit-details-marker { display: none; }
.sstack__b { padding-top: 12px; }

/* نامِ انگلیسیِ روی صفحه‌ی Shortcuts — قرص، نه `<b>`. */
.uiname {
  font-family: ui-monospace, Menlo, monospace; font-size: .8125rem;
  padding: 1px 6px; border-radius: 6px;
  background: var(--bg-subtle); border: 1px solid var(--border);
  direction: ltr; unicode-bidi: isolate; white-space: nowrap;
}

.scstep { display: flex; gap: 10px; padding: 9px 0; border-top: 1px solid var(--border); }
.scstep:first-of-type { border-top: 0; padding-top: 0; }
.scstep__n {
  flex: none; display: grid; place-items: center; width: 24px; height: 24px;
  border-radius: 50%; background: var(--primary); color: var(--primary-text);
  font-size: .75rem; font-weight: 700;
}
.scstep__t { flex: 1; font-size: .875rem; line-height: 1.9; }
.scstep__t code {
  font-family: ui-monospace, Menlo, monospace; font-size: .8125rem;
  padding: 1px 5px; border-radius: 5px; background: var(--bg-subtle); direction: ltr;
}

/* ── تصویرِ اکشنِ شورتکات ──────────────────────────────────────────────
 *
 * سخت‌ترین مرحله‌ی راه‌اندازیِ پیامک خودکار یک صفحه‌ی ناآشنا با چهار
 * فیلد است، و توضیح متنی‌اش هرچقدر هم دقیق باشد، کسی که تا حالا
 * Shortcuts را باز نکرده نمی‌تواند از رویش صفحه را بسازد.
 *
 * عمداً HTML است نه عکس: با تمِ روشن و تاریک هماهنگ می‌آید، روی هر
 * عرضی درست می‌نشیند، وزنی به اپ اضافه نمی‌کند و متنش قابل انتخاب است.
 *
 * `dir="ltr"` روی خودِ کادر می‌نشیند چون نام فیلدها در آیفون انگلیسی
 * است — حتی وقتی زبان گوشی فارسی باشد. یادداشت‌های فارسیِ داخلش
 * دوباره `rtl` می‌شوند. */
.scmock {
  margin: 10px 0 2px; border: 1px solid var(--border); border-radius: 12px;
  background: var(--bg-subtle); overflow: hidden;
  font-family: ui-monospace, Menlo, monospace; font-size: .8125rem;
}
.scmock__h {
  padding: 8px 12px; background: var(--border); font-weight: 700;
  font-size: .8125rem; letter-spacing: -.01em;
}
.scmock__r {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 7px 12px; border-top: 1px solid var(--border);
}
.scmock__r span { color: var(--text-muted); }
.scmock__r b { font-weight: 700; }
.scmock__sub { background: var(--bg); }
/* یادداشت‌های فارسیِ داخل کادر باید از فونتِ مونواسپیسِ کادر **بیرون
   بیایند**. وگرنه فارسی حرف‌به‌حرف کش می‌آید و بدتر از نبودنش می‌شود —
   مونواسپیس برای نام فیلدهای انگلیسی است، نه برای جمله‌ی فارسی. */
.scmock__note {
  padding: 2px 12px 8px; font-size: .75rem;
  color: var(--text-muted); line-height: 1.9;
  font-family: Vazirmatn, Tahoma, 'Iranian Sans', system-ui, sans-serif;
}

/* دکمه‌ای که در واقع پیوند است — باید مثل بقیه‌ی دکمه‌ها دیده شود. */
a.btn { text-decoration: none; }

/* ── فهرست گروه‌بندی‌شده ──────────────────────────────────────────────
 *
 * الگوی اصلی ناوبری در اپ، و بزرگ‌ترین تفاوتی که نسخه‌ی وب داشت. آنجا هر
 * مقصد یک **ردیف** است — آیکون فیروزه‌ای سمت راست، عنوان، فلش سمت چپ — و
 * ردیف‌ها داخل یک کارت با خط جداکننده کنار هم می‌نشینند. اینجا هر مقصد یک
 * دکمه‌ی تمام‌عرض بود، که هم شلوغ‌تر به‌نظر می‌رسید هم سلسله‌مراتب را
 * از بین می‌برد: «مدیریت دسته‌ها» و «ذخیره‌ی بودجه» یک‌شکل بودند در حالی
 * که یکی رفتن به صفحه‌ی دیگر است و دیگری یک کنش.
 */

/* برچسب کوچکِ بالای هر گروه — «نمایش»، «مدیریت»، «ابزارها». عمداً کوچک و
   کم‌رنگ است: کارِ دسته‌بندی می‌کند، نه جلب توجه. */
.grouplabel {
  margin: 24px 6px 8px;
  font-size: .8125rem; font-weight: 600; color: var(--text-muted);
}
.grouplabel:first-child { margin-top: 6px; }

.group {
  background: var(--surface); border-radius: 20px;
  border: 1px solid var(--border);
  overflow: hidden;           /* تا گوشه‌ی ردیف اول و آخر گرد بماند */
  margin-bottom: 4px;
}

.nrow {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 13px 14px; min-height: 58px;
  border: 0; border-top: 1px solid var(--border);
  background: none; color: inherit; font: inherit; text-align: start;
  cursor: pointer;
  transition: background .14s;
}
.nrow:first-child { border-top: 0; }
.nrow:active { background: var(--bg-subtle); }
.nrow:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; }

/* آیکون در یک مربعِ گردِ کم‌رنگ، مثل اپ. رنگش فیروزه‌ای است و تنها جای
   رنگی هر ردیف — برای همین چشم اول همان را پیدا می‌کند. */
.nrow__ic {
  flex: none; display: grid; place-items: center; width: 34px; height: 34px;
  border-radius: 11px; background: var(--primary-subtle); color: var(--primary);
}
.nrow__ic svg { width: 19px; height: 19px; }

.nrow__main { flex: 1; min-width: 0; display: grid; gap: 1px; }
.nrow__main b { font-size: .9375rem; font-weight: 600; }
.nrow__main span { font-size: .8125rem; color: var(--text-muted); }

.nrow__side { flex: none; display: flex; align-items: center; gap: 8px; color: var(--text-muted); }
.nrow__side .num { font-size: .875rem; }

/* فلش. در RTL باید به چپ اشاره کند — یعنی همان جهتی که صفحه‌ی بعد از آن
   می‌آید — و آیکون از اول همان‌طور کشیده شده. اینجا عمداً هیچ
   `scaleX(-1)`ای نیست؛ کامنتِ قبلی می‌گفت هست، نبود، و افزودنش فلش را
   به سمتِ غلط می‌بَرد. */
.nrow__chev { width: 18px; height: 18px; flex: none; opacity: .5; }

/* شمارنده‌ی «منتظرِ تو» (صندوق پیامک‌ها).
   قرمز نیست: قرمز در این اپ فقط یعنی «چیزی خراب است»، و پیامکِ منتظرِ
   تأیید خطا نیست. سفید روی قرمزِ تمِ تاریک هم ۲٫۵ به ۱ بود. */
.nrow__badge {
  min-width: 22px; height: 22px; padding: 0 7px;
  display: grid; place-items: center; border-radius: 999px;
  background: var(--primary); color: var(--primary-text);
  font-size: .75rem; font-weight: 700; font-variant-numeric: tabular-nums;
}

/* ردیف ویرانگر — «پاک کردن همه‌ی داده‌ها» در اپ قرمز است، با آیکون قرمز. */
.nrow--danger .nrow__ic { background: color-mix(in srgb, var(--negative) 14%, transparent); color: var(--on-negative-wash); }
.nrow--danger .nrow__main b { color: var(--negative); }

/* نشان اپ در صفحه‌ی «درباره». */
/* ⚠️ `display: block` لازم است و نبودنش لوگو را سمت راست می‌انداخت.
   `margin: auto` فقط عنصرِ بلوکی را وسط می‌آورد؛ `img` پیش‌فرض inline
   است، پس حاشیه‌ی خودکار هیچ کاری نمی‌کرد و لوگو از `text-align` پیروی
   می‌کرد — که در RTL یعنی راست. */
.aboutmark {
  display: block;
  width: 76px; height: 76px; margin: 4px auto 14px; border-radius: 22px;
  background: linear-gradient(160deg, var(--teal-600), var(--teal-900));
  box-shadow: 0 12px 30px -12px rgba(1,70,62,.6);
}
.aboutname { margin: 0; text-align: center; font-size: 1.25rem; font-weight: 800; }

/* ══ هم‌شکل‌سازی با اپ ══════════════════════════════════════════════════
 *
 * سه چیز که در تصاویر اپ فوراً به چشم می‌آیند و نسخه‌ی وب نداشت: تب فعال
 * می‌درخشد، دکمه‌ی ثبت هاله دارد، و سگمنت‌ها بزرگ و برجسته‌اند.
 */

/* عنوان صفحه در اپ درشت‌تر است و بالای آن جای بیشتری دارد. */
.h1 { margin: 10px 0 18px; font-size: 2rem; font-weight: 800; }

/* تب فعال: در اپ یک قرصِ فیروزه‌ای فقط پشتِ آیکون است — نه پشت کل دکمه —
   و برچسبِ زیرش فیروزه‌ای می‌شود، نه سفید. هاله همان چیزی است که به نوار
   عمق می‌دهد. */
.tab { font-size: 12px; }
.tab svg { width: 21px; height: 21px; }
.tab[aria-current="page"] .tab__ic {
  box-shadow: 0 4px 12px -2px color-mix(in srgb, var(--primary) 55%, transparent);
}

/* دکمه‌ی ثبت هم همان هاله را دارد — در اپ دور «+ ثبت تراکنش» یک درخشش
   فیروزه‌ای هست که آن را از تب‌بار جدا نگه می‌دارد. */
.fab {
  height: 54px; padding: 0 22px; font-size: .9375rem;
  box-shadow: 0 8px 22px -6px rgba(1,70,62,.45),
              0 0 24px -4px color-mix(in srgb, var(--primary) 50%, transparent);
}

/* سگمنت: در اپ بلندتر است و گزینه‌ی انتخاب‌شده واضح‌تر بالا می‌آید. */
.seg { padding: 4px; gap: 4px; border-radius: 16px; }
.seg button { min-height: 46px; border-radius: 13px; font-size: .9375rem; }
.seg button[aria-selected="true"],
.seg button[aria-checked="true"] {
  background: var(--surface-raised); color: var(--text);
  box-shadow: 0 2px 6px rgba(0,0,0,.18);
}
.seg--sm { padding: 3px; gap: 3px; border-radius: 999px; }
.seg--sm button { min-height: 34px; border-radius: 999px; font-size: .875rem; }

/* کارت‌ها در اپ حاشیه‌ی نازکی دارند که در حالت تاریک لبه‌شان را از پس‌زمینه
   جدا می‌کند. بدون آن، کارت روی زمینه‌ی تیره شناور و بی‌مرز به‌نظر می‌رسد. */
/* لبه فقط در تمِ تاریک (`--card-edge`)؛ در روشن، مرز از پله‌ی سطح می‌آید. */
.card { border: 1px solid var(--card-edge); padding: 18px 16px; }


/* اعداد گزارش کاملند، مثل اپ — «۶۰,۳۲۴,۲۷۰» نه «۶۰ میلیون». سه ستونِ
   عدد کامل روی ۳۷۵ پیکسل تنگ می‌شود، پس فونت کوچک‌تر و بدون شکستن خط.
   خلاصه‌کردن، عددی می‌داد که کاربر نمی‌توانست با صورت‌حساب بانکش مقایسه
   کند — و همان مقایسه، کل کارِ این صفحه است. */
.stat { padding: 11px 8px; border: 1px solid var(--card-edge); text-align: center; }
.stat span { font-size: .75rem; }
.stat b { font-size: .8125rem; white-space: nowrap; }


/* ── فرم ثبت ─────────────────────────────────────────────────────────── */

/* هزینه و درآمد رنگ خودشان را دارند و همان رنگ روی دکمه می‌نشیند. کاربر
   پیش از خواندن هر کلمه‌ای می‌فهمد دارد چه ثبت می‌کند — چیزی که یک سگمنت
   خاکستری نمی‌دهد. */
.typepick { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 4px; }
.typepick__b {
  min-height: 54px; border-radius: 16px; cursor: pointer;
  background: none; font-weight: 700; font-size: 1rem;
  /* حالت انتخاب‌نشده بی‌رنگ است. رنگ‌کردنِ هر دو گزینه، «هزینه» را پیش از
     هر انتخابی شبیه یک هشدار نشان می‌داد — و ثبتِ یک خرجِ معمولی، کارِ
     روزمره‌ی این اپ است، نه خطا. */
  border: 1.6px solid var(--border); color: var(--text-muted);
  transition: background .16s, color .16s, border-color .16s;
}
.typepick__b--out[aria-checked="true"] { background: var(--outflow); border-color: var(--outflow); color: var(--primary-text); }
.typepick__b--in[aria-checked="true"] { background: var(--primary); border-color: var(--primary); color: var(--primary-text); }

/* نمایشگر مبلغ: بزرگ و وسط‌چین. اولین و مهم‌ترین چیزی که کاربر می‌بیند. */
.bigamt {
  display: grid; justify-items: center; gap: 2px;
  padding: 18px 16px; margin: 12px 0;
  border-radius: 22px; background: var(--surface); border: 1px solid var(--border);
  cursor: text;
}
.bigamt__in {
  width: 100%; border: 0; background: none;
  /* عددِ خنثی. قرمزِ پیش‌فرض یعنی «چیزی اشتباه شده»، نه «دارم خرج ثبت
     می‌کنم» — و در اپ هم مبلغِ خرج رنگِ متن است، نه قرمز. */
  color: var(--text);
  font-family: inherit; font-size: clamp(1.6rem, 8vw, 2.375rem); font-weight: 800; line-height: 1.15; text-align: center;
  font-variant-numeric: tabular-nums;
}
.bigamt__in:focus { outline: none; }
.bigamt__in::placeholder { color: var(--border-strong); }
.bigamt__unit { color: var(--text-muted); font-size: .9375rem; font-weight: 600; }
/* درآمد که انتخاب شود، عدد هم فیروزه‌ای می‌شود — همان نشانه‌ی رنگی، پایین
   صفحه هم تکرار می‌شود. */
.bigamt--in .bigamt__in { color: var(--primary); }

/* قرص‌های تاریخ. «امروز» و «دیروز» چیزی است که در نود درصد موارد لازم است؛
   تقویم برای بقیه. */
.datechips { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.datechip {
  min-height: 40px; padding: 0 15px;
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface); color: var(--text-muted);
  font-size: .875rem; font-weight: 600; cursor: pointer;
}
.datechip[aria-pressed="true"] {
  background: var(--primary-subtle); border-color: var(--primary);
  color: var(--primary); font-weight: 700;
}

.datechip--shown { background: var(--primary-subtle); border-color: var(--primary); color: var(--primary); display: grid; place-items: center; }
/* تاریخ و ساعت: یک قرص با آیکنِ تقویم و ساعتِ فعلی، که انتخابگرِ
   تاریخ‌وساعت را باز می‌کند (پیش‌تر دو قرص بودند که همان یک کار را می‌کردند).
   ⚠️ دو شکلِ قدیمی‌ترِ ساعت هر دو شکست خوردند: قرصی با `pointer-events: none`
   و بعد متنِ خالی (مالک: «آیتمِ مرده؛ نه قابلِ انتخاب، نه معلوم که چیست»). */
.datechip--when {
  display: inline-flex; align-items: center; gap: 6px; padding-inline: 12px;
}
.datechip--when svg { width: 16px; height: 16px; flex: none; }

/* حساب‌ها: کارت‌های ضربه‌خور به‌جای منوی کشویی. نام پررنگ، موجودی زیرش. */
.acctpick {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(128px, 1fr));
  gap: 8px; border-radius: 18px; margin-bottom: 18px;
}
.acctpick__b {
  display: grid; gap: 2px; min-height: 58px; padding: 9px 12px;
  border: 1.5px solid var(--border); border-radius: 16px;
  background: var(--surface); color: var(--text);
  text-align: start; font-family: inherit; cursor: pointer;
  transition: border-color .15s, background .15s;
}
.acctpick__name { font-size: .9375rem; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acctpick__bal { font-size: .75rem; color: var(--text-muted); }
.acctpick__b[aria-checked="true"] {
  border-color: var(--primary); background: var(--primary-subtle);
}
.acctpick__b[aria-checked="true"] .acctpick__name { color: var(--primary); }
.acctpick__b:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }

/* شبکه‌ی دسته‌ها — سه ستون، آیکون بالا و نام پایین، مثل اپ. چیپ‌های متنیِ
   قبلی جست‌وجوی چشمی را سخت می‌کردند: بیست برچسبِ هم‌شکل که فقط با خواندن
   از هم جدا می‌شدند. آیکون، همان کار را در یک نگاه می‌کند. */
/* بدون اسکرولِ داخلی: در اپ کل صفحه اسکرول می‌شود. یک ناحیه‌ی اسکرولِ
   تودرتو یعنی کاربر گاهی شبکه را می‌لغزاند و گاهی صفحه را، و هیچ‌وقت
   نمی‌داند کدام. */
.catgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 12px; }
.cattile {
  display: grid; justify-items: center; align-content: center; gap: 6px;
  min-height: 78px; padding: 10px 6px; cursor: pointer;
  border: 1px solid var(--border); border-radius: 14px;
  background: var(--bg-subtle); color: var(--text);
  transition: border-color .14s, background .14s;
}
.cattile__ic { width: 22px; height: 22px; color: var(--primary); }
/* دو خط، ۱۳ پیکسل: «حمل‌ونقل» و «خرید روزمره» روی صفحه‌ی باریک بریده
   می‌شدند — در هدفِ اصلیِ ضربه‌ی پرکاربردترین فرمِ اپ. */
.cattile__name {
  font-size: .8125rem; font-weight: 600; text-align: center; line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; max-width: 100%; overflow-wrap: anywhere;
}
.cattile.is-on { border-color: var(--primary); background: var(--primary-subtle); }
.cattile.is-on .cattile__name { color: var(--primary); }

.search--sm { min-height: 42px; }

/* دکمه‌ی دوم در نوار کنش‌ها — حاشیه‌دار، تا از دکمه‌ی اصلی کم‌رنگ‌تر باشد
   ولی گم نشود. */
.btn--outline {
  background: none; color: var(--primary);
  border: 1.6px solid var(--primary-border);
}
.btn--outline:active { background: var(--primary-subtle); }

/* بلوک حساب بین قرص‌های تاریخ و دسته‌ها می‌نشیند و بدون این، برچسبش به
   ردیف بالا می‌چسبد. */
#acctBlock:not(:empty) { margin-top: 4px; }

/* ══ حرکت ══════════════════════════════════════════════════════════════
 *
 * اپ همه‌ی جابه‌جایی‌ها را با snappy(0.24) انجام می‌دهد. نسخه‌ی وب بدون
 * حرکت، «قطع» به نظر می‌رسید: صفحه‌ها می‌پریدند و دکمه‌ی ثبت ناگهان
 * ظاهر و ناپدید می‌شد. همان زمان‌بندی اینجا هم تکرار شده.
 */

/* ورودِ صفحه، فقط هنگام عوض‌شدن تب — نه بعد از هر ذخیره. */
/* عوض‌کردن تب، «رفتن به عمق» نیست — پس فقط محو می‌شود و جابه‌جایی عمودی
   ندارد. آن هشت پیکسلِ بالا-پایین، حسِ «صفحه‌ی تازه لود شد» می‌داد، که
   دقیقاً همان چیزی است که نمی‌خواهیم. */
.view--in { animation: viewIn .2s ease-out; }
@keyframes viewIn { from { opacity: 0; } to { opacity: 1; } }

/* دکمه‌ی ثبت از پایینِ خودش کوچک می‌شود و می‌رود — همان
   .scale(0.85, anchor: .bottom) که در اپ هست.
   ⚠️ منحنیِ جهنده (--ease-pop) فقط برای **آمدن**. قبلاً برای رفتن هم بود:
   دکمه در حالِ محو شدن از اندازه‌ی هدف رد می‌شد و برمی‌گشت — لرزشی ریز،
   نه یک خروج. رفتن تند و با --ease-in است، چون کاربر منتظرش نیست. */
.fab {
  transform-origin: bottom center;
  transition: transform var(--dur-2) var(--ease-pop), opacity var(--dur-2) var(--ease-out);
}
.fab.fab--off {
  transform: scale(.85); opacity: 0; pointer-events: none;
  transition: transform var(--dur-1) var(--ease-in), opacity var(--dur-1) var(--ease-in);
}

/* ── فشردن: یک قاعده برای هر چیزِ ضربه‌خور ───────────────────────────
   ⚠️ نامتقارن: فرو رفتن تقریباً آنی (۶۰ms)، برگشتن آرام (۲۶۰ms). انگشت در
   صفرِ زمان روی شیشه می‌نشیند؛ عنصری که ۱۲۰ms طول بکشد تا فرو برود،
   پیوندِ علت و معلول را می‌شکند و «اتفاقی که افتاد» خوانده می‌شود، نه
   «پاسخِ من». و ۰٫۹۷ نه ۰٫۹۸۵: روی ردیفِ ۶۴ پیکسلی، ۰٫۹۸۵ کمتر از یک
   پیکسل است. فهرست یک‌جاست تا عنصرِ تازه فراموش نشود. */
.nrow, .irow, .plan, .dtab, .cattile, .datechip, .btn, .acct, .mcard, .probar,
.due__main--btn, .sheet__action, .fab {
  transition: transform 260ms var(--ease-out), background var(--dur-1), border-color var(--dur-1), color var(--dur-1);
}
.nrow:active, .irow:active, .plan:active, .dtab:active, .cattile:active, .datechip:active,
.btn:active, .acct:active, .mcard:active, .probar:active, .due__main--btn:active,
.sheet__action:active, .fab:active {
  transform: scale(.97);
  transition-duration: 60ms;
}
/* دکمه‌ی ثبت هم فشرده می‌شود و هم پنهان؛ فشردن نباید منحنیِ آمدنش را بپوشاند. */
.fab:not(:active):not(.fab--off) { transition: transform var(--dur-2) var(--ease-pop), opacity var(--dur-2) var(--ease-out); }

/* ── نوار به‌روزرسانی ─────────────────────────────────────────────────
 *
 * بالای صفحه می‌نشیند، نه پایین: پایینِ صفحه جای تب‌بار و دکمه‌ی ثبت است و
 * یک نوارِ چهارم آنجا، همان سه‌لایه‌ی شناور را چهار می‌کرد.
 */
.updbar {
  position: fixed; z-index: 60;
  inset-inline: 12px; top: calc(10px + env(safe-area-inset-top));
  max-width: 480px; margin-inline: auto;
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  border-radius: 16px;
  background: var(--primary); color: var(--primary-text);
  box-shadow: 0 8px 24px -6px rgba(1,70,62,.5);
  font-size: .875rem;
  animation: updIn .26s cubic-bezier(.2,.8,.2,1);
}
.updbar span { flex: 1; min-width: 0; }
.updbar__go {
  flex: none; padding: 7px 14px; border: 0; border-radius: 999px;
  background: var(--primary-text); color: var(--primary);
  font-weight: 700; font-size: .8125rem; cursor: pointer;
}
.updbar__x {
  flex: none; width: 30px; height: 30px; padding: 0;
  border: 0; border-radius: 50%; background: none;
  color: inherit; opacity: .8; cursor: pointer;
}
@keyframes updIn { from { opacity: 0; transform: translateY(-12px); } to { opacity: 1; transform: none; } }

/* دستگیره‌ی شیت. بدون این، «می‌شود کشیدش» هیچ نشانه‌ای ندارد. */
.sheet__grab {
  display: grid; place-items: center;
  padding: 8px 0 2px; cursor: grab; touch-action: none;
}
.sheet__grab i {
  display: block; width: 36px; height: 5px;
  border-radius: 999px; background: var(--border-strong); opacity: .65;
}
.sheet__head { cursor: grab; touch-action: none; }
.sheet__head b, .sheet__grab { user-select: none; }


/* کنشِ اصلیِ شیت، در سرِ آن.
   ────────────────────────
   دکمه‌ی «ذخیره» ته یک بدنه‌ی اسکرول‌شونده بود، بعد از قرص‌های تاریخ و
   شبکه‌ی دسته‌ها. صفحه‌کلیدِ آیفون نزدیک نیمی از صفحه را می‌گیرد، پس کاربر
   مبلغ را می‌زد و برای ذخیره باید صفحه‌کلید را می‌بست و اسکرول می‌کرد —
   دو کارِ اضافه در جریانی که هدفش «زیر پنج ثانیه» است. */
.sheet__action {
  margin-inline-start: auto; flex: none;
  padding: 8px 16px; border: 0; border-radius: 999px;
  background: var(--primary); color: var(--primary-text);
  font-weight: 700; font-size: .875rem; cursor: pointer;
}


/* قرص‌های مبلغِ سریع. مبالغِ روزمره رقم‌های گردند و تایپِ شش‌رقمی روی
   گوشی، کندترین قدمِ کل جریان است. */
.quickamt { display: flex; gap: 8px; justify-content: center; margin: -6px 0 14px; }
.quickamt button {
  min-height: 36px; padding: 0 14px;
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface); color: var(--text-muted);
  font-size: .8125rem; font-weight: 600; cursor: pointer;
}
.quickamt button:active { background: var(--primary-subtle); border-color: var(--primary); color: var(--primary); }
.quickamt #zeros { min-width: 84px; font-weight: 700; color: var(--text); }
/* جای کلید همیشه نگه داشته می‌شود تا ظاهرشدنش فرم را پایین نکشد. */
.quickamt { min-height: 36px; }

/* قدمِ پیامک در خوشامد: متنِ نمونه و نتیجه‌ی خواندنش. */
.onb__sms {
  margin: 12px 0 0; padding: 12px 14px;
  border-radius: 14px; background: var(--bg-subtle);
  font-size: .8125rem; line-height: 1.9; color: var(--text-muted);
  white-space: pre-line;
}
.onb__read {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 12px; min-height: 40px;
}
.onb__got { display: grid; gap: 2px; }
.onb__got b { font-size: 1.125rem; }

/* آن‌چه از متنِ پیامک فهمیده شده، در خودِ متن نشان داده می‌شود.
   کاربر باید ببیند «۱۲۵ هزار» از کجا آمده، نه اینکه عددی بالا و متنی
   پایین ببیند و خودش تطبیق بدهد. */
.mk { border-radius: 5px; padding: 0 3px; background: none; }
.mk--amt { background: color-mix(in srgb, var(--primary) 22%, transparent); color: var(--text); font-weight: 700; }
.mk--bal { background: color-mix(in srgb, var(--text-muted) 20%, transparent); color: var(--text); }

/* پیشنهادِ متنِ داخل حافظه‌ی موقت، بالای صندوق پیامک. */
.clip {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; margin-bottom: 12px;
  border: 1px solid var(--primary-border); border-radius: 18px;
  background: var(--primary-subtle);
}
.clip__main { flex: 1; min-width: 0; display: grid; gap: 2px; }
.clip__main span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* نشانگرِ نوارِ افقیِ حساب‌ها. بدون آن، کاربر نمی‌فهمد چیزی برای کشیدن
   هست — و نقطه‌های صفحه‌بندی با تعدادِ متغیرِ حساب‌ها جور درنمی‌آیند. */
.cards__bar {
  position: relative; height: 3px; margin: -6px auto 14px;
  width: 64px; border-radius: 99px; background: var(--border);
}
.cards__bar span {
  /* عرضِ پیش‌فرض تا وقتی اندازه‌ها خوانده شوند؛ بدون آن، لحظه‌ی اول یک
     نوارِ خالی دیده می‌شود. */
  width: 40%; inset-inline-start: 0;
  position: absolute; top: 0; height: 100%;
  border-radius: 99px; background: var(--border-strong);
  /* ⚠️ بی‌transition، و با transform: چیزی که با انگشت حرکت می‌کند باید در
     همان فریم باشد. `inset-inline-start` متحرک هم چیدمان را در هر فریمِ
     اسکرول دوباره حساب می‌کرد. جابه‌جایی در `--x` (dashboard.js). */
  transform: translateX(var(--x, 0));
}

/* ساعت داخل شیتِ تاریخ. تنها جایی که کنترلِ بومیِ مرورگر لازم است، و
   دیگر وسط ردیفِ فارسیِ قرص‌ها نمی‌نشیند. */
.timerow { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.timerow__in { width: 140px; text-align: center; }

/* یادآوریِ شورتکات، داخل خودِ صندوق پیامک. */
.autohint {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 13px 14px; margin-bottom: 14px;
  border: 1px dashed var(--primary-border); border-radius: 18px;
  background: none; color: inherit; text-align: start; cursor: pointer;
}
.autohint__ic { width: 34px; height: 34px; padding: 8px; flex: none; border-radius: 12px; background: var(--primary-subtle); color: var(--primary); }
.autohint__main { flex: 1; min-width: 0; display: grid; gap: 2px; }
.autohint__main b { font-size: .875rem; }

/* ردیفی که تازه ثبت شد.
   ─────────────────────
   صفحه بعد از هر ذخیره کامل رسم می‌شود (دلیلش در app.js نوشته شده)، پس
   کاربر «چیزی عوض شد» را می‌بیند ولی نمی‌داند چه. این یک لحظه می‌گوید
   کجا را نگاه کند. */
/* ۶۰۰ms نه ۱۱۰۰: کارش «بگو کجا را نگاه کنم» است و چشم در ۳۰۰ms گرفته.
   باقیِ آن محوشدن «دارد چیزی بارگذاری می‌شود» خوانده می‌شد. */
.row--new { animation: rowNew 600ms var(--ease-out); }
@keyframes rowNew {
  0%   { background: color-mix(in srgb, var(--primary) 18%, transparent); }
  100% { background: transparent; }
}

/* عددِ علامت‌دار: منها و به‌علاوه سمتِ چپ عدد.
   ──────────────────────────────────────────
   `isolate` تنها، عدد را از همسایه‌ها جدا می‌کرد ولی جهتِ راست‌به‌چپِ صفحه
   را به ارث می‌برد، و در آن جهت علامت سمتِ راستِ رقم‌ها می‌نشیند. برای
   مبلغ — که همیشه «علامت، بعد عدد» خوانده می‌شود — جهت باید چپ‌به‌راست
   باشد.

   عمداً روی همه‌ی `.num` اعمال نمی‌شود: رشته‌هایی مثل «۵۰۰ تومان» واحدشان
   فارسی است و در چپ‌به‌راست، «تومان» به سمت راست پرت می‌شود. */
.amt, .irow__amt { direction: ltr; unicode-bidi: isolate; }

/* ── نسخه پرو ─────────────────────────────────────────────────────────
 *
 * ستاره، نه قفل. رنگش هم `--secondary` است نه `--alert`: نداشتنِ اشتراک
 * خطا نیست، پس نباید مثل خطا دیده شود.
 */
.pro-badge {
  display: inline-block; vertical-align: middle;
  margin-inline-end: 6px; padding: 2px 8px;
  border-radius: 999px;
  background: var(--primary-subtle); color: var(--primary);
  font-size: .6875rem; font-weight: 700;
}

.probar {
  display: flex; align-items: flex-start; gap: 10px; width: 100%;
  padding: 11px 13px; margin-bottom: 12px;
  border: 0; border-radius: 14px;
  background: var(--primary-subtle); color: inherit;
  text-align: start; cursor: pointer;
}

.probar__ic { width: 18px; height: 18px; flex: none; margin-top: 1px; color: var(--primary); }
.probar__txt { flex: 1; min-width: 0; font-size: .8125rem; line-height: 1.8; color: var(--text-muted); }
.probar__go { width: 14px; height: 14px; flex: none; margin-top: 3px; opacity: .5; }

.progate__mark { padding: 12px; }
.progate__btn { margin-top: 18px; padding: 0 28px; }

.proSheet { text-align: center; padding: 8px 6px 22px; }
.proSheet__mark {
  width: 56px; height: 56px; margin: 0 auto 14px; padding: 14px;
  border-radius: 18px; background: var(--primary-subtle); color: var(--primary);
}
.proSheet__title { display: block; font-size: 1.125rem; }
.proSheet__msg { margin: 8px 0 0; font-size: .9375rem; line-height: 1.9; color: var(--text-muted); }

/* ستاره‌ی کوچک روی دکمه‌ای که پرو می‌خواهد. دکمه فعال می‌ماند —
   خاکستر شدنش کنتراست را زیر حد خواندن می‌برد و کاربر هم نمی‌فهمد چرا. */
.btn__pro { display: inline-flex; width: 14px; height: 14px; opacity: .8; }

/* ستاره وقتی داخل متن می‌نشیند (نه روی دکمه‌ی رنگی) رنگِ پرو می‌گیرد،
   وگرنه مثل یک نقطه‌ی سیاه در وسط جمله دیده می‌شود. */
.onbopt .btn__pro { color: var(--primary); vertical-align: -1px; }

/* دکمه‌ی برگشت در قدم دوم خوشامد. کوچک و کم‌رنگ — راهِ فرار است، نه
   کنشِ اصلی؛ ولی باید دیده شود، چون همان دو فیلدِ قبلی بیشترین غلطِ
   تایپی را دارند. */
.onb__back{
  display: inline-flex; align-items: center; gap: 6px;
  margin: 0 0 12px; padding: 6px 10px 6px 12px;
  border: 0; border-radius: 999px;
  background: none; color: var(--text-muted);
  font: inherit; font-size: .875rem; cursor: pointer;
}
.onb__back svg{ width: 16px; height: 16px; }
.onb__back:active{ background: var(--primary-subtle); }

/* راه‌های خروج از مرورگرِ داخل‌اپ. */
.gate__out{ display: grid; gap: 10px; margin-top: 20px; }

/* هشدارِ «فقط سافاری» در دروازه. تأکیدی است، نه خطا — پس رنگِ برند
   می‌گیرد نه قرمز: کاربر کاری اشتباه نکرده، فقط باید جای دیگری باشد. */
.gate__only{
  margin: 14px 0 0; padding: 13px 15px;
  border: 1px solid var(--primary-border); border-radius: 16px;
  background: var(--primary-subtle);
  font-size: .875rem; line-height: 1.9;
}
.gate__only code{
  padding: 1px 6px; border-radius: 6px;
  background: var(--surface); font-family: inherit; direction: ltr;
  unicode-bidi: isolate;
}

/* سرِ هر روز در شیتِ «این عدد از کجا آمد؟». تراکنش‌ها روزبه‌روز گروه
   می‌شوند چون کاربر خرجش را با روز به یاد می‌آورد، نه با ردیف. */
.ddday {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  margin: 16px 4px 8px;
  font-size: .8125rem; color: var(--text-muted);
}
.ddday:first-child { margin-top: 0; }

/* ستون‌های نمودار روند و ردیف‌های سقف بودجه حالا دکمه‌اند. */
.bars__col, .bprog {
  border: 0; background: none; font: inherit; color: inherit;
  text-align: start; cursor: pointer; width: 100%;
}
.bars__col:active, .bprog:active { opacity: .7; }

/* ── موجودی از پیامک ──────────────────────────────────────────────────
 *
 * بسته می‌ماند تا وقتی خواسته شود: کسی که عدد را از حفظ دارد نباید یک
 * کادرِ باز و یک textarea خالی جلوی چشمش باشد.
 */
.smsbal { margin-top: 10px; }
.smsbal__open {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 11px 12px;
  border: 1px dashed var(--primary-border); border-radius: 16px;
  background: none; color: inherit; font: inherit; text-align: start; cursor: pointer;
}
.smsbal__open:active { background: var(--primary-subtle); }
.smsbal__ic {
  width: 30px; height: 30px; padding: 7px; flex: none;
  border-radius: 10px; background: var(--primary-subtle); color: var(--primary);
}
.smsbal__main { flex: 1; min-width: 0; display: grid; gap: 2px; }
.smsbal__main b { font-size: .875rem; }
.smsbal__body { margin-top: 10px; }
.smsbal__out { margin-top: 8px; line-height: 1.9; min-height: 1.2em; }

/* ── نوار نصب (اندروید و دسکتاپ) ──────────────────────────────────────
 *
 * قبلاً روی **سایت** بود. آنجا برداشته شد چون دکمه‌ی «نصب» باید مستقیم
 * به اپ برود، نه به یک پنجره‌ی تأیید. ولی برداشتنِ ساده یعنی کاربر
 * اندروید نصبِ یک‌ضربه‌ای را از دست بدهد، پس همان‌جا آمد که باید باشد.
 *
 * روی آیفون هیچ‌وقت دیده نمی‌شود: سافاری `beforeinstallprompt` ندارد.
 */
.instbar {
  position: fixed; inset-inline: 12px; bottom: calc(12px + env(safe-area-inset-bottom));
  z-index: 60; display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; border-radius: 16px;
  background: var(--surface); border: 1px solid var(--border);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .18);
  animation: instbar-in var(--dur-3) var(--ease-out) both;
}
@keyframes instbar-in { from { opacity: 0; transform: translateY(14px); } }
.instbar__t { flex: 1; min-width: 0; display: grid; gap: 1px; }
.instbar__t b { font-size: .875rem; }
.instbar__t span { font-size: .75rem; color: var(--text-muted); line-height: 1.7; }
.instbar__x {
  flex: none; width: 30px; height: 30px; border: 0; border-radius: 50%;
  background: var(--bg-subtle); color: var(--text-muted); font-size: 1.1rem; line-height: 1;
}

/* ── کد شش‌رقمی ────────────────────────────────────────────────────────
 *
 * شش خانه‌ی دیده‌شده روی **یک** ورودیِ واقعی.
 *
 * چرا نه شش <input>: تکمیل خودکار می‌شکند. سافاری کدِ پیشنهادیِ بالای
 * کیبورد را فقط در خانه‌ی اول می‌ریزد و کاربر باید پنج رقم را از رویش
 * تایپ کند — یعنی همان چیزی که قرار بود حذف شود. WebOTP اندروید هم یک
 * فیلد را پر می‌کند، نه شش‌تا.
 *
 * پس ورودی یکی است و متنش شفاف؛ رقم‌ها را جاوااسکریپت در شش span
 * می‌نشاند. `caret-color: transparent` چون مکان‌نمای واقعی وسطِ خانه‌ی
 * اشتباه می‌افتد — به‌جایش خانه‌ی فعال قاب رنگی می‌گیرد.
 */
.otpwrap { position: relative; direction: ltr; }
.otpwrap__slots {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 8px;
}
.otpwrap__slots i {
  display: flex; align-items: center; justify-content: center;
  height: 58px; font-style: normal;
  font-size: 1.5rem; font-weight: 800; font-variant-numeric: tabular-nums;
  color: var(--text);
  background: var(--bg-subtle);
  border: 1.6px solid var(--border);
  border-radius: 14px;
  transition: border-color .18s ease, background-color .18s ease;
}
.otpwrap.is-focus .otpwrap__slots i.is-active {
  border-color: var(--primary);
  background: var(--surface);
}
.otpwrap__slots i.is-filled { border-color: var(--border-strong, var(--border)); }
/* ورودیِ واقعی: تمامِ سطح را می‌پوشاند تا هر ضربه‌ای روی هر خانه فوکوسش
   کند، ولی نه دیده می‌شود و نه چیزی از ظاهر را عوض می‌کند. */
.otpwrap__in {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  padding: 0; margin: 0; border: 0;
  background: transparent;
  color: transparent; caret-color: transparent;
  font-size: 1.5rem; text-align: center;
  -webkit-text-fill-color: transparent;
}
.otpwrap__in:focus { outline: none; }
@media (max-width: 380px) {
  .otpwrap__slots { gap: 6px; }
  .otpwrap__slots i { height: 52px; font-size: 1.25rem; border-radius: 12px; }
}

/* ⚠️ نوارِ ذخیره **یک ردیف** است و قدش هیچ‌وقت عوض نمی‌شود.
   ─────────────────────────────────────────────────────
   اینجا یک کلیدِ «چند تراکنش پشت‌سرهم» بود که با باز و بسته شدنِ
   صفحه‌کلید ظاهر و ناپدید می‌شد، و «ذخیره» را چهل پیکسل زیرِ انگشتِ
   کاربر جابه‌جا می‌کرد. آن تصمیم حالا به نانِ تستِ بعد از ذخیره رفته —
   جایی که کاربر جوابش را می‌داند. دلیلِ کاملش در add.js کنارِ `bar:`. */
.savebar { display: grid; gap: 10px; }

/* کاشیِ «همه‌ی دسته‌ها» — هم‌اندازه‌ی بقیه تا شبکه به‌هم نریزد، ولی بدون
   آیکن، چون دسته نیست. */
.cattile--more { font-weight: 600; color: var(--primary); }

/* ضربدرِ پاک‌کردنِ مبلغ. داخلِ خودِ کادرِ بزرگ، سمتِ شروع (چپ در RTL)،
   چون سمتِ پایان جای واحدِ «تومان» است. */
.bigamt { position: relative; }
.bigamt__clear {
  position: absolute; inset-inline-start: 12px; top: 50%; transform: translateY(-50%);
  width: 32px; height: 32px; display: grid; place-items: center;
  border: 0; border-radius: 50%; cursor: pointer;
  background: var(--bg-subtle); color: var(--text-muted);
}
.bigamt__clear svg { width: 15px; height: 15px; }

/* ── منویِ سه‌نقطه‌ی هدرِ شیت ────────────────────────────────────────────
 *
 * کنشِ نادر و برگشت‌ناپذیر جایش اینجاست، نه ته فرم. هدر `sticky` است و
 * `z-index: 2` دارد، پس این پاپ‌آور باید از آن بالاتر بنشیند وگرنه زیرِ
 * بدنه‌ی شیت می‌رود. در راست‌به‌چپ، `margin-inline-start: auto` دکمه را
 * به لبه‌ی چپ می‌برد — روبه‌روی ضربدر — و پاپ‌آور از همان لبه باز می‌شود. */
.sheetmenu { position: relative; margin-inline-start: auto; flex: none; }
.sheet__action + .sheetmenu { margin-inline-start: 0; }
.sheetmenu__btn {
  width: 34px; height: 34px; padding: 7px; display: block;
  border: 0; border-radius: 50%; background: var(--bg-subtle); color: var(--text-muted); cursor: pointer;
}
.sheetmenu__btn[aria-expanded="true"] { background: var(--border); color: var(--text); }
/* ⚠️ `inset-inline-end`, نه `-start`.
   دکمه با `margin-inline-start: auto` به انتهای نوار می‌رود — در
   راست‌به‌چپ یعنی لبه‌ی چپِ فیزیکی. لنگر انداختن از `inline-start`
   پاپ‌آور را ۱۹۰ پیکسل بیشتر به چپ می‌بُرد، یعنی بیرونِ خودِ شیت.
   از `inline-end` لنگر می‌اندازد و به سمتِ داخل باز می‌شود. */
.sheetmenu__pop {
  position: absolute; top: calc(100% + 8px); inset-inline-end: 0;
  min-width: 190px; z-index: 3;
  padding: 6px; border: 1px solid var(--border); border-radius: 16px;
  background: var(--bg); box-shadow: 0 12px 30px rgba(5,46,41,.16);
}
.sheetmenu__pop button {
  display: block; width: 100%; min-height: 42px;
  padding: 0 12px; border: 0; border-radius: 11px;
  background: transparent; color: var(--text); cursor: pointer;
  font: inherit; font-size: .9375rem; text-align: start;
}
.sheetmenu__pop button:active { background: var(--bg-subtle); }
.sheetmenu__pop button.danger { color: var(--negative); }

/* ── کشیدنِ ردیف برای حذف ────────────────────────────────────────────────
 *
 * ⚠️ `touch-action: pan-y` حذف‌شدنی نیست. بدون آن مرورگر کلِ حرکتِ انگشت
 * را برای اسکرول برمی‌دارد و رویدادِ افقی هیچ‌وقت به JS نمی‌رسد — ژست
 * بی‌صدا هیچ کاری نمی‌کند. با آن، عمودی همچنان دستِ مرورگر است و فقط
 * افقی به ما می‌رسد. */
.swipe-list .irow { touch-action: pan-y; }
/* ⚠️ `--surface` است، نه `--bg`.
   ردیف روی یک `.card` می‌نشیند و در حالتِ تاریک این دو یکی نیستند
   (#131F1D در برابرِ ink-950). با `--bg`، ردیفِ در حالِ کشیده‌شدن یک
   لکه‌ی تیره‌تر از کارت می‌شد — فقط در حالتِ تاریک، فقط وسطِ ژست. */
.irow--swiping { position: relative; z-index: 1; background: var(--surface); }

/* ظرفِ ردیف‌ها فقط در حینِ ژست مبنای موقعیت می‌شود. */
.swipehost { position: relative; }

/* ⚠️ `left`/`width` از JS می‌آیند و اینجا نوشته نمی‌شوند.
   ظرفِ ردیف‌ها `.card--flush` است با ۱۶ پیکسل حاشیه‌ی درونی. یک عنصرِ
   مطلق نسبت به **جعبه‌ی padding** جا می‌گیرد، نه جعبه‌ی محتوا — پس
   `inset-inline: 0` لایه را ۳۲ پیکسل پهن‌تر از خودِ ردیف می‌کرد و از
   گوشه‌های گردِ ۲۲پیکسلیِ کارت بیرون می‌زد. `offsetLeft` و `offsetWidth`
   دقیقاً همان جعبه‌ی ردیف را می‌دهند و به عددِ حاشیه وابسته نیستند. */
.swipebg {
  position: absolute; border-radius: 12px;
  background: color-mix(in srgb, var(--negative) 16%, transparent);
  color: var(--on-negative-wash);
}
.swipebg--armed { background: var(--negative); color: #fff; }

/* ⚠️ `right`، نه `flex-end`.
   کشیدن فقط به چپ است، پس نوارِ بازشده همیشه سمتِ **راستِ فیزیکی** است.
   `flex-end` در راست‌به‌چپ به چپ ترجمه می‌شود، یعنی دقیقاً زیرِ خودِ ردیف
   — و برچسب هیچ‌وقت دیده نمی‌شد. */
.swipebg__lbl {
  position: absolute; right: 16px; top: 50%; transform: translateY(-50%);
  display: inline-flex; align-items: center; gap: 7px;
  font-size: .8125rem; font-weight: 700; white-space: nowrap;
}
.swipebg__lbl svg { width: 18px; height: 18px; }

/* ── نکته‌ها (settings.js ← openTipsSheet) ─────────────────────────────
   همان ردیف‌های nrow؛ فقط دو نشانه اضافه می‌شود: نقطه‌ی فیروزه‌ای برای
   تازه، تیکِ خاکستری برای دیده‌شده. کم‌رنگیِ دیده‌شده با **رنگ** است، نه
   opacity — متنِ محوشده با opacity کنتراستش را از دست می‌دهد (a11y.html). */
.tipmark { flex: none; display: grid; place-items: center; }
.tipmark--new { width: 8px; height: 8px; border-radius: 50%; background: var(--primary); }
.tipmark--seen { width: 18px; height: 18px; color: var(--text-muted); }
.tipmark--seen svg { width: 16px; height: 16px; }
.tip--seen .nrow__main b { color: var(--text-muted); font-weight: 500; }
.tip--seen .nrow__ic { background: var(--bg-subtle); color: var(--text-muted); }
.tip__act { font-size: .8125rem; font-weight: 600; color: var(--primary); white-space: nowrap; }
/* نکته‌ی بی‌مقصد: ردیفِ ثابت. شکلِ دکمه بدونِ کار، از نبودنش بدتر است. */
.nrow--static { cursor: default; }
.nrow--static:active { background: none; transform: none; }


/* ── «با بانک نمی‌خواند» (dashboard.js ← driftCard) ─────────────────────
   رنگِ هشدار، نه قرمز: چیزی باید بررسی شود، ولی خطای کاربر نیست. متن با
   --on-warning-wash تا روی پس‌زمینه‌ی رنگی کنتراستش نیفتد. */
.drift {
  margin: 14px 0 4px; padding: 14px; border-radius: 18px;
  background: color-mix(in srgb, var(--warning) 12%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--warning) 35%, transparent);
}
.drift__t { display: block; font-size: .9375rem; color: var(--on-warning-wash, var(--text)); }
.drift__p { margin: 6px 0 12px; font-size: .8125rem; line-height: 1.9; color: var(--text); }
.drift__balances { margin: 0 0 12px; font-size: .8125rem; line-height: 1.8; color: var(--text); }
.drift__balances > div { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding-block: 4px; }
.drift__balances dt { flex: 1; min-width: 0; }
.drift__balances dd { margin: 0; max-width: 58%; text-align: end; font-weight: 600; overflow-wrap: anywhere; }
.drift__balances small { display: block; font-weight: 400; }
.drift__acts { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
/* ── نکته‌ی هفته در داشبوردِ خلوت ─────────────────────────────────────── */
.tipline {
  display: flex; align-items: center; gap: 10px;
  margin: 14px 0 4px; padding: 11px 12px;
  border-radius: 16px; background: var(--primary-subtle); color: var(--text);
  font-size: .8125rem; line-height: 1.8;
}
.tipline__ic { flex: none; display: grid; place-items: center; width: 30px; height: 30px; border-radius: 10px; background: var(--surface); color: var(--primary); }
.tipline__ic svg { width: 17px; height: 17px; }
.tipline__t { flex: 1; min-width: 0; }
.tipline__t b { color: var(--primary); font-weight: 700; }
.tipline__more { flex: none; font-weight: 700; }

/* حلقه‌ای کوتاه دورِ چیزی که نکته به آن اشاره کرد (چشمِ کارتِ موجودی). */
.attn { animation: attn 1.1s var(--ease-out) 2; border-radius: 999px; }
@keyframes attn {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--primary) 60%, transparent); }
  100% { box-shadow: 0 0 0 12px transparent; }
}

/* ── نوارِ آفلاین (app.js ← watchConnectivity) ──────────────────────────
   درونِ جریانِ صفحه، نه fixed: روی عنوانِ بزرگ نمی‌افتد و جا باز می‌کند.
   ناحیه‌ی امنِ بالا را نوار می‌گیرد، پس «view» دیگر لازمش ندارد. */
.offbar {
  box-sizing: border-box; width: calc(100% - 36px); max-width: 604px;
  margin: calc(8px + var(--safe-top, env(safe-area-inset-top))) auto 0;
  padding: 8px 12px; border-radius: 12px;
  background: var(--bg-subtle); color: var(--text); border: 1px solid var(--border);
  font-size: .8125rem; line-height: 1.8; text-align: center;
}
.offbar--back { color: var(--positive); }
.offbar:not([hidden]) ~ .view { padding-top: 10px; }

/* ── نانِ تستِ خطا ───────────────────────────────────────────────────
   متن روی قرمز همان جفتِ دکمه‌ی «حذف» است: در تمِ تاریک قرمز روشن است و
   سفید رویش ۲٫۳ می‌شد. */
.toast--bad, .undobar--bad { background: var(--negative); color: var(--on-negative); }
.undobar--bad .toast__undo { background: color-mix(in srgb, var(--on-negative) 18%, transparent); }

/* ── راه‌اندازیِ پیامک: نوارِ درجا، نبضِ انتظار، قدمِ بعد ─────────────── */
.netstrip {
  margin: 0 0 12px; padding: 10px 12px; border-radius: 12px;
  background: var(--bg-subtle); border: 1px solid var(--border);
  font-size: .8125rem; line-height: 1.9; color: var(--text);
}
.waitline { display: flex; align-items: center; gap: 10px; margin: 14px 0 0; font-size: .8125rem; line-height: 1.8; color: var(--text-muted); }
.waitline__dot { flex: none; width: 9px; height: 9px; border-radius: 50%; background: var(--primary); animation: waitpulse 1.6s var(--ease-move) infinite; }
@keyframes waitpulse { 0%, 100% { transform: scale(.7); opacity: .45; } 50% { transform: scale(1); opacity: 1; } }
.scnext { display: grid; gap: 10px; margin-top: 14px; }
.scnext b { font-size: .9375rem; }
.sccheer { margin: 0 0 8px; font-size: .875rem; line-height: 1.9; }
.sccheer b { color: var(--positive); }

/* طرحِ ساده‌شده‌ی صفحه‌ی اتوماسیونِ آیفون — نه اسکرین‌شات. فونتِ سیستم،
   چپ‌به‌راست، چون روی گوشی هم همین شکل است. */
/* اسکرین‌شاتِ واقعیِ زیرمرحله‌ی سه (shortcut.js ← SHOT_URL). حلقه در خودِ
   عکس کشیده شده، نه با CSS: جای کادرها به ابعادِ هر آیفون بسته است. */
.iosshot { margin: 4px 0 18px; }
.iosshot img {
  display: block; width: 100%; max-width: 480px; height: auto; margin-inline: auto;
  border-radius: 18px; border: 1px solid var(--border); background: var(--bg-subtle);
}
.iosshot figcaption { margin: 8px 2px 0; line-height: 1.9; }
.iosmock { margin: 4px 0 18px; }
.iosmock__screen {
  padding: 12px; border-radius: 18px; background: var(--bg-subtle); border: 1px solid var(--border);
  font-family: -apple-system, 'SF Pro Text', system-ui, sans-serif; font-size: .8125rem;
}
.iosmock__title { font-weight: 700; font-size: .9375rem; margin: 0 4px 8px; }
.iosmock__group { border-radius: 12px; background: var(--surface); overflow: hidden; }
.iosmock__group + .iosmock__group { margin-top: 10px; }
.iosmock__group--ring { box-shadow: 0 0 0 2.5px var(--primary), 0 0 0 7px color-mix(in srgb, var(--primary) 20%, transparent); }
.iosmock__row { display: flex; justify-content: space-between; gap: 12px; padding: 10px 12px; border-top: 1px solid var(--border); }
.iosmock__row:first-child { border-top: 0; }
.iosmock__row b { font-weight: 500; color: var(--primary); }
.iosmock__row--dim { color: var(--text-muted); }
.iosmock figcaption { margin: 8px 2px 0; line-height: 1.9; }
@media (prefers-reduced-motion: no-preference) {
  .swipebg { transition: background-color .12s ease, color .12s ease; }
}

/* خطِ «انتخاب در ماهِ دیگری است» زیرِ شبکه‌ی تقویم. فقط وقتی هست که
   انتخاب روی صفحه دیده نمی‌شود، پس حضورش خودش یک خبر است. */
.cal__away {
  display: block; width: 100%; margin-top: 10px;
  padding: 9px 12px; border: 0; border-radius: 12px;
  background: var(--bg-subtle); color: var(--text-muted);
  font: inherit; font-size: .8125rem; text-align: center; cursor: pointer;
}
.cal__away b { color: var(--text); font-weight: 700; }

/* ── ثبت گروهی ───────────────────────────────────────────────────────
 *
 * خلاصه‌ی حساب‌ها و پیش‌نمایش، هر دو پیش از ضربه‌ی آخر دیده می‌شوند: این
 * تنها جای اپ است که یک ضربه چند تراکنش می‌سازد. */
.bulksum { margin: 0 0 14px; line-height: 1.9; }
.bulkacc { display: grid; gap: 4px; margin-top: 8px; line-height: 1.9; }
.bulkprev {
  margin: 16px 0 0; padding: 10px 12px;
  border-radius: 12px; background: var(--bg-subtle);
  font-size: .8125rem; font-weight: 700; text-align: center;
}

/* حسابِ نامشخص: پیامکی که جیبوک نفهمید مالِ کدام حساب است. رنگِ هشدار،
   نه خطا — چیزی خراب نیست، فقط یک انتخاب مانده. */
.pend__unknown { color: var(--warning); font-weight: 700; }
/* پیشنهادِ سررسید روی ردیفِ پیامک (duematch.js).
   «شاید قسط…» یک پیشنهاد است و رنگِ برند دارد؛ «از قبل پرداخت شده» یک هشدارِ
   واقعی است — تأییدش پول را دو بار حساب می‌کند — پس رنگِ هشدار می‌گیرد. */
.pend__due, .pend__dupe {
  display: block; margin-top: 4px; font-size: .8125rem; font-weight: 700; line-height: 1.7;
}
.pend__due { color: var(--primary); }
.pend__dupe { color: var(--warning); }
/* پیشنهادِ جابه‌جایی روی ردیفِ صندوق (inbox.js ← pairText). همان شکلِ پیشنهادِ قسط. */
.pend__pair { display: block; margin-top: 4px; font-size: .8125rem; font-weight: 700; line-height: 1.7; color: var(--primary); }
/* خلاصه‌ی «از / به / کارمزد» در شیتِ پرسش. */
.pairsum { display: grid; gap: 8px; }
.pairsum__row { display: grid; grid-template-columns: 2.4rem 1fr auto; align-items: center; gap: 10px; }
.pairsum__row > span { color: var(--text-muted); font-size: .8125rem; }
.pairsum__fee { color: var(--text-muted); border-top: 1px solid var(--border); padding-top: 8px; }
.pairsum__fee b { font-weight: 500; }
.bulkskip {
  margin: 12px 0 0; padding: 10px 12px; border-radius: 12px; line-height: 1.8;
  color: var(--warning); background: color-mix(in srgb, var(--warning) 12%, transparent);
}
.acct-note { margin: 0 0 8px; line-height: 1.8; color: var(--warning); }
.acct-hint {
  margin: 8px 0 0; padding: 10px 12px; border-radius: 12px; line-height: 1.9;
  color: var(--warning); background: color-mix(in srgb, var(--warning) 12%, transparent);
}
.acct-hint .linkbtn { font-weight: 700; }
.acctpick--ask .acctpick__b { border-color: color-mix(in srgb, var(--warning) 70%, transparent); }
.acctpick--warn .acctpick__b[aria-checked="true"] { border-color: var(--warning); background: color-mix(in srgb, var(--warning) 12%, transparent); }
.acctpick--warn .acctpick__b[aria-checked="true"] .acctpick__name { color: var(--warning); }

/* ── تیکِ رضایت (ورود و خرید) ──────────────────────────────────────────
   چک‌باکسِ واقعی، نه شبیه‌سازی‌شده: صفحه‌خوان و صفحه‌کلید بی‌کارِ اضافه با آن
   کار می‌کنند. برچسب کلِ ردیف را لمس‌پذیر می‌کند (هدفِ لمسی ≥ ۲۴ پیکسل). */
.consent-check {
  display: flex; align-items: flex-start; gap: 10px; margin: 14px 2px 4px;
  font-size: .875rem; line-height: 1.8; color: var(--text); cursor: pointer;
}
.consent-check input { flex: none; width: 22px; height: 22px; margin: 3px 0 0; accent-color: var(--primary); cursor: pointer; }
.consent-check a { color: var(--primary); font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }
.consent-err { margin: 0 2px 6px; margin-inline-start: 34px; font-size: .875rem; font-weight: 700; }
.consent-err:empty { display: none; }
/* شیتِ «تأیید خرید». */
.confirm__plan { margin: 0 2px 10px; font-weight: 700; }
.confirm__row {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin: 0 0 6px;
  padding: 12px 14px; border-radius: 14px; background: var(--primary-subtle, color-mix(in srgb, var(--primary) 10%, transparent));
}
.confirm__row span { color: var(--text-muted); font-size: .9375rem; }
.confirm__row b { font-size: 1.25rem; font-weight: 800; }

/* ── «کاهشِ حرکت»: یک محافظِ سراسری ─────────────────────────────────────
   پیش‌تر دوازده بلوکِ جدا کنارِ هر انیمیشن بود و چهارتا از قلم افتاده بودند
   (میله‌های روند، نوارهای پیشرفت، نشانگرِ کارت‌ها…). حالا هر حرکتِ تازه
   خودکار پوشش دارد. مسیرهای جاوااسکریپتی (کشیدن، تکانِ حذف، شمارشِ عددها،
   خروجِ شیت) matchMedia را خودشان می‌پرسند.
   ⚠️ فرورفتنِ لمس «بی‌حرکت» نیست، «بی‌فرورفتن» است: transform: none. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after, ::backdrop {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .nrow:active, .irow:active, .plan:active, .dtab:active, .cattile:active, .datechip:active,
  .btn:active, .acct:active, .mcard:active, .probar:active, .due__main--btn:active,
  .sheet__action:active, .fab:active { transform: none; }
}

/* ── سررسید: کارتِ برنامه‌ی اقساط، هم‌قرارداد با ردیفِ چک و طلب ─────────
   همان ردیفِ `.due` (تیکِ قسطِ بعدی کنارِ مبلغ، بدنه‌ی ضربه‌خور)، با نوارِ
   پیشرفت زیرش. به‌جای آیکون، شمارِ قسط‌های مانده در همان مربع. */
.plancard { margin-bottom: 10px; padding-bottom: 12px; }
.plancard .due { border-top: 0; }
.plancard .plan__bar { display: block; }
.plan__left { display: grid; place-items: center; padding: 0; font-size: .9375rem; font-weight: 800; }

/* دو فیلدِ عددیِ کوتاه که با هم خوانده می‌شوند (مبلغِ هر قسط و تعداد). */
.fieldrow { display: grid; grid-template-columns: minmax(0, 1fr) 6.5rem; gap: 10px; align-items: end; }

/* ── دنگ (views/dong.js) ────────────────────────────────────────────────
   فقط چیزهایی که پیش از این در اپ نبود؛ بقیه همان `due`، `chip`، `seg` و
   `card` است تا بخشِ دنگ ادامه‌ی همین اپ باشد، نه صفحه‌ای دیگر. */

/* دعوت به ساختنِ اولین دنگ: آیکون، دو خط، دکمه. */
.dongInvite { display: flex; align-items: center; gap: 12px; }
.dongInvite > div { flex: 1; min-width: 0; }
.dongInvite b { font-size: .9375rem; }
.dongInvite p { margin: 2px 0 0; line-height: 1.8; }
.dongDone { display: flex; align-items: center; gap: 12px; }
.dongDone > div { flex: 1; min-width: 0; }
.dongDone p { margin: 2px 0 0; }

.dhint { margin: 8px 2px 0; line-height: 1.9; }
.dlink { display: block; margin: 12px auto 0; }
.dcount { display: inline-grid; place-items: center; min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: 9px; background: var(--primary); color: var(--primary-text); font-size: .6875rem; font-weight: 700; }
.dweight { font-size: .75rem; color: var(--text-muted); font-weight: 600; }
/* حرفِ اولِ نام در مربعِ آیکون، به‌جای یک آیکونِ تکراری. */
.dinit { display: grid; place-items: center; padding: 0; font-size: .9375rem; font-weight: 800; }

/* «تنظیماتِ بیشتر» در فرمِ دنگ: تاریخ، ضریب، مادرخرج و گرد کردن برای کاربرِ
   بارِ اول مفاهیمِ پیشرفته‌اند. `details` تا باز و بسته شدن با صفحه‌کلید و
   صفحه‌خوان از خودِ مرورگر بیاید. خلاصه‌ی سمتِ دیگر می‌گوید چه چیزی عوض شده. */
.dmore { margin-top: 18px; border-radius: var(--r-card); background: var(--card); border: 1px solid var(--card-edge); }
.dmore__h {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  min-height: 48px; padding: 10px 14px; cursor: pointer; list-style: none;
  font-size: .9375rem; font-weight: 700;
}
.dmore__h::-webkit-details-marker { display: none; }
.dmore__h .muted { font-weight: 500; text-align: end; min-width: 0; }
.dmore__b { padding: 0 14px 14px; }
.dmore__b > .field-label:first-child { margin-top: 4px; }
/* پیشنهادِ نام از دنگ‌های قبلی: گروهِ دوستان تکرار می‌شود. */
.dsuggest { margin-top: 10px; gap: 6px; }
.dsuggest .chip { min-height: 36px; padding: 0 12px; font-size: .8125rem; }
/* ضریبِ غیرِ یک، وقتی ضریب‌ها پنهان‌اند: فقط خبر می‌دهد و بازشان می‌کند. */
.dwchip { flex: none; min-height: 40px; padding: 0 10px; font-weight: 700; }
.dweights { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; }
.dwrow { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.dwrow > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stepper button:disabled { color: var(--text-muted); cursor: default; }
/* «می‌گیرد ۳۰۰٬۰۰۰» — فعل هم‌وزنِ عدد نیست. */
.dverb { font-size: .75rem; font-weight: 600; color: var(--text-muted); }

/* ── بازبینیِ دنگ (۱۴۰۵/۰۷/۰۸) ─────────────────────────────────────────
   کارتِ بالا جوابِ «من» را می‌دهد. رنگِ جهت ندارد: بدهکار بودن در دنگ «خطا»
   نیست (قاعده‌ی رنگ: قرمز فقط وقتی کاری باید کرد). */
.dhead { margin: 0 0 4px; font-size: 1.125rem; font-weight: 800; line-height: 1.8; }
.dhead .num { font-size: 1.25rem; }
.dkitty { margin-top: 6px; font-weight: 600; }
/* ردیفِ پرداختی که «من» در آن هستم کمی جلوتر است. */
.due--me { background: color-mix(in srgb, var(--primary) 6%, transparent); }
.dme {
  flex: none; padding: 2px 9px; border-radius: 999px;
  background: var(--primary-subtle, var(--bg-subtle)); color: var(--primary);
  font-size: .75rem; font-weight: 800;
}
.dsteps b { font-size: .9375rem; }
.dsteps ol { margin: 8px 0 0; padding-inline-start: 1.3em; display: grid; gap: 6px; line-height: 1.9; font-size: .875rem; }
.dmoretype { display: block; margin: 0 2px 4px; }
.dledger { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 4px; }
.dledger .linkbtn { min-height: 32px; }
/* ریزِ حسابِ یک نفر: جمله در یک سو، عدد در سوی دیگر، جمع زیرِ خط. */
.dcalc { display: grid; gap: 10px; }
.dcalc__row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; line-height: 1.8; }
.dcalc__row > span { min-width: 0; }
.dcalc__row .num { flex: none; font-variant-numeric: tabular-nums; }
.dcalc__row--total { border-top: 1px solid var(--border); padding-top: 10px; font-weight: 800; }

/* افراد: نام، ضریب، حذف — یک ردیف. */
.dpeople { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; }
.dperson { display: flex; align-items: center; gap: 8px; }
.dperson .field { flex: 1; min-width: 0; }
.dadd { display: flex; gap: 8px; margin-top: 10px; }
.dadd .field { flex: 1; min-width: 0; }
.dadd .btn { flex: none; min-height: 48px; }

.stepper { display: flex; align-items: center; flex: none; border-radius: 12px; background: var(--bg-subtle); }
.stepper button {
  position: relative; width: 36px; height: 40px; border: 0; background: none; color: var(--text);
  font-size: 1.125rem; font-weight: 700; cursor: pointer; font-family: inherit;
}
/* دیده‌شدن ۳۶ پیکسل، لمس ۴۴ — همان قاعده‌ی کلِ اپ. */
.stepper button::after { content: ''; position: absolute; inset: -2px -4px; }
.stepper button:focus-visible { outline: 2px solid var(--focus-ring); border-radius: 10px; }
.stepper span { min-width: 2.4rem; text-align: center; font-size: .8125rem; font-weight: 700; }

/* یک قلمِ فاکتور یا یک «اضافه»: نام و حذف، اعداد، سهم‌بَرها. */
.dline { display: grid; gap: 8px; padding: 12px; }
.dline__top { display: flex; align-items: center; gap: 8px; }
.dline__top .field { flex: 1; min-width: 0; }
.dline__nums { display: flex; align-items: flex-end; gap: 8px; flex-wrap: wrap; }
.dline__nums label { display: grid; gap: 3px; flex: 1 1 6rem; min-width: 0; }
.dline__nums label:first-child { flex: 0 0 4.5rem; }
.dline__nums .seg { flex: 0 0 auto; }
.dline__amt { flex: 0 0 auto; min-width: 5rem; padding-bottom: 12px; text-align: end; font-weight: 700; }
.dline .chips { gap: 6px; }
.dline .chip { min-height: 36px; padding: 0 12px; font-size: .8125rem; }

/* «چه کسی چقدر»: نام کنارِ مبلغ. */
.dgrid { display: grid; gap: 8px; }
.drow { display: grid; grid-template-columns: minmax(0, 7rem) minmax(0, 1fr); align-items: center; gap: 10px; }
.drow > span { font-size: .875rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* نوارِ پایینِ ویرایشگرِ هزینه: جمعِ زنده بالای «ذخیره». */
.xbar { display: grid; gap: 8px; }
.xbar > span { text-align: center; }
/* سطرِ دومِ ردیفِ «سهم‌ها» می‌شکند، بریده نمی‌شود: عدد تنها خبرِ آن ردیف است. */
.due__main span.dwrap { white-space: normal; line-height: 1.8; }
.due__main span.dpair { white-space: nowrap; }
.duesum .dblock { display: block; }

/* انتخاب گروهی صندوق در عرض ۳۲۰ پیکسل هم دکمهٔ کامل دارد. */
.bulkbar--inbox { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.bulkbar--inbox > * { min-width: 0; }
.bulkbar--inbox .btn { min-height: 44px; padding: 8px; white-space: normal; }

.finance-entry { margin: 12px 0; display: grid; gap: 10px; }
.finance-entry .linkbtn { min-height: 44px; text-align: start; white-space: normal; }
.finance-summary { padding: 12px; border-radius: 16px; background: var(--primary-subtle); line-height: 1.9; margin: 10px 0; }
.finance-person { padding: 12px; border: 1px solid var(--border); border-radius: 16px; margin: 12px 0; }
.finance-person .field-label:first-child { margin-top: 0; }
.finance-choice { display: flex; gap: 10px; align-items: flex-start; padding: 10px 0; min-height: 44px; }
.finance-choice input { width: 22px; height: 22px; flex: none; margin: 5px 0; }
.finance-obligation { display:block; width:100%; margin:8px 0; text-align:start; white-space:normal; }
.finance-obligations { margin-bottom:20px; }

.finance-person .dblock, .finance-obligation .dblock { display: block; }
.finance-choice > span { min-width: 0; flex: 1; }
.finance-choice b { display: block; margin-bottom: 4px; }

/* Transaction shares: compact entry, clear field groups and readable totals. */
.finance-options { border: 1px solid var(--border); border-radius: 16px; }
.finance-options summary { display: grid; gap: 4px; position: relative; padding: 12px 14px; padding-inline-start: 36px; min-height: 56px; cursor: pointer; list-style: none; }
.finance-options summary::-webkit-details-marker { display: none; }
.finance-options summary::before { content: "‹"; position: absolute; inset-inline-start: 14px; top: 14px; font-size: 24px; line-height: 24px; }
.finance-options[open] summary::before { transform: rotate(-90deg); }
.finance-options summary > span { display: block; }
.finance-options summary > span:first-child { font-weight: 600; }
.finance-options__body { display: grid; gap: 10px; padding: 0 14px 14px; }
.finance-options summary:focus-visible { outline: 2px solid var(--focus-ring); border-radius: 16px; }
.finance-total, .finance-summary > div { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 12px; align-items: baseline; }
.finance-total { margin: 8px 0 24px; }
.finance-own { margin-bottom: 24px; }
.finance-own__head { display: flex; flex-wrap: wrap; gap: 8px 12px; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.finance-own__head .field-label { margin: 0; }
.finance-own__head .chip { min-height: 44px; }
.finance-own .field[readonly] { color: var(--text-muted); }
.finance-person { margin: 16px 0; }
.finance-summary > div + div { margin-top: 8px; }
.finance-summary > div b { font-variant-numeric: tabular-nums; }
.finance-summary > p { margin: 10px 0 0; }
.finance-person [aria-invalid="true"], .finance-own [aria-invalid="true"] { outline: 2px solid var(--negative); }
.finance-person .fault, .finance-own .fault { margin: 8px 0 0; }
.finance-choice { cursor: pointer; }

/* Add-account action follows the last card in the RTL strip. */
.acct--add { width: 112px; min-height: 112px; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 10px; color: var(--primary);
  border: 1px dashed var(--border); font-size: .8125rem; font-weight: 700; }
.acct--add__plus { width: 40px; height: 40px; display: grid; place-items: center;
  border-radius: 50%; background: var(--primary-subtle); font-size: 1.75rem; line-height: 1; }

/* Authentication precedes every private view; modal top layers are covered too. */
.session-locked #app, .session-locked .onb,
.session-locked dialog:not([data-session-auth]), .session-locked .undobar {
  visibility: hidden !important; pointer-events: none !important;
}
.session-gate { min-height: 100dvh; display: grid; place-items: center; padding: 24px 18px;
  padding-top: max(24px, env(safe-area-inset-top)); padding-bottom: max(24px, env(safe-area-inset-bottom)); }
.session-gate__card { width: min(100%, 400px); padding: 28px 22px; border-radius: 24px;
  background: var(--surface); border: 1px solid var(--border); }
.session-gate__brand { color: var(--primary); font-weight: 800; font-size: 1.625rem; margin-bottom: 28px; }
.session-gate h1 { font-size: 1.375rem; margin: 0 0 12px; line-height: 1.7; }
.session-gate p { font-size: .9375rem; line-height: 2; color: var(--text-muted); margin: 0; overflow-wrap: anywhere; }
.session-gate__actions { display: grid; gap: 10px; margin: 26px 0 22px; }
.session-gate small { color: var(--text-muted); font-size: .75rem; }

/* Mobile layout: stable page bounds, quieter controls and readable numerals. */
html[data-text-size="large"] { font-size: 18px; }
.sheet__head, .sheet__grab { flex-shrink: 0; }
.sheet__body { overscroll-behavior: contain; scroll-padding-block: 12px; }
.sheet--out::backdrop { animation: backdropIn var(--dur-2) reverse both; }
.sheet--page .sheet__body { padding-bottom: calc(22px + env(safe-area-inset-bottom)); }
.sheet > .toast, .sheet > .undobar { position: absolute; }
.sheet:has(.sheet__bar:not([hidden])) > .toast,
.sheet:has(.sheet__bar:not([hidden])) > .undobar { bottom: calc(88px + env(safe-area-inset-bottom)); }
.acct--add { border-color: var(--border-strong); }
.finance-save-summary { margin: 0 0 8px; font-size: .8125rem; line-height: 1.65; }
.draft-notice { padding: 10px 12px; margin-bottom: 12px; border-radius: 12px; background: var(--primary-subtle); font-size: .8125rem; }
.draft-notice button { margin-inline-start: 12px; }
.inbox-tools { margin-bottom: 12px; }
.inbox-tools summary { cursor: pointer; min-height: 44px; padding-block: 10px; color: var(--primary); font-weight: 600; }
/* همان فلشِ پایین‌روی گروه‌های تنظیمات، نه مثلثِ مرورگر. */
.inbox-tools > summary { display: flex; align-items: center; gap: 10px; list-style: none; }
.inbox-tools .card { margin-top: 8px; }
.inbox-tools #autoHint { margin-bottom: 0; }
.inbox-selection { padding: 10px 18px calc(10px + env(safe-area-inset-bottom)); }
.inbox-selection .bulkbar { margin: 0; }
.bank-flow-help { margin: 0 0 12px; }
.bank-flow-help summary { cursor: pointer; min-height: 44px; display: flex; align-items: center; color: var(--primary); }
.bank-flow-help p { margin: 0 0 10px; }
.quick-manage { display: flex; gap: 10px; flex-wrap: wrap; margin: 12px 0; }
.quick-manage .chip { min-height: 44px; }
.bottom-dock { pointer-events: none; position: fixed; z-index: 24; inset: auto 0 0;
  height: calc(var(--tabbar-bottom) + var(--tabbar-h) + 12px + env(safe-area-inset-bottom));
  background: var(--bg-subtle); border-top: 1px solid var(--border); }
.app--fab .bottom-dock { height: calc(var(--tabbar-bottom) + var(--tabbar-h) + 12px + 54px + 12px + env(safe-area-inset-bottom)); }
@media (prefers-reduced-motion: reduce) { .sheet--out::backdrop { animation: none; } }


/* Subscription state: stays readable at narrow widths and large text sizes. */
.pro-expiry { margin: 0 0 16px; padding: 16px; border: 1px solid var(--border); border-radius: 20px; background: var(--surface); text-align: start; }
.pro-expiry p { margin: 8px 0 12px; line-height: 1.9; font-size: .875rem; }
.pro-expiry__actions { display: flex; flex-wrap: wrap; gap: 8px; }
.pro-expiry__actions .btn { flex: 1 1 120px; min-height: 44px; white-space: normal; }
/* Optional bank fee: contained, readable at 320px and above the keyboard. */
.fee-block { margin-block: 18px; min-width: 0; }
.fee-block summary { cursor: pointer; min-height: 44px; display: flex; align-items: center; gap: 8px; }
.fee-block details { border: 1px solid var(--border); border-radius: 14px; padding: 4px 14px; }
.fee-block details[open] { padding-bottom: 12px; }
.fee-block p { line-height: 1.9; margin-block: 10px 0; }
.fee-suggestion { background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 14px; margin-bottom: 12px; }
.fee-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
#feeTotal { padding: 10px 12px; border-inline-start: 3px solid var(--border); }

.fee-actions button { min-height: 44px; }
.fee-block summary::after { content: '+'; margin-inline-start: auto; font-size: 20px; }
.fee-block details[open] summary::after { content: '−'; }

/* Everyday tasks: compact hierarchy, readable details and touch targets. */
html[data-text-size="larger"] { font-size: 20px; }
.offbar { padding: 0; }
.delivery-status { display: block; width: 100%; min-height: 44px; padding: 8px 12px; border: 0; border-radius: inherit; background: transparent; color: var(--text-muted); font: inherit; font-size: .875rem; line-height: 1.7; cursor: pointer; }
.delivery-status[data-state="review"], .delivery-status[data-state="error"] { color: var(--text); }
.bank-account-list { display: grid; gap: 12px; margin-block: 16px 4px; }
.bank-account-option { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 52px; text-align: start; cursor: pointer; }
.bank-account-option svg { width: 22px; height: 22px; flex: 0 0 22px; color: var(--primary); }
.bank-account-option span { overflow-wrap: anywhere; }
.export-range-tabs { grid-auto-flow: row; grid-template-columns: 1fr 1fr; gap: 4px; }
.export-range-tabs button { min-height: 44px; }
.export-month { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-block: 16px; }
.export-month label, .export-custom > label { font-size: .875rem; font-weight: 600; min-width: 0; }
.export-month .field { margin-top: 6px; width: 100%; min-width: 0; }
.export-month select { color: var(--text); background-color: var(--bg-subtle); font-family: inherit; }
.export-month .field, .export-date .field { font-size: max(16px, 1rem); }
.export-custom { margin-top: 16px; }
.export-date { display: grid; grid-template-columns: minmax(0,1fr) auto; gap: 8px; margin-block: 6px 12px; }
.export-date .field { min-width: 0; width: 100%; }
.export-date button { min-width: 48px; min-height: 48px; }
.export-date svg { width: 22px; height: 22px; }
.export-count { margin: 12px 0 16px; line-height: 1.9; }
.export-help { margin: 16px 0 10px; line-height: 1.9; }
#exportError { color: var(--negative); font-size: .875rem; line-height: 1.8; }
.settings-section, .transaction-filters, .people-directory, .dashboard-guide { margin-bottom: 12px; padding: 0 14px; border: 1px solid var(--border); border-radius: 16px; background: var(--surface); min-width: 0; }
.settings-section > summary, .transaction-filters > summary, .people-directory > summary, .dashboard-guide > summary { min-height: 48px; padding: 12px 0; cursor: pointer; font-weight: 600; }
/* مثلثِ پیش‌فرضِ مرورگر («◄») با بقیه‌ی فلش‌های اپ نمی‌خواند؛ یک فلشِ
   پایین‌رو که با باز شدن برمی‌گردد. جهت‌خنثی است، پس در RTL درست می‌ماند. */
.settings-section > summary, .transaction-filters > summary, .people-directory > summary, .dashboard-guide > summary {
  display: flex; align-items: center; gap: 10px; list-style: none;
}
:is(.settings-section, .transaction-filters, .people-directory, .dashboard-guide, .inbox-tools) > summary::-webkit-details-marker { display: none; }
:is(.settings-section, .transaction-filters, .people-directory, .dashboard-guide, .inbox-tools) > summary::after {
  content: ""; flex: none; margin-inline-start: auto;
  width: 8px; height: 8px; margin-block-start: -4px;
  /* ⚠️ جهتِ فیزیکی، عمداً: در RTL «inline-end» چپ است و فلش به چپ می‌چرخید —
     درست شکلِ فلشِ ردیف‌هایی که به صفحه‌ی دیگر می‌روند. این یکی باید پایین باشد. */
  border-right: 2px solid var(--text-muted); border-bottom: 2px solid var(--text-muted);
  transform: rotate(45deg); transition: transform var(--dur-2) var(--ease-move);
}
:is(.settings-section, .transaction-filters, .people-directory, .dashboard-guide, .inbox-tools)[open] > summary::after {
  transform: rotate(-135deg); margin-block-start: 4px;
}
.settings-section[open], .transaction-filters[open], .people-directory[open], .dashboard-guide[open] { padding-bottom: 12px; }
.settings-section .group { margin-bottom: 0; }
.settings-section .small, .backup-explainer, .version-diff, .filter-summary, .person-entry { font-size: .875rem; line-height: 1.9; }
.transaction-filters { width: 100%; box-sizing: border-box; }
/* جست‌وجو و «فیلتر» در یک ردیف؛ فیلترِ باز ردیفِ خودش را می‌گیرد. */
.filterrow { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-start; margin-bottom: 12px; }
.filterrow .search { flex: 1 1 200px; margin-bottom: 0; }
.filterrow .transaction-filters { flex: 0 0 auto; width: auto; margin-bottom: 0; }
.filterrow .transaction-filters[open] { flex-basis: 100%; }
.filterrow .transaction-filters > summary { min-height: 46px; padding: 0 2px; gap: 6px; }
.filterrow .transaction-filters > summary > svg { width: 18px; height: 18px; flex: none; color: var(--text-muted); }
/* نوعِ تراکنش در یک خط: «برداشت و هزینه» دو خط می‌شد. ستون‌ها به اندازه‌ی متن. */
#typeFilter { grid-auto-columns: auto; }
#typeFilter button { white-space: nowrap; padding-inline: 10px; font-size: .8125rem; }
.transaction-filters .field-label { margin-block: 12px 6px; }
.transaction-filters .field { width: 100%; min-width: 0; }
.filter-summary:empty, #filterError:empty { display: none; }
#clearFilters { min-height: 44px; }
.people-directory [data-person] { margin-top: 8px; white-space: normal; }
.person-entry { display: grid; gap: 6px; width: 100%; margin: 10px 0; padding: 14px; min-height: 48px; border: 1px solid var(--border); border-radius: 14px; background: var(--surface); color: var(--text); text-align: start; cursor: pointer; overflow-wrap: anywhere; }
.person-entry > span { color: var(--text-muted); }
.report-heading { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 8px; margin-bottom: 10px; }
.report-title { margin: 0 2px 10px; font-size: 1.0625rem; }
.segrow { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; margin-bottom: 12px; }
.segrow .seg { margin-bottom: 0; }
.bank-flow-card .bank-flow-help { margin: 6px 0 0; }
.report-heading h2 { font-size: 1rem; margin: 0; }
.report-heading .btn { min-height: 44px; }
.finance-save-summary { font-size: .875rem; line-height: 1.65; }
.summary-state { display: block; color: var(--text-muted); margin-bottom: 4px; }
.summary-pair { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 2px 10px; }
.cash-label { display: block; color: var(--text-muted); font-size: .875rem; font-weight: 400; direction: rtl; margin-bottom: 4px; }
.version-diff { padding: 12px; margin-bottom: 14px; border-inline-start: 3px solid var(--primary); background: var(--primary-subtle); border-radius: 10px; }
.version-diff p { margin: 4px 0; }
.bulk-delete { color: var(--negative); border: 1px solid var(--border); min-height: 44px; }
.bigamt { padding-block: 12px; margin-block: 8px; }
.quickamt { min-height: 0; margin-bottom: 10px; }
.quickamt:has(#zeros:not([hidden])) { min-height: 44px; }
.irow__main > span, .nrow__main > span { font-size: .875rem; }

.pro-expiry > summary { min-height: 44px; cursor: pointer; line-height: 1.8; }
.pro-expiry > summary .dblock { display: block; font-weight: 400; }

[data-finance-version] { margin-block: 12px; padding: 0 12px; border: 1px solid var(--border); border-radius: 12px; }
[data-finance-version] > summary { min-height: 44px; padding-block: 10px; cursor: pointer; }

.cash-label { max-inline-size: 10rem; white-space: normal; }
#deliveryReview { margin-bottom: 8px; }

.transaction-filters select.field { font: inherit; font-size: max(16px, 1rem); background: var(--bg-subtle); color: var(--text); border: 1px solid var(--border); border-radius: 14px; padding: 12px; min-height: 48px; }
