/* GENERATED by tools/build_css_bundles.py — do not edit directly.
   Exact source order is recorded at every boundary. */

/* ===== BEGIN tokens.css sha256:418c8df32ec526f4 ===== */
/* ==========================================================================
   Bazarche — Design Tokens · «فیروزه و لاجورد اصیل ایرانی» (Persian Turquoise & Obsidian Lapis)
   ==========================================================================
   هویت بصری اختصاصی، تک و متمایز بازارچه:
     • رنگ اصلی: فیروزه‌ای اصیل ایرانی (Persian Turquoise / Jewel Teal)
     • رنگ مکمل کنشی: کهربایی/زعفرانی گرم ایرانی (Persian Saffron / Amber Glow)
     • زمینهٔ روز: مرواریدی بسیار تمیز، ملایم و چشم‌نواز با کارت‌های شناور
     • زمینهٔ شب: آبسیدین لاجوردی عمیق (Deep Persian Obsidian) با درخشش فیروزه‌ای
     • کنتراست تضمین‌شدهٔ WCAG 2.2 AA (تمام متن‌ها ≥ ۴٫۵:۱)
   ========================================================================== */

/* ---------- Fonts (self-hosted, no network needed) ---------- */
@font-face {
  font-family: 'Vazirmatn';
  src: url('../fonts/Vazirmatn-Variable.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* ==========================================================================
   ۰) رنگ‌های پایه (رَمپ‌ها)
   ========================================================================== */
:root {
  /* ---------- Brand ramp — فیروزه‌ای اصیل ایرانی (Persian Teal) ---------- */
  --brand-50:  #f0fdfa;
  --brand-100: #ccfbf1;
  --brand-200: #99f6e4;
  --brand-300: #5eead4;
  --brand-400: #2dd4bf;
  --brand-500: #0d9488;
  --brand-600: #0f766e;
  --brand-700: #0b6059;
  --brand-800: #084c47;
  --brand-900: #042f2c;

  /* ---------- Neutral ramp — سنگ خنثی و باوقار (Slate / Pearl) ---------- */
  --gray-50:  #f8fafc;
  --gray-100: #f1f5f9;
  --gray-200: #e2e8f0;
  --gray-300: #cbd5e1;
  --gray-400: #94a3b8;
  --gray-500: #64748b;
  --gray-600: #475569;
  --gray-700: #334155;
  --gray-800: #1e293b;
  --gray-900: #0f172a;
  --gray-950: #020617;

  /* ---------- Functional ramps (موفقیت/هشدار/خطر/اطلاع) ---------- */
  --green-500: #047857;   /* روز: ۵٫۲:۱ روی سفید */
  --green-300: #34d399;   /* شب */
  --red-500:   #b91c1c;   /* روز: ۵٫۶:۱ روی سفید */
  --red-300:   #f87171;   /* شب */
  --amber-500: #92400e;   /* روز: زعفرانی غنی و خوانا — ۵٫۸:۱ روی سفید */
  --amber-400: #f59e0b;
  --amber-300: #fbbf24;   /* شب */
  --sky-500:   #075985;   /* روز: ۶٫۸:۱ روی سفید */
  --sky-300:   #38bdf8;   /* شب */

  /* ---------- سازگاری با نام‌های پیشین ---------- */
  --accent-300: var(--amber-300);
  --accent-400: var(--amber-400);
  --accent-500: #d97706;
  --accent-600: #b45309;
  --accent-700: #92400e;

  --gold-200: var(--amber-300);
  --gold-300: var(--amber-400);
  --gold-400: #d97706;
  --gold-500: #d97706;
  --gold-600: #b45309;

  --aurora-v: var(--brand-300);
}

/* ==========================================================================
   ۱) توکن‌های معنایی — حالت روز (پیش‌فرض، روی :root)
   ========================================================================== */
:root {
  color-scheme: light;

  --color-primary:         #2f6b45;            /* سبز گیاهی روز؛ ۶٫۲:۱ با سفید */
  --color-primary-hover:   #245638;
  --color-on-primary:      #ffffff;
  --color-secondary:       var(--gray-100);
  --color-on-secondary:    var(--gray-900);
  --color-accent:          var(--amber-500);   /* زعفرانی گرم برای اقدامات ویژه */
  --color-accent-hover:    #b45309;
  --color-on-accent:       #ffffff;
  --color-neon:            var(--brand-500);
  --color-on-neon:         #ffffff;
  --color-on-brand:        var(--brand-50);
  --color-brand-ink:       var(--brand-900);

  --color-background:      #f7f1e3;    /* کرم گرم و آشکارا متمایز از شب */
  --color-background-2:    #eee5d2;
  --color-foreground:      #1f2a22;    /* جوهر سبز-زغالی */
  --color-card:            #fffdf8;
  --color-card-foreground: #1f2a22;
  --color-surface:         #fbf8ef;
  --color-muted:           #efe9da;
  --color-muted-foreground: #526157;
  --color-faint:           #657267;
  --color-border:          #ddd4c2;
  --color-border-strong:   #c8bca6;

  --color-destructive:     var(--red-500);
  --color-on-destructive:  #ffffff;
  /* v330-fix (دسترس‌پذیری): متنِ روی پس‌زمینهٔ success. تا امروز قواعدی
     مثل .map-me.is-on رنگ را #fff هاردکد می‌کردند که در تم شب نسبت
     کنتراست ۱٫۹۲ می‌داد (حداقل WCAG AA برابر ۴٫۵ است). */
  --color-on-success:      #ffffff;            /* ۵٫۲:۱ روی green-500 */
  --color-success:         var(--green-500);
  --color-warning:         var(--amber-500);
  --color-ring:            var(--brand-500);

  /* رنگ‌های متن معنایی با کنتراست عالی */
  --color-primary-text:  var(--brand-700);     /* ۵٫۴:۱ روی سفید */
  --color-success-text:  var(--green-500);     /* ۴٫۸:۱ */
  --color-danger-text:   var(--red-500);       /* ۵٫۰:۱ */
  --color-info-text:     var(--sky-500);       /* ۴٫۷:۱ */
  /* F-13 (2026-10-31): --color-info was referenced by 19 rules in five
     stylesheets — the contextual-help badge among them — but never
     defined, so `background: var(--color-info)` fell back to
     transparent and the white mark rendered white-on-white (1.1:1). */
  --color-info:          var(--sky-500);       /* ۷٫۴:۱ با سفید */
  --color-on-info:       #ffffff;
  --color-danger:        var(--red-500);
  /* v289 a11y: was #b45309, commented "۵٫۲:۱". That figure only holds on pure
     white. Pixel-sampled on the surfaces it actually renders on — the inbox
     badge chip rgb(235,221,209) and the backup notice rgb(242,232,226) — it
     measured 3.78:1 and 4.16:1, both under the 4.5:1 WCAG AA floor for 14px
     text. #8c4410 is the same amber hue darkened enough to clear 4.5:1 on the
     darker of the two chips (5.36:1) while still reading as a warning. */
  --color-warning-text:  #8c4410;             /* ۵٫۴:۱ روی چیپ کرم، ۶٫۶:۱ روی سفید */

  /* حلقهٔ استوری — فیروزه و کهربا */
  --ring-conic: conic-gradient(from 140deg, var(--brand-500) 0%, var(--amber-400) 50%, var(--brand-600) 100%);
  --story-ring-glow: rgba(13, 148, 136, 0.25);

  /* ---------- لایهٔ شیشه‌ای ---------- */
  --glass-bg:        rgba(255, 253, 248, 0.97);
  --glass-bg-strong: #fffdf8;
  --glass-bg-weak:   rgba(251, 248, 239, 0.94);
  --glass-border:    #ddd4c2;
  --glass-hairline:  #ddd4c2;
  --glass-blur:      0px;
  --glass-blur-lg:   0px;
  --glass-specular:  none;

  --wash-1: transparent;
  --wash-2: transparent;
  --wash-3: transparent;

  /* ---------- سایه‌های چندلایهٔ شناور و لمسی (Tactile Floating Elevations) ---------- */
  --e1: 0 1px 3px rgba(15, 23, 42, 0.05), 0 1px 2px rgba(15, 23, 42, 0.03);
  --e2: 0 4px 6px -1px rgba(15, 23, 42, 0.07), 0 2px 4px -2px rgba(15, 23, 42, 0.04);
  --e3: 0 10px 15px -3px rgba(15, 23, 42, 0.08), 0 4px 6px -4px rgba(15, 23, 42, 0.03);
  --e4: 0 20px 25px -5px rgba(15, 23, 42, 0.10), 0 8px 10px -6px rgba(15, 23, 42, 0.04);
  --e-glow:      0 0 0 3px rgba(13, 148, 136, 0.20), 0 8px 24px rgba(11, 96, 89, 0.18);
  --e-glow-gold: 0 0 0 3px rgba(217, 119, 6, 0.20), 0 8px 24px rgba(217, 119, 6, 0.18);
  --e-inset-top: none;

  /* ---------- فاصله ---------- */
  --space-xs:  4px;
  --space-sm:  8px;
  --space-md:  16px;
  --space-lg:  24px;
  --space-xl:  32px;
  --space-2xl: 48px;
  --space-3xl: 64px;
  --space-4xl: 96px;

  /* ---------- شعاع گوشه‌ها — نرم، مدرن و اصیل ---------- */
  --radius-xs:  4px;
  --radius-sm:  6px;
  --radius-md:  8px;
  --radius-lg:  12px;
  --radius-xl:  16px;
  --radius-2xl: 20px;
  --radius-pill: 999px;

  /* ---------- تایپوگرافی ---------- */
  --font-sans: 'Vazirmatn', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --fs-xs:   clamp(0.75rem, 0.72rem + 0.1vw, 0.8125rem);   /* ۱۲–۱۳px */
  --fs-sm:   clamp(0.8125rem, 0.8rem + 0.1vw, 0.875rem);   /* ۱۳–۱۴px */
  --fs-md:   clamp(0.875rem, 0.86rem + 0.12vw, 0.9375rem); /* ۱۴–۱۵px */
  --fs-base: clamp(0.9375rem, 0.92rem + 0.1vw, 1rem);      /* ۱۵–۱۶px */
  --fs-lg:   clamp(1rem, 0.97rem + 0.15vw, 1.125rem);      /* ۱۶–۱۸px */
  --fs-xl:   clamp(1.125rem, 1.05rem + 0.3vw, 1.375rem);   /* ۱۸–۲۲px */
  --fs-2xl:  clamp(1.375rem, 1.25rem + 0.5vw, 1.75rem);    /* ۲۲–۲۸px */
  --fs-3xl:  clamp(1.5rem, 1.35rem + 0.6vw, 2rem);         /* ۲۴–۳۲px */
  --fs-4xl:  clamp(1.75rem, 1.55rem + 0.8vw, 2.5rem);      /* ۲۸–۴۰px */
  --lh-tight: 1.25;
  --lh-snug:  1.4;
  --lh-base:  1.6;

  /* ---------- حرکت و ترنزیشن ---------- */
  --dur-1: 100ms;
  --dur-2: 160ms;
  --dur-3: 220ms;
  --dur-4: 300ms;
  --dur-5: 420ms;
  --ease-out:    cubic-bezier(0.2, 0, 0, 1);
  --ease-inout:  cubic-bezier(0.4, 0, 0.2, 1);
  --ease-spring: cubic-bezier(0.2, 0, 0, 1);
  --ease-lux:    cubic-bezier(0.2, 0, 0, 1);

  /* ---------- چیدمان ---------- */
  --container: 1200px;
  --container-wide: 1400px;
  --header-h: 64px;
  --z-bg: 0;
  --z-content: 10;
  --z-sticky: 100;
  --z-header: 200;
  --z-overlay: 300;
  --z-modal: 400;
  --z-toast: 500;

  /* ---------- پایهٔ لمسی موبایل ---------- */
  --tap: 44px;
  --tap-lg: 48px;
  --botnav-h: 64px;
  --callbar-h: 60px;
}

/* ==========================================================================
   ۲) حالت شب — آبسیدین لاجوردی عمیق (Deep Persian Obsidian)
   ========================================================================== */
:root[data-theme="dark"],
:root[data-theme="night"],
:root[data-theme="luxury"] {
  color-scheme: dark;

  --brand-50:  #061a18;
  --brand-100: #0a2926;
  --brand-200: #10443f;
  --brand-300: #5eead4;
  --brand-400: #2dd4bf;
  --brand-500: #14b8a6;
  --brand-600: #0d9488;
  --brand-700: #0f766e;
  --brand-800: #0b6059;
  --brand-900: #f0fdfa;

  --color-primary:         var(--brand-500);   /* #14b8a6 — درخشش فیروزه‌ای در شب */
  --color-primary-hover:   var(--brand-400);
  --color-on-primary:      #042f2c;            /* متن تیره روی دکمهٔ فیروزه‌ای شب — ۹٫۵:۱ */
  --color-secondary:       #1a1918;
  --color-on-secondary:    #f4f1ea;
  --color-accent:          var(--amber-400);
  --color-accent-hover:    var(--amber-300);
  --color-on-accent:       #451a03;            /* ۹٫۸:۱ */
  --color-neon:            var(--brand-400);
  --color-on-neon:         #042f2c;
  --color-on-brand:        #ccfbf1;
  --color-brand-ink:       #0f172a;

  /* v281: پوستهٔ شبِ گرم — پس‌زمینه قهوه‌ای بسیار تیره و سطح‌های خنثیِ
     نزدیک به مشکی، هم‌رنگ با اسکرین‌شات‌های تولید (به‌جای سرمه‌ای قدیم). */
  --color-background:      #26231e;    /* قهوه‌ای بسیار تیرهٔ گرم */
  --color-background-2:    #1b1815;
  --color-foreground:      #f4f1ea;    /* سفید گرم */
  --color-card:            #121212;    /* سطح خنثی نزدیک به مشکی */
  --color-card-foreground: #f4f1ea;
  --color-surface:         #121212;
  --color-muted:           #1a1918;
  --color-muted-foreground: #a8a29e;   /* خاکستری گرم */
  --color-faint:           #a8a29e;
  --color-border:          #2b2823;
  --color-border-strong:   #3b372f;

  --color-destructive:     #f87171;
  --color-on-destructive:  #450a0a;
  --color-on-success:      #022c22;            /* ۷٫۸۸:۱ روی #34d399 */
  --color-success:         #34d399;
  --color-warning:         #fbbf24;
  --color-ring:            var(--brand-400);

  --color-primary-text:  var(--brand-400);     /* فیروزه‌ای درخشان — ۱۰٫۵:۱ روی کارت */
  --color-success-text:  #34d399;              /* ۱۰٫۲:۱ */
  --color-danger-text:   #f87171;              /* ۷٫۸:۱ */
  --color-info-text:     #38bdf8;              /* ۹٫۶:۱ */
  --color-danger:        #f87171;
  --color-warning-text:  #fbbf24;              /* ۱۱٫۵:۱ */

  --ring-conic: conic-gradient(from 140deg, var(--brand-400) 0%, var(--amber-400) 50%, var(--brand-500) 100%);
  --story-ring-glow: rgba(45, 212, 191, 0.28);

  --glass-bg:        rgba(18, 18, 18, 0.96);
  --glass-bg-strong: #121212;
  --glass-bg-weak:   rgba(18, 18, 18, 0.88);
  --glass-border:    #2b2823;
  --glass-hairline:  #2b2823;
  --glass-specular:  none;

  --e1: 0 1px 3px rgba(0, 0, 0, 0.40);
  --e2: 0 4px 6px -1px rgba(0, 0, 0, 0.45);
  --e3: 0 10px 15px -3px rgba(0, 0, 0, 0.50);
  --e4: 0 20px 25px -5px rgba(0, 0, 0, 0.55);
  --e-glow:      0 0 0 3px rgba(45, 212, 191, 0.25), 0 8px 24px rgba(20, 184, 166, 0.22);
  --e-glow-gold: 0 0 0 3px rgba(245, 158, 11, 0.25), 0 8px 24px rgba(245, 158, 11, 0.22);
}

/* ==========================================================================
   ۳) موبایل
   ========================================================================== */
@media (max-width: 1024px) {
  :root {
    --space-2xl: 32px;
    --space-3xl: 40px;
    --space-4xl: 48px;
    --fs-xs: 0.75rem;     /* ۱۲px — کف استاندارد */
    --fs-sm: 0.8125rem;   /* ۱۳px */
    --header-h: 56px;
  }

  input, select, textarea { font-size: max(16px, var(--fs-base)) !important; }
}

/* کاهش حرکت (دسترس‌پذیری) */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
/* ===== END tokens.css ===== */

/* ===== BEGIN main.css sha256:6317194a1a8558ae ===== */
/* ==========================================================================
   v281 — استاندارد: ویژگی hidden باید همیشه ببرد. display نویسنده (مثل
   display:flex روی .ai-quotaend) بر قاعدهٔ UA یعنی [hidden]{display:none}
   غلبه می‌کرد و بنر «سهمیه تمام شد» را حتی با اعتبارِ باقی‌مانده همیشه
   نمایش می‌داد. این reset سراسری همان الگوی استاندارد فریم‌ورک‌هاست.
   ========================================================================== */
[hidden] { display: none !important; }

/* ==========================================================================
   Bazarche Najafabad — Core UI  (Spatial UI / Glassmorphism, RTL)
   Depends on tokens.css
   ========================================================================== */

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
/* v118: the browser UA shrinks <small> to 0.833em, which put caption text at
   10px on phones and 11.67px on desktop — under the 12px floor. Inherit the
   parent size; components opt down explicitly via --fs-xs when they want a
   caption (which is a 12-13px token, still above the floor). */
small { font-size: inherit; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  color: var(--color-foreground);
  background: var(--color-background);
  /* v63 FONT FIX: `-webkit-font-smoothing: antialiased` DISABLES subpixel
     antialiasing on Android WebView (what Pydroid 3 opens the site in),
     which is exactly why Persian text looked thin/faded. `auto` lets Android
     keep its native subpixel rendering = crisp, full-weight glyphs. */
  -webkit-font-smoothing: auto;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: auto;
  font-synthesis: none;             /* never fake-bold a Persian glyph */
  min-height: 100dvh;
  overflow-x: hidden;
}

/* ---- Dark-mode typography ----
   Fix (v56): the earlier attempt nudged body text to a FRACTIONAL weight
   (450/480) and added letter-spacing. Both are wrong for Persian:
     • letter-spacing breaks the connected script and reads as "faded" gaps;
     • fractional weights interpolate the variable font inconsistently, so
       individual glyphs render thinner than their neighbours.
   The correct, masterful fix is to leave weight alone (400) and rely on the
   already-fixed muted-foreground colour for contrast. Integer 500 is used
   only where a genuine half-step is wanted — never a fractional value. */
/* v111: token-based contrast made the per-theme weight nudge obsolete. */

img, svg, video, canvas { display: block; max-width: 100%; }
/* Inline icons carry no intrinsic size: without this an unclassed <svg> falls
   back to the CSS default 300x150 and blows the layout apart. */
svg:not([width]):not([height]) { width: 1.15em; height: 1.15em; flex: none; }
img { height: auto; }
input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; padding: 0; }
table { border-collapse: collapse; width: 100%; }
h1,h2,h3,h4,h5 { line-height: var(--lh-tight); font-weight: 800; text-wrap: balance; }
p { text-wrap: pretty; }
:target { scroll-margin-top: calc(var(--header-h) + 24px); }

/* ---------- Accessibility ---------- */
:focus-visible {
  outline: 3px solid var(--color-ring);
  outline-offset: 3px;
  border-radius: var(--radius-xs);
}
:focus:not(:focus-visible) { outline: none; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0;
  margin: -1px; overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; inset-inline-start: 50%; top: -100px;
  transform: translateX(50%);
  z-index: var(--z-toast);
  background: var(--color-primary); color: var(--color-on-primary);
  padding: 12px 22px; border-radius: 0 0 var(--radius-md) var(--radius-md);
  font-weight: 700; transition: top var(--dur-2) var(--ease-out);
}
.skip-link:focus { top: 0; }

/* ==========================================================================
   SPATIAL BACKDROP — the depth substrate every glass surface samples
   ========================================================================== */
.spatial-bg {
  /* v111 formal: a flat wash. The aurora orbs that drifted here were the
     luxury identity; the neutral site keeps one token colour. */
  position: fixed; inset: 0; z-index: var(--z-bg);
  pointer-events: none; overflow: hidden;
  background: var(--color-background);
}

/* ── Aurora mesh ────────────────────────────────────────────────────────
   Five independently drifting orbs rather than one baked image. This is the
   pattern Stripe, Linear and Vercel all ship: it retints from the theme
   tokens, never pixelates, costs one paint layer instead of a 400KB JPEG,
   and gives backdrop-filter something alive to sample.
   Motion is deliberately slow and low-amplitude — a background that moves
   quickly under a paragraph makes the text feel unstable.
   ------------------------------------------------------------------- */
.spatial-bg::before, .spatial-bg::after, .spatial-bg .orb { display: none; }
.spatial-bg::before {
  width: 46vmax; height: 46vmax; inset-inline-end: -12vmax; top: -14vmax;
  background: radial-gradient(circle at 30% 30%, var(--brand-400), transparent 70%);
  animation: orbFloatA 26s var(--ease-inout) infinite alternate;
}
.spatial-bg::after {
  width: 38vmax; height: 38vmax; inset-inline-start: -10vmax; bottom: -12vmax;
  background: radial-gradient(circle at 60% 40%, var(--accent-400), transparent 70%);
  animation: orbFloatB 32s var(--ease-inout) infinite alternate;
}
.spatial-bg .orb-1 {
  width: 34vmax; height: 34vmax; inset-inline-start: 22%; top: -8vmax;
  background: radial-gradient(circle at 50% 50%, var(--brand-300, var(--brand-400)), transparent 68%);
  opacity: .34;
  animation: orbFloatC 38s var(--ease-inout) infinite alternate;
}
.spatial-bg .orb-2 {
  width: 30vmax; height: 30vmax; inset-inline-end: 14%; bottom: -6vmax;
  background: radial-gradient(circle at 40% 60%, var(--accent-300, var(--accent-400)), transparent 66%);
  opacity: .28;
  animation: orbFloatD 44s var(--ease-inout) infinite alternate;
}
.spatial-bg .orb-3 {
  width: 26vmax; height: 26vmax; inset-inline-start: 46%; top: 34%;
  background: radial-gradient(circle at 50% 50%, var(--brand-500), transparent 64%);
  opacity: .2;
  animation: orbFloatE 52s var(--ease-inout) infinite alternate;
}
@keyframes orbFloatA {
  from { transform: translate3d(0,0,0) scale(1); }
  to   { transform: translate3d(-6vmax, 5vmax, 0) scale(1.14); }
}
@keyframes orbFloatB {
  from { transform: translate3d(0,0,0) scale(1.08); }
  to   { transform: translate3d(5vmax, -4vmax, 0) scale(1); }
}
@keyframes orbFloatC {
  from { transform: translate3d(0,0,0) scale(1); }
  to   { transform: translate3d(7vmax, 6vmax, 0) scale(1.2); }
}
@keyframes orbFloatD {
  from { transform: translate3d(0,0,0) scale(1.1); }
  to   { transform: translate3d(-8vmax, -3vmax, 0) scale(.94); }
}
@keyframes orbFloatE {
  from { transform: translate3d(-4vmax,0,0) scale(.9); }
  to   { transform: translate3d(4vmax, -6vmax, 0) scale(1.16); }
}
/* Respect the OS setting: freeze the drift, keep the colour. */
@media (prefers-reduced-motion: reduce) {
  .spatial-bg::before, .spatial-bg::after, .spatial-bg .orb { animation: none; }
}
/* A phone GPU should not push five blurred 40vmax layers. */
@media (max-width: 760px) {
  .spatial-bg .orb-2, .spatial-bg .orb-3 { display: none; }
  .spatial-bg::before, .spatial-bg::after { filter: blur(70px); }
}

/* Fine grain / noise overlay kills gradient banding on large glass areas */
.spatial-grain { display: none; }

/* ==========================================================================
   GLASS PRIMITIVES
   ========================================================================== */
.glass {
  position: relative;
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(180%);
  backdrop-filter: blur(var(--glass-blur)) saturate(180%);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--e2), var(--e-inset-top);
}
.glass-strong { background: var(--glass-bg-strong); }
.glass-weak   { background: var(--glass-bg-weak); }

/* Specular highlight sweep — sells the "pane of glass" read */
.glass::before {
  content: ''; position: absolute; inset: 0;
  border-radius: inherit; pointer-events: none;
  background: var(--glass-specular);
  opacity: .7;
}
/* Fallback for browsers without backdrop-filter */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass { background: var(--color-card); }
}

/* ==========================================================================
   LAYOUT
   ========================================================================== */
.container {
  width: min(100% - 2 * var(--space-lg), var(--container));
  margin-inline: auto;
}
.container-wide {
  width: min(100% - 2 * var(--space-lg), var(--container-wide));
  margin-inline: auto;
}
.section { padding-block: var(--space-4xl); position: relative; z-index: var(--z-content); }
.section-sm { padding-block: var(--space-2xl); position: relative; z-index: var(--z-content); }

.stack > * + * { margin-top: var(--space-md); }
.stack-lg > * + * { margin-top: var(--space-lg); }

.grid { display: grid; gap: var(--space-lg); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 230px), 1fr)); }

.cluster { display: flex; flex-wrap: wrap; gap: var(--space-sm); align-items: center; }
.between { display: flex; flex-wrap: wrap; gap: var(--space-md); align-items: center; justify-content: space-between; }

.main-content { position: relative; z-index: var(--z-content); min-height: 60dvh; }

/* ---------- Section headings ---------- */
.section-head { margin-bottom: var(--space-2xl); max-width: 62ch; }
/* The eyebrow pill.

   This used to be scoped to `.section-head .eyebrow`, so on every
   `.page-hero` it fell back to a plain inline element: the icon and the
   words wrapped onto separate lines and the label sat there unstyled and
   crooked. Nine pages were affected (/submit /nearby /events
   /pricing /contact /compare /offers /blog) — this is the "text not in its
   proper place, disorderly" the shopkeeper reported.

   Styling the class itself, wherever it appears, fixes all of them at once
   and stops the next new page inheriting the same bug. */
.eyebrow,
.section-head .eyebrow {
  display: inline-flex; align-items: center; gap: var(--space-xs);
  font-size: var(--fs-sm); font-weight: 700; letter-spacing: .02em;
  color: var(--color-primary-text);
  padding: 6px 14px; border-radius: var(--radius-pill);
  background: color-mix(in oklab, var(--color-primary) 12%, transparent);
  border: 1px solid color-mix(in oklab, var(--color-primary) 22%, transparent);
  margin-bottom: var(--space-md);
  /* the icon and its label are one unit and must never wrap apart */
  white-space: nowrap;
  max-width: 100%;
}
.eyebrow svg { width: 16px; height: 16px; flex: none; }
.eyebrow > span {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.section-head h2 { font-size: var(--fs-3xl); }
.section-head p { margin-top: var(--space-sm); color: var(--color-muted-foreground); font-size: var(--fs-lg); }
.section-head.center { margin-inline: auto; text-align: center; }

/* ==========================================================================
   3D TILT / DEPTH ENGINE  (CSS side — JS adds --mx/--my/--rx/--ry)
   ========================================================================== */
.scene-3d { perspective: 1200px; perspective-origin: 50% 50%; }

.tilt {
  --rx: 0deg; --ry: 0deg; --tz: 0px;
  transform: perspective(1000px) rotateX(var(--rx)) rotateY(var(--ry)) translateZ(var(--tz));
  transform-style: preserve-3d;
  transition: transform var(--dur-4) var(--ease-out), box-shadow var(--dur-3) var(--ease-out);
  will-change: transform;
}
.tilt:hover, .tilt:focus-within { --tz: 14px; box-shadow: var(--e4); }
.tilt.is-tracking { transition: box-shadow var(--dur-3) var(--ease-out); }

/* children lift out of the card plane */
.tilt .layer-1 { transform: translateZ(18px); transform-style: preserve-3d; }
.tilt .layer-2 { transform: translateZ(36px); transform-style: preserve-3d; }
.tilt .layer-3 { transform: translateZ(58px); transform-style: preserve-3d; }

/* Cursor-following sheen for tilt surfaces */
.tilt .sheen {
  position: absolute; inset: 0; border-radius: inherit;
  pointer-events: none; opacity: 0;
  transition: opacity var(--dur-3) var(--ease-out);
  background: radial-gradient(320px circle at var(--mx, 50%) var(--my, 50%),
              rgba(255,255,255,.10), transparent 62%);
}
/* v111: gold sheen removed with the luxury identity. */
.tilt:hover .sheen, .tilt:focus-within .sheen { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .tilt { transform: none !important; transition: none; }
  .tilt .layer-1, .tilt .layer-2, .tilt .layer-3 { transform: none; }
  .spatial-bg::before, .spatial-bg::after { animation: none; }
}
@media (hover: none) {
  .tilt { transform: none; }  /* no pointer → no tilt, keep it honest on touch */
}

/* ==========================================================================
   BUTTONS
   ========================================================================== */
.btn {
  position: relative; isolation: isolate;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-sm);
  min-height: 46px; padding: 12px 22px;
  border-radius: var(--radius-md);
  background: var(--color-secondary);
  color: var(--color-on-secondary);
  border: 1px solid var(--color-border);
  font-weight: 700; font-size: var(--fs-sm);
  cursor: pointer; user-select: none;
  white-space: nowrap;
  transition: transform var(--dur-2) var(--ease-out),
              box-shadow var(--dur-2) var(--ease-out),
              background-color var(--dur-2) var(--ease-out),
              border-color var(--dur-2) var(--ease-out),
              color var(--dur-2) var(--ease-out);
  transform-style: preserve-3d;
}
.btn:active { transform: translateY(1px) scale(.985); }
.btn svg { width: 18px; height: 18px; flex: none; }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; transform: none; }

/* v111 formal: flat token fills. on-primary is computed per theme in
   tokens.css, so the label is AA in day AND night. */
.btn-primary {
  background: var(--color-primary);
  color: var(--color-on-primary);
  border: 1px solid transparent;
  box-shadow: var(--e1);
}
.btn-primary:hover { background: var(--color-primary-hover); box-shadow: var(--e2); transform: translateY(-1px); }

.btn-accent {
  background: var(--color-accent);
  color: var(--color-on-accent);
  border: 1px solid transparent;
  box-shadow: var(--e1);
}
.btn-accent:hover { background: var(--color-accent-hover); box-shadow: var(--e2); transform: translateY(-1px); }

.btn-glass {
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  color: var(--color-foreground);
  box-shadow: var(--e1), var(--e-inset-top);
}
.btn-glass:hover { background: var(--glass-bg-strong); transform: translateY(-2px); box-shadow: var(--e3); }

.btn-ghost { color: var(--color-foreground); border: 1px solid transparent; }
.btn-ghost:hover { background: var(--color-muted); border-color: var(--color-border); }

.btn-outline { border: 1.5px solid var(--color-border-strong); color: var(--color-foreground); }
.btn-outline:hover { border-color: var(--color-primary); color: var(--color-primary); background: color-mix(in oklab, var(--color-primary) 8%, transparent); }

.btn-danger { background: var(--color-destructive); color: var(--color-on-destructive); box-shadow: var(--e2); }
.btn-danger:hover { filter: brightness(1.08); transform: translateY(-2px); }

/* v330-stage8: even compact action buttons must keep the 44px tap floor. */
.btn-sm { min-height: var(--tap); padding: 8px 16px; font-size: var(--fs-xs); border-radius: var(--radius-sm); }
.btn-lg { min-height: 56px; padding: 16px 32px; font-size: var(--fs-base); border-radius: var(--radius-lg); }
.btn-block { width: 100%; }

/* Icon-only button — always needs aria-label (see a11y rules) */
.btn-icon {
  min-height: 44px; min-width: 44px; padding: 0;
  border-radius: var(--radius-md);
  display: inline-grid; place-items: center;
  color: var(--color-muted-foreground);
  cursor: pointer;
  transition: background-color var(--dur-2) var(--ease-out), color var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out);
}
.btn-icon:hover { background: var(--color-muted); color: var(--color-foreground); }
.btn-icon svg { width: 20px; height: 20px; }

/* ==========================================================================
   BADGES / CHIPS / PILLS  (resilient text: never let them wrap-break)
   ========================================================================== */
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 10px; border-radius: var(--radius-pill);
  font-size: var(--fs-xs); font-weight: 700; line-height: 1.4;
  white-space: nowrap; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis;
  border: 1px solid transparent;
}
/* v330-stage8: a badge can be plain text, but when it is a link/button it is
   an action target; give only interactive badges the full WCAG 44px hit area. */
a.badge, button.badge { min-height: var(--tap); padding-block: 0; }
.badge svg { width: 13px; height: 13px; flex: none; }
.badge-open    { background: #dcfce7; color: #15803d; border-color: #bbf7d0; }
.badge-closed  { background: #fee2e2; color: #b91c1c; border-color: #fecaca; }
/* v285: برچسب «ویژه» — طلایی لوکس با کنتراست بالا در هر دو تم (قبلاً در
   حالت شب تیره و در حالت روز روشن/محو می‌شد — روی شیت نقشه و فهرست‌ها). */
.badge-featured{
  background: linear-gradient(135deg, #fcd34d, #f59e0b);
  color: #201400; font-weight: 800;
  border: 1px solid rgba(255, 255, 255, .45);
  box-shadow: 0 1px 6px rgba(245, 158, 11, .40);
}
:root[data-theme="dark"] .badge-featured{
  background: linear-gradient(135deg, #fbbf24, #d97706);
  color: #241500;
  border-color: rgba(0, 0, 0, .38);
  box-shadow: 0 1px 8px rgba(251, 191, 36, .30);
}
.badge-neutral { background: var(--color-muted); color: var(--color-muted-foreground); border-color: var(--color-border); }
.badge-info    { background: #e0f2fe; color: #0369a1; border-color: #bae6fd; }
.badge-warn    { background: #fef3c7; color: #92400e; border-color: #fde68a; }

:root[data-theme="dark"] .badge-open,
:root[data-theme="night"] .badge-open,
:root[data-theme="luxury"] .badge-open { background: #063821; color: #34d399; border-color: #0b5934; }

:root[data-theme="dark"] .badge-closed,
:root[data-theme="night"] .badge-closed,
:root[data-theme="luxury"] .badge-closed { background: #400e0e; color: #f87171; border-color: #611919; }

:root[data-theme="dark"] .badge-info,
:root[data-theme="night"] .badge-info,
:root[data-theme="luxury"] .badge-info { background: #082f49; color: #38bdf8; border-color: #0c4a6e; }

:root[data-theme="dark"] .badge-warn,
:root[data-theme="night"] .badge-warn,
:root[data-theme="luxury"] .badge-warn { background: #451a03; color: #fbbf24; border-color: #78350f; }

.chip {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: var(--tap); padding: 8px 16px; /* v77: بزرگ‌شدن به ۴۴px (قانون لمس) */
  border-radius: var(--radius-pill);
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border: 1px solid var(--glass-border);
  font-size: var(--fs-sm); font-weight: 600;
  white-space: nowrap; cursor: pointer;
  transition: all var(--dur-2) var(--ease-out);
}
.chip:hover { transform: translateY(-2px); box-shadow: var(--e2); }
.chip[aria-pressed="true"], .chip.is-active {
  background: var(--color-primary);
  color: var(--color-on-primary); border-color: transparent; box-shadow: var(--e-glow);
}
.chip svg { width: 16px; height: 16px; flex: none; }

/* ==========================================================================
   FORMS
   ========================================================================== */
.field { display: block; margin-bottom: var(--space-lg); }
.field-label {
  display: block; margin-bottom: 7px;
  font-size: var(--fs-sm); font-weight: 700;
  color: var(--color-foreground);
}
.field-label .req { color: var(--color-destructive); margin-inline-start: 3px; }
.field-hint { margin-top: 6px; font-size: var(--fs-xs); color: var(--color-muted-foreground); }
.field-error {
  display: flex; align-items: center; gap: 6px;
  margin-top: 6px; font-size: var(--fs-xs); font-weight: 600;
  color: var(--color-destructive);
}
.field-error svg { width: 14px; height: 14px; flex: none; }

.input, .textarea, .select {
  width: 100%;
  min-height: 48px;
  padding: 12px 16px;
  font-size: var(--fs-base);
  color: var(--color-foreground);
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-md);
  transition: border-color var(--dur-2) var(--ease-out),
              box-shadow var(--dur-2) var(--ease-out),
              background-color var(--dur-2) var(--ease-out);
}
.textarea { min-height: 130px; resize: vertical; line-height: var(--lh-base); }
.select {
  appearance: none; cursor: pointer;
  padding-inline-end: 44px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: left 14px center;
  background-size: 18px;
}
/* v111: one neutral chevron for both themes. */

.input::placeholder, .textarea::placeholder { color: var(--color-muted-foreground); opacity: .8; }
.input:hover, .textarea:hover, .select:hover { border-color: var(--color-border-strong); }
.input:focus, .textarea:focus, .select:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--color-primary) 18%, transparent);
}
.input[aria-invalid="true"], .textarea[aria-invalid="true"], .select[aria-invalid="true"] {
  border-color: var(--color-destructive);
}
.input[aria-invalid="true"]:focus { box-shadow: 0 0 0 4px color-mix(in oklab, var(--color-destructive) 18%, transparent); }

/* Search input with leading icon */
.search-wrap { position: relative; }
.search-wrap .search-icon {
  position: absolute; inset-inline-start: 15px; top: 50%;
  transform: translateY(-50%);
  width: 20px; height: 20px; pointer-events: none;
  color: var(--color-muted-foreground);
}
.search-wrap .input { padding-inline-start: 48px; }

/* Checkbox / radio */
.check {
  display: flex; align-items: flex-start; gap: 10px;
  cursor: pointer; padding: 8px 0; min-height: 44px;
  align-items: center;
}
.check input[type="checkbox"], .check input[type="radio"] {
  width: 24px; height: 24px; flex: none; cursor: pointer;
  accent-color: var(--color-primary);
}
.check span { font-size: var(--fs-sm); }

/* Toggle switch */
.switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; min-height: 44px; }
.switch input, .switch-row input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch .track, .switch-row .track {
  width: 50px; height: 28px; border-radius: var(--radius-pill);
  background: var(--color-border-strong);
  position: relative; transition: background-color var(--dur-3) var(--ease-out);
  flex: none;
}
.switch .track::after, .switch-row .track::after {
  content: ''; position: absolute; top: 3px; inset-inline-start: 3px;
  width: 22px; height: 22px; border-radius: 50%;
  background: #fff; box-shadow: var(--e1);
  transition: transform var(--dur-3) var(--ease-spring);
}
.switch input:checked + .track { background: var(--color-primary); }
.switch input:checked + .track::after { transform: translateX(-22px); }
.switch input:focus-visible + .track { outline: 3px solid var(--color-ring); outline-offset: 3px; }
/* v158: ردیفِ سوییچ با ساختار تازه (متنی/رهگیری با ~ به‌جای +) */
.switch-row input:checked ~ .track { background: var(--color-primary); }
.switch-row input:checked ~ .track::after { transform: translateX(-22px); }
.switch-row input:focus-visible ~ .track { outline: 3px solid var(--color-ring); outline-offset: 3px; }

/* ==========================================================================
   CARDS
   ========================================================================== */
.card {
  position: relative;
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(180%);
  backdrop-filter: blur(var(--glass-blur)) saturate(180%);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--e2), var(--e-inset-top);
  overflow: hidden;
  transition: box-shadow var(--dur-3) var(--ease-out), transform var(--dur-3) var(--ease-out), border-color var(--dur-3) var(--ease-out);
}
.card-pad { padding: var(--space-lg); }
.card-hover:hover { box-shadow: var(--e4); border-color: color-mix(in oklab, var(--color-primary) 30%, var(--glass-border)); }

.card-media {
  position: relative; aspect-ratio: 16 / 10; overflow: hidden;
  background: var(--color-muted);
}
.card-media img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform var(--dur-5) var(--ease-out);
}
.card-hover:hover .card-media img { transform: scale(1.06); }
.card-media::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 45%, rgba(4,20,16,.55) 100%);
}
.card-media .media-badges {
  position: absolute; top: 12px; inset-inline-start: 12px;
  display: flex; gap: 6px; flex-wrap: wrap; z-index: 2; max-width: calc(100% - 24px);
}
.card-body { padding: var(--space-lg); }
.card-title { font-size: var(--fs-lg); font-weight: 800; }
.card-title a:hover { color: var(--color-primary); }
.card-meta {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  font-size: var(--fs-xs); color: var(--color-muted-foreground);
  margin-top: 6px;
}
.card-meta svg { width: 14px; height: 14px; flex: none; }
/* a card-meta that is itself a link is a real tap target */
a.card-meta, .card-meta a {
  min-height: var(--tap);   /* v116-audit */ padding-block: 5px;
  min-width: 44px;          /* v118: short shop names measured 42px wide */
  display: inline-flex; align-items: center; gap: 6px;
}
.card-desc {
  margin-top: 10px; font-size: var(--fs-sm); color: var(--color-muted-foreground);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  line-clamp: 2; overflow: hidden;
}
.card-foot {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-sm);
  padding-top: var(--space-md); margin-top: var(--space-md);
  border-top: 1px solid var(--glass-hairline);
}

/* Stretched link keeps the whole card clickable without nesting <a> */
/* v113: the visible title link itself must clear the 24px floor (the ::after
   already makes the whole card tappable). */
a.stretch-link { display: inline-block; padding-block: 4px; }
.stretch-link::after {
  content: ''; position: absolute; inset: 0; z-index: 1;
}

/* ---------- Stat card ---------- */
.stat {
  padding: var(--space-lg);
  display: flex; align-items: center; gap: var(--space-md);
}
/* v78: کارت آمارِ لینک‌دار — هدف لمسی کامل، بدون زیرخط/رنگ اضافی */
a.stat-link {
  min-height: var(--tap);
  text-decoration: none; color: inherit; cursor: pointer;
  transition: transform var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out);
}
a.stat-link:hover { transform: translateY(-2px); box-shadow: var(--e3); }
a.stat-link:active { transform: translateY(0); }
.stat-icon {
  width: 52px; height: 52px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--radius-md);
  background: linear-gradient(160deg, color-mix(in oklab, var(--color-primary) 22%, transparent), color-mix(in oklab, var(--color-primary) 6%, transparent));
  color: var(--color-primary);
  box-shadow: var(--e-inset-top);
}
.stat-icon svg { width: 26px; height: 26px; }
.stat-value { font-size: var(--fs-2xl); font-weight: 800; line-height: 1.1; font-variant-numeric: tabular-nums; }
.stat-label { font-size: var(--fs-sm); color: var(--color-muted-foreground); margin-top: 2px; }

/* ==========================================================================
   HEADER / NAV
   ========================================================================== */
.site-header {
  position: sticky; top: 0; z-index: var(--z-header);
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur-lg)) saturate(190%);
  backdrop-filter: blur(var(--glass-blur-lg)) saturate(190%);
  border-bottom: 1px solid var(--glass-hairline);
  transition: box-shadow var(--dur-3) var(--ease-out), background-color var(--dur-3) var(--ease-out);
}
.site-header.is-stuck { box-shadow: var(--e3); background: var(--glass-bg-strong); }

.header-inner {
  height: var(--header-h);
  display: flex; align-items: center; gap: var(--space-md);
}

.brand { display: flex; align-items: center; gap: 10px; font-weight: 800; font-size: var(--fs-lg); flex: none; }
.brand { min-height: var(--tap); }   /* v116-audit: 40px brand link < 44px touch law */
.brand-mark {
  width: 40px; height: 40px; border-radius: 12px; flex: none;
  display: grid; place-items: center; overflow: hidden;
  background: #ffffff;
  border: 1px solid color-mix(in oklab, var(--brand-700) 18%, transparent);
  box-shadow: 0 4px 12px color-mix(in oklab, var(--brand-700) 20%, transparent);
  transition: transform var(--dur-3) var(--ease-spring);
}
.brand:hover .brand-mark { transform: rotate(-8deg) scale(1.06); }
.brand-mark svg { width: 38px; height: 38px; }
.brand-mark img { width: 38px; height: 38px; display: block; object-fit: contain; }  /* v178: لوگوی تأییدشده */
.brand-text small { display: block; font-size: 12px; font-weight: 500; color: var(--color-muted-foreground); line-height: 1.2; }

.main-nav { display: flex; align-items: center; gap: 2px; margin-inline-start: var(--space-md); }
.main-nav a {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--tap); min-width: var(--tap);
  padding: 9px 14px; border-radius: var(--radius-sm);
  font-size: var(--fs-sm); font-weight: 600;
  color: var(--color-muted-foreground);
  transition: color var(--dur-2) var(--ease-out), background-color var(--dur-2) var(--ease-out);
  white-space: nowrap;
}
.main-nav a:hover { color: var(--color-foreground); background: var(--color-muted); }
.main-nav a[aria-current="page"] { color: var(--color-primary-text); background: color-mix(in oklab, var(--color-primary) 12%, transparent); }

.header-actions {
  margin-inline-start: auto;
  display: flex; align-items: center; gap: 6px;
  flex: 0 1 auto; min-width: 0;
}
/* the nav must yield before the action buttons get pushed off-screen */
.main-nav { min-width: 0; overflow: hidden; }
.header-inner { min-width: 0; }

.nav-toggle { display: none; }
/* v106: on a phone the hamburger is comfortably tappable and crisp */
.nav-toggle {
  color: var(--color-foreground);
  background: var(--color-secondary);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.nav-toggle:hover { background: var(--color-muted); border-color: var(--color-border-strong); }
.nav-toggle:active { transform: scale(.94); }
.nav-toggle svg { width: 22px; height: 22px; }

/* Mobile drawer */
.mobile-nav {
  position: fixed; inset: 0; z-index: var(--z-modal);
  display: none;
}
.mobile-nav.is-open { display: block; }
.mobile-nav .backdrop {
  position: absolute; inset: 0;
  background: rgba(4, 16, 14, .5);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  animation: fadeIn var(--dur-3) var(--ease-out);
}
.mobile-nav .panel {
  position: absolute; inset-block: 0; inset-inline-end: 0;
  width: min(80vw, 320px);
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: blur(var(--glass-blur-lg)) saturate(190%);
  backdrop-filter: blur(var(--glass-blur-lg)) saturate(190%);
  border-inline-start: 1px solid var(--glass-border);
  box-shadow: var(--e4);
  padding: var(--space-lg);
  overflow-y: auto;
  animation: slideInEnd var(--dur-4) var(--ease-out);
  display: flex; flex-direction: column; gap: var(--space-xs);
}
.mobile-nav .panel a {
  display: flex; align-items: center; gap: 10px;
  padding: 13px 14px; border-radius: var(--radius-md);
  font-weight: 600; min-height: 48px;
  transition: background-color var(--dur-2) var(--ease-out);
}
.mobile-nav .panel a:hover { background: var(--color-muted); }
.mobile-nav .panel a[aria-current="page"] { background: color-mix(in oklab, var(--color-primary) 14%, transparent); color: var(--color-primary); }
.mobile-nav .panel a svg { width: 19px; height: 19px; flex: none; color: var(--color-muted-foreground); }
.mobile-nav .panel a[aria-current="page"] svg { color: var(--color-primary); }

@keyframes fadeIn { from { opacity: 0 } to { opacity: 1 } }
@keyframes slideInEnd { from { transform: translateX(-100%); opacity: .4 } to { transform: translateX(0); opacity: 1 } }
html[dir="rtl"] .mobile-nav .panel { animation-name: slideInEndRtl; }
@keyframes slideInEndRtl { from { transform: translateX(-100%); opacity: .4 } to { transform: translateX(0); opacity: 1 } }

/* Collapse the top nav into the hamburger before it can push the header
   actions off-screen.

   Measured, not guessed — see tools/navfit.py, which prints these numbers.

   The nav is now 11 links (مقایسهٔ قیمت added) needing 908px, plus brand 103
   and actions 363 and two 16px gaps = 1406px of content. The .container-wide
   caps at 1440px but its own padding leaves only ~1440 usable, so 1440 itself
   still overflowed by 9px while 1441+ was fine. The switch to the hamburger
   therefore has to include 1440, not stop just below it.

   Two labels were shortened (نقشهٔ شهر → نقشه, محصولات و خدمات → محصولات) to
   buy back 87px rather than hide a whole section. Re-run tools/navfit.py
   before adding a twelfth link — each costs roughly 80px. */
@media (max-width: 1440px) {
  .main-nav { display: none; }
  .nav-toggle { display: inline-grid; }
}

/* v76: twelve public destinations plus the city/account/submit actions need
   more than the 1440px header container if every label keeps roomy card
   padding. Keep the full desktop navigation instead of clipping its first or
   last link: the brand tagline is already repeated in the page hero, and a
   compact 12px nav still has a 40px pointer target. navfit.py verifies the
   resulting scrollWidth at 1500–1920px. */
@media (min-width: 1441px) {
  .site-header .brand-text small { display: none; }
  .site-header .main-nav { margin-inline-start: 0; gap: 0; }
  .site-header .main-nav a { padding-inline: 8px; font-size: 12px; }
}

/* ==========================================================================
   FOOTER
   ========================================================================== */
.site-footer {
  position: relative; z-index: var(--z-content);
  margin-top: var(--space-4xl);
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(180%);
  backdrop-filter: blur(var(--glass-blur)) saturate(180%);
  border-top: 1px solid var(--glass-hairline);
  padding-top: var(--space-3xl);
}
.footer-grid {
  display: grid; gap: var(--space-2xl);
  grid-template-columns: 1.6fr repeat(3, 1fr);
  padding-bottom: var(--space-2xl);
}
@media (max-width: 900px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .footer-grid { grid-template-columns: 1fr; } }
.footer-col h3 { font-size: var(--fs-sm); font-weight: 800; margin-bottom: var(--space-md); letter-spacing: .01em; }
.footer-col li + li { margin-top: 2px; }
.footer-col li { display: flex; }
.footer-col a, .footer-col li > span {
  font-size: var(--fs-sm); color: var(--color-muted-foreground);
  transition: color var(--dur-2) var(--ease-out);
  display: inline-flex; align-items: center;
  min-height: var(--tap); min-width: var(--tap); padding-block: 6px;
}
.footer-col a:hover { color: var(--color-primary); }
.footer-about p { font-size: var(--fs-sm); color: var(--color-muted-foreground); margin-top: var(--space-md); max-width: 42ch; }
.footer-bottom {
  border-top: 1px solid var(--glass-hairline);
  padding-block: var(--space-lg);
  display: flex; flex-wrap: wrap; gap: var(--space-md);
  align-items: center; justify-content: space-between;
  font-size: var(--fs-xs); color: var(--color-muted-foreground);
}
.tehran-clock {
  direction: rtl; unicode-bidi: isolate; white-space: nowrap;
  padding: 5px 10px; border: 1px solid var(--glass-hairline);
  border-radius: 999px; background: var(--glass-bg);
  color: var(--color-foreground); font-variant-numeric: tabular-nums;
}
.social-row { display: flex; gap: 8px; }
.social-row a {
  width: var(--tap); height: var(--tap); border-radius: var(--radius-sm);
  display: grid; place-items: center;
  background: var(--color-muted); color: var(--color-muted-foreground);
  transition: all var(--dur-2) var(--ease-out);
}
.social-row a:hover { background: var(--color-primary); color: var(--color-on-primary); transform: translateY(-3px); }
.social-row svg { width: 19px; height: 19px; }

/* ==========================================================================
   BREADCRUMB / PAGE HERO
   ========================================================================== */
.breadcrumb {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  font-size: var(--fs-xs); color: var(--color-muted-foreground);
  padding-block: var(--space-lg);
}
.breadcrumb a {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--tap); min-width: 32px; padding-inline: 4px;   /* v116-audit: 44px touch law */
  border-radius: var(--radius-xs);
}
.breadcrumb a:hover { color: var(--color-primary); }
.breadcrumb svg { width: 13px; height: 13px; opacity: .55; }
.breadcrumb [aria-current="page"] { color: var(--color-foreground); font-weight: 600; }

.page-hero {
  position: relative; z-index: var(--z-content);
  padding-block: var(--space-2xl) var(--space-xl);
}
.page-hero h1 { font-size: var(--fs-3xl); }
.page-hero p { margin-top: var(--space-sm); color: var(--color-muted-foreground); font-size: var(--fs-lg); max-width: 70ch; }

/* The notification title and its only page action belong to one compact row.
   Previously h1 was a block followed by an inline form, which pushed the
   action under the title and made this tiny header 119px tall on a phone. */
.notifications-hero {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: nowrap; gap: var(--space-sm);
  /* Asymmetric rhythm deliberately raises the compact title row a little. */
  padding-block: var(--space-sm) var(--space-md);
}
.notifications-hero h1 {
  display: flex; align-items: center; gap: var(--space-sm);
  min-width: 0; white-space: nowrap;
}
.notifications-hero form { flex: none; }

/* ==========================================================================
   TABLES (admin/panel)
   ========================================================================== */
.table-wrap {
  overflow-x: auto; border-radius: var(--radius-lg);
  border: 1px solid var(--glass-border);
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur)); backdrop-filter: blur(var(--glass-blur));
  box-shadow: var(--e2);
  -webkit-overflow-scrolling: touch;
}
.table { min-width: 620px; font-size: var(--fs-sm); }
.table th, .table td { padding: 14px 16px; text-align: start; vertical-align: middle; }
.table thead th {
  font-weight: 800; font-size: var(--fs-xs);
  color: var(--color-muted-foreground);
  background: color-mix(in oklab, var(--color-muted) 60%, transparent);
  border-bottom: 1px solid var(--color-border);
  position: sticky; top: 0; z-index: 1;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  white-space: nowrap;
}
.table tbody tr { border-bottom: 1px solid var(--glass-hairline); transition: background-color var(--dur-2) var(--ease-out); }
.table tbody tr:last-child { border-bottom: 0; }
.table tbody tr:hover { background: color-mix(in oklab, var(--color-primary) 5%, transparent); }
.table .num { font-variant-numeric: tabular-nums; }
.table .actions { display: flex; gap: 4px; }

/* ==========================================================================
   TABS / ACCORDION / ALERTS
   ========================================================================== */
.tabs { display: flex; gap: 4px; padding: 5px; border-radius: var(--radius-md); background: var(--color-muted); overflow-x: auto; }
.tabs button {
  padding: 10px 18px; border-radius: var(--radius-sm);
  font-size: var(--fs-sm); font-weight: 700; white-space: nowrap;
  color: var(--color-muted-foreground); cursor: pointer; min-height: var(--tap);
  transition: all var(--dur-2) var(--ease-out);
}
.tabs button:hover { color: var(--color-foreground); }
.tabs button[aria-selected="true"] {
  background: var(--color-card); color: var(--color-primary);
  box-shadow: var(--e1);
}
.tab-panel[hidden] { display: none; }

.accordion-item { border-bottom: 1px solid var(--glass-hairline); }
.accordion-trigger {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: var(--space-md);
  padding: var(--space-md) 0; text-align: start;
  font-weight: 700; font-size: var(--fs-base); cursor: pointer; min-height: 56px;
  transition: color var(--dur-2) var(--ease-out);
}
.accordion-trigger:hover { color: var(--color-primary); }
.accordion-trigger svg { width: 20px; height: 20px; flex: none; transition: transform var(--dur-3) var(--ease-out); color: var(--color-muted-foreground); }
.accordion-trigger[aria-expanded="true"] svg { transform: rotate(180deg); color: var(--color-primary); }
.accordion-panel { padding-bottom: var(--space-lg); color: var(--color-muted-foreground); font-size: var(--fs-sm); }
.accordion-panel[hidden] { display: none; }

.alert {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 14px 16px; border-radius: var(--radius-md);
  border: 1px solid; font-size: var(--fs-sm);
}
.alert svg { width: 20px; height: 20px; flex: none; margin-top: 1px; }
.alert-info    { background: color-mix(in oklab, var(--color-info-text) 10%, transparent); border-color: color-mix(in oklab, var(--color-info-text) 28%, transparent); color: var(--color-info-text); }
.alert-success { background: color-mix(in oklab, var(--color-success) 11%, transparent); border-color: color-mix(in oklab, var(--color-success) 30%, transparent); color: var(--color-success-text); }
.alert-warn    { background: color-mix(in oklab, var(--color-warning) 12%, transparent); border-color: color-mix(in oklab, var(--color-warning) 30%, transparent); color: var(--color-warning-text); }
.alert-error   { background: color-mix(in oklab, var(--color-destructive) 10%, transparent); border-color: color-mix(in oklab, var(--color-destructive) 28%, transparent); color: var(--color-danger-text); }
/* v111: per-theme alert overrides removed — tokens carry both modes. */

/* ==========================================================================
   EMPTY / LOADING STATES
   ========================================================================== */
.empty-state { text-align: center; padding: var(--space-4xl) var(--space-lg); }
.empty-state .icon-wrap {
  width: 88px; height: 88px; margin: 0 auto var(--space-lg);
  border-radius: 50%; display: grid; place-items: center;
  background: var(--color-muted); color: var(--color-muted-foreground);
}
.empty-state .icon-wrap svg { width: 40px; height: 40px; }
.empty-state h3 { font-size: var(--fs-xl); }
.empty-state p { margin-top: var(--space-sm); color: var(--color-muted-foreground); max-width: 44ch; margin-inline: auto; }

.skeleton {
  background: linear-gradient(90deg, var(--color-muted) 25%, color-mix(in oklab, var(--color-muted) 55%, var(--color-card)) 50%, var(--color-muted) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.4s linear infinite;
  border-radius: var(--radius-sm);
}
@keyframes shimmer { from { background-position: 200% 0 } to { background-position: -200% 0 } }
@media (prefers-reduced-motion: reduce) { .skeleton { animation: none; } }

.spinner {
  width: 20px; height: 20px; flex: none;
  border: 2.5px solid color-mix(in oklab, currentColor 25%, transparent);
  border-top-color: currentColor; border-radius: 50%;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg) } }

/* ==========================================================================
   MODAL / TOAST
   ========================================================================== */
.modal-backdrop {
  position: fixed; inset: 0; z-index: var(--z-modal);
  display: grid; place-items: center; padding: var(--space-lg);
  background: rgba(4, 16, 14, .55);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  animation: fadeIn var(--dur-3) var(--ease-out);
}
.modal-backdrop[hidden] { display: none; }
.modal {
  width: min(100%, 540px); max-height: 86dvh; overflow-y: auto;
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: blur(var(--glass-blur-lg)) saturate(190%);
  backdrop-filter: blur(var(--glass-blur-lg)) saturate(190%);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-xl);
  box-shadow: var(--e4);
  padding: var(--space-xl);
  animation: modalIn var(--dur-4) var(--ease-spring);
}
@keyframes modalIn {
  from { opacity: 0; transform: translateY(24px) scale(.94) rotateX(-6deg); }
  to   { opacity: 1; transform: translateY(0) scale(1) rotateX(0); }
}
@media (prefers-reduced-motion: reduce) { .modal, .modal-backdrop { animation: none; } }

.toast-stack {
  position: fixed; z-index: var(--z-toast);
  bottom: var(--space-lg); inset-inline-start: var(--space-lg);
  display: flex; flex-direction: column; gap: 10px;
  pointer-events: none;
}
.toast {
  display: flex; align-items: center; gap: 10px;
  padding: 13px 18px; border-radius: var(--radius-md);
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: blur(18px) saturate(190%); backdrop-filter: blur(18px) saturate(190%);
  border: 1px solid var(--glass-border);
  box-shadow: var(--e4);
  font-size: var(--fs-sm); font-weight: 600;
  pointer-events: auto;
  animation: toastIn var(--dur-4) var(--ease-spring);
  max-width: min(92vw, 400px);
}
.toast svg { width: 19px; height: 19px; flex: none; }
.toast.ok  svg { color: var(--color-success); }
.toast.err svg { color: var(--color-destructive); }
@keyframes toastIn { from { opacity: 0; transform: translateY(16px) scale(.95) } to { opacity: 1; transform: none } }

/* ==========================================================================
   SCROLL REVEAL (no-JS safe: visible by default, JS opts in)
   ========================================================================== */
.js .reveal { opacity: 0; transform: translateY(22px); }
.js .reveal.is-in {
  opacity: 1; transform: none;
  transition: opacity var(--dur-5) var(--ease-out), transform var(--dur-5) var(--ease-out);
}
.js .reveal-3d { opacity: 0; transform: perspective(900px) rotateX(12deg) translateY(30px) scale(.97); }
.js .reveal-3d.is-in {
  opacity: 1; transform: perspective(900px) rotateX(0) translateY(0) scale(1);
  transition: opacity var(--dur-5) var(--ease-out), transform 780ms var(--ease-out);
}
@media (prefers-reduced-motion: reduce) {
  .js .reveal, .js .reveal-3d { opacity: 1 !important; transform: none !important; transition: none !important; }
}

/* ==========================================================================
   UTILITIES
   ========================================================================== */
.text-center { text-align: center; }
.text-muted  { color: var(--color-muted-foreground); }
.text-sm     { font-size: var(--fs-sm); }
/* v330-stage8: utility links can be standalone actions (panel “همه ←”). */
a.text-sm { min-width: var(--tap); min-height: var(--tap); display: inline-flex; align-items: center; }
.text-xs     { font-size: var(--fs-xs); }
.fw-700 { font-weight: 700; } .fw-800 { font-weight: 800; }
.nums { font-variant-numeric: tabular-nums; }
/* Phone digits must keep their dial order inside RTL prose/cards. */
.phone-value, [dir="ltr"].nums { direction: ltr; unicode-bidi: isolate; text-align: left; }
.mt-0{margin-top:0}.mt-sm{margin-top:var(--space-sm)}.mt-md{margin-top:var(--space-md)}
.mt-lg{margin-top:var(--space-lg)}.mt-xl{margin-top:var(--space-xl)}.mt-2xl{margin-top:var(--space-2xl)}
.mb-lg{margin-bottom:var(--space-lg)}.mb-xl{margin-bottom:var(--space-xl)}
.w-full { width: 100%; }
.hide { display: none !important; }
@media (max-width: 768px) { .hide-mobile { display: none !important; } }
@media (min-width: 769px) { .hide-desktop { display: none !important; } }

/* Divider */
.divider { height: 1px; background: var(--glass-hairline); border: 0; margin-block: var(--space-lg); }

/* Print */
@media print {
  .site-header, .site-footer, .spatial-bg, .spatial-grain, canvas { display: none !important; }
  body { background: #fff; color: #000; }
}

/* ======================================================================
   MOBILE LAYER  ·  everything below 1024px
   ----------------------------------------------------------------------
   Written after measuring the real thing on a 360px Galaxy A:
     · 70 of 76 controls on /catalog were smaller than 44px
     · the smallest rendered text was 10px
     · the home hero was 1496px tall — two screens before any content
     · "تماس" on a shop page sat at y=834, below the fold

   The rules are grouped by the problem they solve, not by component, so a
   new component inherits the fix instead of having to remember it.
   ====================================================================== */
@media (max-width: 1024px) {

  /* ---- 1. TOUCH TARGETS -------------------------------------------
     Apple asks 44pt, Material 48dp. Rather than resize every component,
     give the tappable primitives a floor. `min-height` alone is not
     enough for icon buttons, which also need width. */
  .btn,
  .btn-sm,
  .btn-icon,
  .chip,
  .sub-pill,
  .panel-nav a,
  .mobile-nav .panel a,
  .todo-item,
  .map-item,
  .tab,
  .pager a,
  select, .select,
  input:not([type="checkbox"]):not([type="radio"]),
  textarea {
    min-height: var(--tap);
  }
  .btn-icon,
  .fav-btn,
  .nav-toggle,
  .icon-btn {
    min-width: var(--tap);
    min-height: var(--tap);
    width: auto;
  }
  /* v118: .btn-sm had a 44px height floor but no width floor — short labels
     like «ویرایش» rendered 28-30px wide, too thin for a thumb. Width floor
     (not width:auto) so text buttons keep their natural width when larger. */
  .btn-sm { min-width: var(--tap); }
  /* v118: plain links inside panel tables (insights/qa rows) measured 42px
     wide — a hair under the floor. */
  .table a { min-width: 44px; display: inline-flex; align-items: center; min-height: 44px; }
  /* the heart on a card was 40px drawn but 38x35 measured */
  .fav-btn { width: var(--tap); height: var(--tap); }

  /* Links inside prose stay visually inline but get a bigger hit area,
     which is the WCAG-sanctioned way to do it without wrecking layout. */
  .card-body a:not(.btn),
  .review a:not(.btn),
  p a:not(.btn) { padding-block: 4px; }

  /* 8px minimum between adjacent targets — the second half of the
     touch-target rule, and the one everybody forgets */
  .cluster { gap: 10px; }
  .card-foot { gap: 10px; }

  /* ---- 2. LEGIBILITY -----------------------------------------------
     Nothing rendered may sit under 12px. These selectors are the ones the
     audit actually caught at 10-11px. */
  .brand-text small,
  .chip-n, .card-meta, .text-xs,
  .item-flag, .badge, .lock-chip,
  .account-text small,
  .pbar-row, .hero-mini .s,
  .today-tag, .dgcmp-flag,
  .event-date .m,
  .unlock-src, .hag-who, .hag-mini {
    font-size: var(--fs-xs) !important;   /* 12px floor */
  }
  /* badges get room to breathe once the text is bigger */
  .badge { padding: 5px 10px; line-height: 1.45; }

  /* Persian needs more leading than Latin at the same size — the
     ascenders and descenders in Vazirmatn are taller. */
  body { line-height: 1.75; }
  .card-desc, .review-body, p { line-height: 1.8; }

  /* ---- 3. BREATHING ROOM -------------------------------------------
     16px is the minimum comfortable side padding on a phone; the desktop
     24px wasted 13% of a 360px screen. */
  .container,
  .container-wide {
    width: min(100% - 32px, var(--container-wide));
  }

  /* ---- 4. ONE COLUMN, ALWAYS ---------------------------------------
     Two-column grids at 360px produce 150px cards nobody can read. */
  /* Was a flat 1fr for everything below 1024px, which is why a phone showed one
     card per screen and the front page ran to nineteen scrolls. The owner asked
     for the roomier desktop feel without shrinking the text, so the columns are
     driven by the space actually available instead of by a single breakpoint:
     two up as soon as two fit legibly, one up on a narrow phone. Card text
     keeps its full size either way — nothing is scaled down. */
  .grid-2 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); }
  .grid-3 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr)); }
  .grid-4 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 165px), 1fr)); gap: 10px; }
  /* stat cards are the exception: they are short and read fine in pairs */
  .grid-4:has(.stat) { grid-template-columns: 1fr 1fr; }

  .site-footer { margin-bottom: 0; }
}

/* ---- ROOM FOR THE FIXED BOTTOM CHROME ------------------------------
   Anything fixed at the bottom must be paid for in body padding, or it
   covers the last row of every list. This has to match the breakpoint the
   bottom bar itself uses (1440px, not 1024px) — while it sat at 860 the bar
   was visible at 980px in Chrome's desktop mode but nothing reserved space
   for it, so it sat on top of the footer and the last card of every list. */
@media (max-width: 768px) {
  body {
    padding-bottom: calc(var(--botnav-h) + env(safe-area-inset-bottom));
  }
  body.has-callbar {
    padding-bottom: calc(var(--botnav-h) + var(--callbar-h)
                         + env(safe-area-inset-bottom));
  }
}

/* Small phones: the 360px Galaxy A and everything narrower. */
@media (max-width: 400px) {
  .container, .container-wide { width: min(100% - 24px, var(--container-wide)); }
  .btn-lg { font-size: var(--fs-base); padding: 12px 18px; }
  /* v106: never let the header row overflow and shove the hamburger off the
     edge. Let the brand yield (shrink + ellipsis) while the action buttons
     keep their 44px, so the menu button always stays fully on screen. */
  .site-header .brand { flex: 0 1 auto; min-width: 0; }
  .site-header .brand-text { max-width: 40vw; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
}

/* ======================================================================
   TOUCH DEVICES  ·  kill the mouse-only 3D
   The .tilt cards apply a perspective transform. On a phone that has two
   costs: the hover effect can never fire (there is no pointer), and the
   perspective visually SHRINKS children — the 44x44 heart button measured
   42x39 on screen, silently undoing the touch-target fix.

   `hover: none` targets real touch devices rather than guessing by width,
   so a small laptop window keeps the effect.
   ====================================================================== */
@media (hover: none) and (pointer: coarse) {
  .tilt,
  .reveal-3d,
  .card-hover { transform: none !important; perspective: none !important; }
  .tilt .layer-1,
  .tilt .layer-2,
  .tilt .layer-3 { transform: none !important; }
  .sheen { display: none; }          /* a hover shine nobody can trigger */
}

/* The last stragglers the audit caught under 12px. These are counters and
   micro-labels that had hard-coded pixel sizes of their own. */
@media (max-width: 1024px) {
  .fav-dot,
  .brand-text small,
  .account-text small,
  /* `.nums` is a numeral-rendering helper, not a size — it is also on the
     phone INPUTS. Forcing 12px here made iOS zoom the whole page the
     moment a shopkeeper tapped the login field, so form controls are
     excluded and keep the 16px that prevents that zoom. */
  .nums:not(input):not(textarea):not(select),
  .chip-n,
  .item-more,
  .media-badges .badge,
  .mobile-nav .panel a.nav-cta small { font-size: var(--fs-xs) !important; }

  /* a card title is a link and a primary target — give it real height */
  .card-title a.stretch-link { display: inline-block; padding-block: 6px; }
}

/* ======================================================================
   REMAINING TOUCH TARGETS
   Found by tools/mobile_audit.py after the first pass: the hamburger
   drawer, breadcrumbs, footer columns and pagination were all built as
   plain text links and measured 22-40px tall.
   ====================================================================== */
@media (max-width: 1024px) {
  /* the slide-out drawer: its links were 40px, just under the bar */
  .mobile-nav .panel a,
  .mobile-nav .panel button {
    min-height: var(--tap-lg);
    padding-block: 12px;
    font-size: var(--fs-base);
  }

  /* breadcrumbs measured 32x32 and sit right under the sticky header,
     which is the hardest area of the screen to hit accurately */
  .breadcrumb a,
  .breadcrumb span { padding-block: 10px; display: inline-block; }
  .breadcrumb { gap: 4px; font-size: var(--fs-sm); }

  /* footer link columns: 22px text links stacked 8px apart */
  .site-footer a {
    display: inline-block;
    min-height: var(--tap);
    padding-block: 11px;
  }
  .footer-col { gap: 0; }

  /* pagination and "show all categories" style toggles */
  .chips-more,
  .pager a, .pager span { min-height: var(--tap); padding-inline: 16px; }

  /* checkbox and radio rows — the input itself was 24x24 */
  .check input[type="checkbox"],
  .check input[type="radio"] { width: 22px; height: 22px; }
  .check { min-height: var(--tap); padding-block: 6px; gap: 10px; }

  /* inline text links that act as buttons (e.g. "کسب‌وکارتان را ثبت کنید") */
  .alert a, .field-hint a, .text-sm a { padding-block: 8px; display: inline-block; }
  a.text-sm { min-width: var(--tap); min-height: var(--tap); display: inline-flex; align-items: center; }
}

/* The bottom-nav labels are intentionally 11px: they sit directly under a
   22px icon that carries the meaning, the whole 72x60 cell is the target,
   and 12px labels wrap to two lines on a 360px screen. This is the one
   documented exception to the 12px floor. */
@media (max-width: 1024px) {
  .bottom-nav a span { font-size: 12px !important; }
}

/* Width, not just height. These last few measured 40px WIDE (footer
   columns are narrow, so a short link like "نقشه" or "۰۳۱" never reaches
   44px across) and 32px for the breadcrumb "خانه". */
@media (max-width: 1024px) {
  .site-footer a { min-width: var(--tap); }
  .breadcrumb a { min-width: 44px; text-align: center; }
  /* the brand lockup is one tall target, which is fine — but make it wide
     enough that a thumb landing slightly off still hits it */
  .brand { min-width: 120px; }
  /* map pins are drawn by Leaflet at 22px; enlarge the hit area without
     changing how the pin looks */
  .leaflet-marker-icon { position: relative; }
  .leaflet-marker-icon::after {
    content: ''; position: absolute; inset: -11px;
  }
  /* the search-toolbar checkbox */
  .dir-toolbar input[type="checkbox"] { width: 22px; height: 22px; }
}

/* Final pass — each of these was named by tools/mobile_audit.py. */
@media (max-width: 1024px) {
  /* the shop-name link under every catalogue card (30 of them on /catalog) */
  a.card-meta { min-height: var(--tap); padding-block: 6px; }

  /* Leaflet's own controls and our map pins. The zoom +/- buttons are kept
     small (v51) — a map control should not rival the «موقعیت من» button in
     size; the hit area stays tap-friendly without the giant graphic. */
  /* v113: the single formal zoom rule below (44px hit / 28px look) applies at
     every width; no per-breakpoint override. */
  .bz-pin { position: relative; }
  .bz-pin::after { content: ''; position: absolute; inset: -11px; border-radius: 50%; }

  /* the floating support button */
  .sup-fab { min-width: var(--tap-lg); min-height: var(--tap-lg); }

  /* inline links inside form hints and cards ("قوانین", "فرم ثبت کسب‌وکار").
     Flex tile/row anchors (.quick-tile, .todo-item, .owner-perk) are excluded —
     forcing them to inline-block flattened their column/row layout and made
     their title + subtitle text overlap. */
  .card a:not(.btn):not(.card-title a):not(.quick-tile):not(.todo-item):not(.owner-perk),
  .field-hint a,
  .check a { min-height: var(--tap); padding-block: 11px; display: inline-block; }
}

/* The last few, each named by tools/mobile_audit.py. */
@media (max-width: 1024px) {
  /* blog/news card titles are links but had no vertical padding */
  .card-title a { display: inline-block; padding-block: 8px; }

  /* checkboxes: the visible box is 22px by design, so grow the hit area
     around it rather than drawing a giant square */
  .check input[type="checkbox"],
  .check input[type="radio"] { position: relative; }
  .check input[type="checkbox"]::after,
  .check input[type="radio"]::after {
    content: ''; position: absolute; inset: -11px;
  }

  /* short links inside prose and form footers ("قوانین", "اول وارد شوید",
     "فرم ثبت کسب‌وکار") — narrow words never reach 44px across */
  .auth-foot a,
  .alert a,
  p a:not(.btn),
  .check a { min-width: var(--tap); text-align: center; }

  /* the shop-name chip under a catalogue card is narrow (42px) because the
     name is short; give it side padding instead of stretching the row */
  a.card-meta { min-width: var(--tap); padding-inline: 8px; }
}

/* Checkboxes are replaced elements — ::after does not render on them, so
   the earlier attempt to grow their hit area silently did nothing. Give
   the box real size and scale the tick back down instead. */
@media (max-width: 1024px) {
  input[type="checkbox"],
  input[type="radio"] {
    width: 26px; height: 26px;
    min-width: 26px; min-height: 26px;
    /* the LABEL is the real target: .check already gets min-height:44px,
       and clicking the label toggles the box */
  }
  /* any link that stands alone as a call to action, wherever it lives */
  a[href="/submit"], a[href="/login"],
  .auth-foot a, .blog-list a, .post-list a { min-height: var(--tap); }
  /* blog links live inside headings without their own class */
  h3 > a, h4 > a { display: inline-block; padding-block: 4px; }
}

/* Last four. The blog links sit inside .card-title but the earlier rule
   used `.card-title a`, which loses to a later `a { }` reset; and the
   remaining checkbox is the bare one in the submit form's terms row. */
@media (max-width: 1024px) {
  .card-title > a,
  .news-card a,
  article a[href^="/blog/"] {
    display: inline-block;
    min-height: var(--tap);
    padding-block: 10px;
  }
  /* the filter checkbox on /businesses has no .check wrapper.
     v176: the 28px native box failed the ≥44px touch standard on phones.
     The control is now a 44×44 hit area; the visible box stays 28px and is
     drawn with ::before, the checkmark with ::after — same look, bigger tap. */
  input[type="checkbox"][data-dir-open],
  .dir-toolbar input[type="checkbox"],
  form input[type="checkbox"]:not(.check input) {
    appearance: none; -webkit-appearance: none;
    width: 44px; height: 44px; margin: 0; flex: none;
    background: transparent; border: none; position: relative; cursor: pointer;
  }
  input[type="checkbox"][data-dir-open]::before,
  .dir-toolbar input[type="checkbox"]::before,
  form input[type="checkbox"]:not(.check input)::before {
    content: ""; position: absolute; inset: 8px;
    border: 1.5px solid color-mix(in oklab, var(--color-foreground) 35%, transparent);
    border-radius: 8px; background: var(--color-card);
    transition: background var(--dur-2) var(--ease-out), border-color var(--dur-2) var(--ease-out);
  }
  input[type="checkbox"][data-dir-open]:checked::before,
  .dir-toolbar input[type="checkbox"]:checked::before,
  form input[type="checkbox"]:not(.check input):checked::before {
    background: var(--color-primary); border-color: var(--color-primary);
  }
  input[type="checkbox"][data-dir-open]::after,
  .dir-toolbar input[type="checkbox"]::after,
  form input[type="checkbox"]:not(.check input)::after {
    content: ""; position: absolute; top: 12px; left: 18px;
    width: 8px; height: 14px; border: solid var(--color-on-primary, #fff);
    border-width: 0 2.5px 2.5px 0; transform: rotate(45deg); opacity: 0;
  }
  input[type="checkbox"][data-dir-open]:checked::after,
  .dir-toolbar input[type="checkbox"]:checked::after,
  form input[type="checkbox"]:not(.check input):checked::after { opacity: 1; }
  label:has(> input[type="checkbox"]),
  label:has(> input[type="radio"]) { min-height: var(--tap); display: inline-flex;
                                     align-items: center; gap: 10px; }
}

/* The auth footer link ("فرم ثبت کسب‌وکار") sits inline inside a sentence,
   so it inherits the paragraph's line box and measured 32px tall. */
@media (max-width: 1024px) {
  .auth-foot { line-height: 2.2; }
  .auth-foot a { display: inline-block; min-height: var(--tap); padding-block: 11px; }
}

/* ----------------------------------------------------------------------
   GRID ITEMS MUST BE ALLOWED TO SHRINK
   A grid/flex item defaults to `min-width: auto`, which refuses to go
   narrower than its content's intrinsic width. Any long unbroken Persian
   name, or a child with its own max-width, then pushes the track wider
   than the screen — this produced the -35px hero and the 883px cards in a
   1024px viewport. Setting the floor to 0 once, here, stops the whole
   class of bug instead of chasing each component.
   ---------------------------------------------------------------------- */
.grid > *,
.grid-2 > *, .grid-3 > *, .grid-4 > *,
.cat-grid > *, .item-grid > *, .price-grid > *,
.cluster > * { min-width: 0; }

/* and long words (URLs, unbroken names) wrap instead of pushing */
.card-title, .card-desc, .item-price, .hero-lead, .pbar-name { overflow-wrap: anywhere; }

/* ----------------------------------------------------------------------
   THE 3D REVEAL MUST NOT WIDEN THE PAGE
   `.reveal-3d` animates in with perspective(900px) rotateX(12deg). A
   rotated element's PAINTED box is wider than its layout box, so on a
   narrow viewport the card visually spilled past the edge and the browser
   reported real horizontal overflow (828px card measuring 883px at 1024px
   wide). Clipping the scroll container is the standard containment for a
   transform that is purely decorative.
   ---------------------------------------------------------------------- */
html, body { overflow-x: clip; }

/* Below the desktop breakpoint the tilt-in is not worth the risk at all:
   the screen is too narrow for a 12deg rotation to look like anything but
   a glitch, and it costs paint time on the cheap phones this must run on. */
@media (max-width: 1024px) {
  .js .reveal-3d {
    opacity: 0;
    transform: translateY(18px);        /* a plain fade-up, no perspective */
  }
  .js .reveal-3d.is-in { opacity: 1; transform: none; }
}

/* ========================================================================== 
   MESSENGER CHAT (v73) — customer ↔ shopkeeper ↔ transparent admin
   ========================================================================== */
/* ---- «گفت‌وگوها» hub: one parent panel, conversation types as sub-tabs ---- */
.conv-hub { margin-bottom: var(--space-md); }
.conv-hub-head {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-weight: 800; font-size: 15px; color: var(--color-foreground);
  margin-bottom: 10px;
}
.conv-hub-head svg { width: 20px; height: 20px; color: var(--color-primary); }
.conv-hub-head small {
  font-weight: 600; font-size: 12px; color: var(--color-muted-foreground);
  margin-inline-start: 2px;
}
.conv-tabs {
  display: flex; gap: 8px; flex-wrap: wrap; padding: 6px;
  border-radius: var(--radius-lg); background: var(--glass-bg);
  border: 1px solid var(--glass-border);
}
.conv-tab {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 44px; padding: 8px 8px; border-radius: 14px;
  font-size: 12.5px; font-weight: 700; text-decoration: none; text-align: center;
  color: var(--color-muted-foreground);
  transition: background var(--dur-2), color var(--dur-2);
  flex: 1 1 0; min-width: 0; white-space: nowrap;
}
.conv-tab svg { width: 18px; height: 18px; }
.conv-tab:hover {
  color: var(--color-foreground);
  background: color-mix(in oklab, var(--color-primary) 10%, transparent);
}
.conv-tab.is-on {
  color: var(--color-on-primary);
  background: linear-gradient(140deg, var(--color-primary-hover, var(--color-primary)), var(--color-primary));
  box-shadow: 0 4px 14px color-mix(in oklab, var(--color-primary) 30%, transparent);
}
.conv-tab.is-on svg { color: var(--color-on-primary); }
.conv-n {
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px;
  background: var(--accent-500); color: var(--color-on-primary);
  font-size: 12px; font-weight: 800; line-height: 18px; text-align: center;
}
.conv-tab.is-on .conv-n { background: rgba(0,0,0,.22); color: #fff; }
.chat-inbox-card,
.messenger {
  border: 1px solid color-mix(in oklab, var(--color-primary) 18%, var(--glass-border));
  background: linear-gradient(155deg,
      color-mix(in oklab, var(--color-card) 94%, var(--color-primary) 6%),
      color-mix(in oklab, var(--color-background) 94%, var(--color-muted) 6%));
  box-shadow: var(--e3), var(--e-inset-top);
}
.chat-inbox-card { border-radius: var(--radius-xl); padding: 8px; overflow: hidden; }
.thread-list { display: grid; gap: 4px; }
.thread-row {
  display: grid; grid-template-columns: 48px minmax(0, 1fr) auto;
  align-items: center; gap: 12px; min-height: 76px; padding: 10px 12px;
  border-radius: var(--radius-lg); border: 1px solid transparent;
  transition: background-color var(--dur-2), border-color var(--dur-2), transform var(--dur-2);
}
.thread-row:hover, .thread-row:focus-visible {
  background: color-mix(in oklab, var(--color-primary) 8%, transparent);
  border-color: color-mix(in oklab, var(--color-primary) 24%, transparent);
  transform: translateX(-2px);
}
.thread-row.is-unread { background: color-mix(in oklab, var(--color-primary) 10%, transparent); }
.thread-avatar, .messenger-avatar {
  display: grid; place-items: center; flex: none;
  color: var(--color-on-primary); font-weight: 900;
  background: linear-gradient(145deg, var(--color-primary-hover), var(--color-primary));
  border: 1px solid rgba(255,255,255,.25); box-shadow: 0 6px 18px rgba(200,154,62,.2);
}
.thread-avatar { width: 48px; height: 48px; border-radius: 17px; font-size: var(--fs-lg); }
.thread-main { min-width: 0; display: grid; gap: 3px; }
.thread-head, .thread-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-width: 0; }
.thread-head strong { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-sm); }
.thread-head time, .thread-foot small { flex: none; font-size: var(--fs-xs); color: var(--color-muted-foreground); }
.thread-preview { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--color-muted-foreground); font-size: var(--fs-sm); }
.thread-row.is-unread .thread-preview, .thread-row.is-unread .thread-head strong { color: var(--color-foreground); font-weight: 800; }
.thread-state { padding: 2px 7px; border-radius: 999px; }
.thread-state.is-open { color: var(--color-success); background: rgba(23,189,169,.14); }
.thread-state.is-closed { color: var(--color-danger-text); background: rgba(244,63,94,.11); }
.thread-unread {
  display: grid; place-items: center; min-width: 24px; height: 24px; padding-inline: 6px;
  border-radius: 999px; background: var(--color-primary); color: var(--color-on-primary);
  font-size: 12px; font-weight: 900;
}

.chat-page { max-width: 920px; }
.messenger {
  position: relative; display: flex; flex-direction: column;
  width: min(100%, 780px); height: min(740px, calc(100dvh - 150px)); min-height: 540px;
  margin-inline: auto; border-radius: 26px; overflow: hidden;
}
.messenger-head {
  position: relative; z-index: 3; display: flex; align-items: center; gap: 10px;
  min-height: 72px; padding: 10px 14px;
  border-bottom: 1px solid var(--glass-hairline);
  background: color-mix(in oklab, var(--color-card) 92%, transparent);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
}
.messenger-back, .composer-icon, .composer-send {
  display: inline-grid; place-items: center; flex: none; width: 44px; height: 44px;
  border: 0; border-radius: 14px; cursor: pointer;
}
.messenger-back, .composer-icon { color: var(--color-muted-foreground); background: color-mix(in oklab, var(--color-foreground) 7%, transparent); }
.messenger-back:hover, .composer-icon:hover { color: var(--color-primary); background: color-mix(in oklab, var(--color-primary) 13%, transparent); }
.messenger-back svg, .composer-icon svg, .composer-send svg { width: 20px; height: 20px; }
.messenger-avatar { width: 46px; height: 46px; border-radius: 16px; }
.messenger-person { min-width: 0; display: grid; flex: 1; }
.messenger-person strong, .messenger-person small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.messenger-person strong { font-size: var(--fs-base); }
.messenger-person small { color: var(--color-muted-foreground); font-size: var(--fs-xs); }
.messenger-state { flex: none; padding: 5px 9px; border-radius: 999px; font-size: var(--fs-xs); }
.messenger-state.is-open { color: var(--color-success); background: rgba(23,189,169,.14); }
.messenger-state.is-closed { color: var(--color-danger-text); background: rgba(244,63,94,.12); }

.chat-box {
  position: relative; flex: 1; min-height: 320px; overflow-y: auto;
  display: flex; flex-direction: column; gap: 10px; padding: 18px 18px 26px;
  direction: ltr;
  overscroll-behavior: contain; scroll-behavior: smooth;
  background:
    radial-gradient(circle at 15% 12%, rgba(52,211,153,.06), transparent 31%),
    linear-gradient(rgba(255,255,255,.012) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.012) 1px, transparent 1px);
  background-size: auto, 28px 28px, 28px 28px;
}
.msg { display: flex; flex-direction: column; max-width: min(82%, 560px); direction: rtl; }
.msg.me { align-self: flex-end; align-items: flex-end; }
.msg.them, .msg.admin { align-self: flex-start; align-items: flex-start; }
.msg-label { padding-inline: 8px; margin-bottom: 3px; color: var(--color-muted-foreground); font-size: 12px; }
.msg.admin .msg-label { color: var(--color-accent, var(--gold-400, var(--color-primary))); font-weight: 800; }
.msg-bubble {
  min-width: 52px; padding: 9px 12px; border-radius: 18px; line-height: 1.72;
  font-size: var(--fs-sm); overflow: hidden; overflow-wrap: anywhere;
  background: color-mix(in oklab, var(--color-muted) 86%, var(--color-card) 14%);
  color: var(--color-foreground); border: 1px solid var(--glass-hairline);
  border-start-end-radius: 5px; box-shadow: 0 5px 16px rgba(0,0,0,.12);
}
.msg.me .msg-bubble {
  color: var(--color-on-primary); font-weight: 560;
  background: linear-gradient(145deg,
    color-mix(in oklab, var(--color-primary) 82%, #fff),
    var(--color-primary));
  border-color: rgba(255,255,255,.28); border-start-start-radius: 5px;
  border-start-end-radius: 18px;
}
.msg.admin .msg-bubble {
  background: color-mix(in oklab, var(--gold-500, var(--color-primary)) 14%, var(--color-muted));
  border-color: color-mix(in oklab, var(--gold-500, var(--color-primary)) 36%, transparent);
  border-inline-start: 3px solid var(--gold-400, var(--color-primary));
}
.msg-text { white-space: pre-wrap; }
.msg-meta { display: flex; gap: 3px; direction: rtl; font-size: 12px; color: var(--color-muted-foreground); margin-top: 3px; padding-inline: 6px; }
.msg.me .msg-meta { color: color-mix(in oklab, var(--color-muted-foreground) 82%, var(--color-primary) 18%); }
.msg-ticks { font-size: 13px; line-height: 1; letter-spacing: -1px; color: var(--color-primary); }
.chat-date { align-self: center; margin: 6px 0 2px; }
.chat-date span {
  display: inline-block; padding: 3px 12px; border-radius: 999px; font-size: 12px;
  color: var(--color-muted-foreground);
  background: color-mix(in oklab, var(--color-foreground) 8%, transparent);
  border: 1px solid var(--glass-hairline);
}
.msg-image { display: block; color: inherit; }
.msg-text + .msg-image, .msg-text + .msg-file { margin-top: 8px; }
.msg-image img { display: block; width: min(100%, 320px); max-height: 280px; object-fit: cover; border-radius: 12px; }
.msg-image > span { display: flex; align-items: center; gap: 6px; margin-top: 6px; font-size: 12px; }
.msg-image svg { width: 15px; height: 15px; }
.msg-file {
  display: grid; grid-template-columns: 42px minmax(0,1fr) 20px; align-items: center; gap: 9px;
  min-width: min(280px, 66vw); padding: 9px; border-radius: 13px; color: inherit;
  background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.12);
}
.msg-file-icon { display: grid; place-items: center; width: 42px; height: 42px; border-radius: 12px; background: rgba(255,255,255,.13); }
.msg-file-icon svg { width: 21px; height: 21px; }
.msg-file > span:nth-child(2) { min-width: 0; display: grid; }
.msg-file strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }
.msg-file small { font-size: 12px; color: var(--color-muted-foreground); }
.msg-file > svg { width: 18px; height: 18px; }
.chat-empty { margin: auto; display: grid; justify-items: center; gap: 4px; text-align: center; color: var(--color-muted-foreground); }
.chat-empty > span { font-size: 32px; color: var(--color-primary); }
.chat-empty small { font-size: var(--fs-xs); }
.chat-new {
  position: absolute; z-index: 4; inset-inline-start: 50%; bottom: 104px;
  transform: translateX(50%); display: inline-flex; align-items: center; gap: 6px;
  min-height: var(--tap); padding: 7px 12px; border: 1px solid var(--glass-border);
  border-radius: 999px; color: var(--color-foreground); background: var(--color-card);
  box-shadow: var(--e3); cursor: pointer;
}
.chat-new[hidden] { display: none; }
.chat-new svg { width: 16px; height: 16px; }
.chat-closed-note { padding: 7px 14px; text-align: center; font-size: var(--fs-xs); color: var(--color-danger-text); background: rgba(244,63,94,.08); border-top: 1px solid rgba(244,63,94,.16); }

.chat-composer {
  position: relative; z-index: 3; padding: 9px 10px 8px;
  border-top: 1px solid var(--glass-hairline);
  background: color-mix(in oklab, var(--color-card) 94%, transparent);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
}
.composer-row { display: flex; align-items: flex-end; gap: 7px; }
.composer-input {
  flex: 1; min-width: 0; min-height: 44px; max-height: 120px; resize: none;
  padding: 10px 14px; border: 1px solid var(--color-border); border-radius: 16px;
  color: var(--color-foreground); background: color-mix(in oklab, var(--color-background) 74%, transparent);
  font: inherit; line-height: 1.55; outline: none;
}
.composer-input:focus { border-color: var(--color-primary); box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-primary) 13%, transparent); }
.composer-send { color: var(--color-on-primary); background: linear-gradient(145deg, var(--color-primary-hover), var(--color-primary)); box-shadow: 0 6px 17px rgba(200,154,62,.24); }
.composer-send:hover { filter: brightness(1.06); }
.composer-help { display: flex; justify-content: space-between; gap: 8px; margin-top: 5px; padding-inline: 51px 4px; color: var(--color-muted-foreground); font-size: 12px; }
.attach-preview {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin-bottom: 7px; padding: 7px 9px; border-radius: 12px;
  color: var(--color-foreground); background: color-mix(in oklab, var(--color-primary) 10%, transparent);
  border: 1px solid color-mix(in oklab, var(--color-primary) 24%, transparent);
}
.attach-preview[hidden] { display: none; }
.attach-preview > span { display: flex; align-items: center; gap: 7px; min-width: 0; }
.attach-preview > span > span { max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }
.attach-preview small { flex: none; color: var(--color-muted-foreground); font-size: 12px; }
.attach-preview svg { width: 17px; height: 17px; }
.attach-preview button { display: grid; place-items: center; width: 36px; height: 36px; border: 0; border-radius: 10px; color: var(--color-danger-text); background: rgba(244,63,94,.09); cursor: pointer; }
.chat-admin-context {
  display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap;
  padding: 14px 16px; border-radius: var(--radius-xl);
  background: color-mix(in oklab, var(--gold-400, var(--color-primary)) 8%, var(--glass-bg));
  border: 1px solid color-mix(in oklab, var(--gold-400, var(--color-primary)) 25%, var(--glass-border));
}
.chat-admin-context h2 { margin-top: 6px; font-size: var(--fs-xl); }
.chat-admin-context p { color: var(--color-muted-foreground); font-size: var(--fs-sm); }

@media (max-width: 768px) {
  .chat-inbox-page .page-hero { padding-bottom: 8px !important; }
  .chat-inbox-card { margin-inline: -2px; padding: 4px; border-radius: 18px; }
  .thread-row { grid-template-columns: 44px minmax(0,1fr) auto; min-height: 72px; padding: 8px; gap: 9px; }
  .thread-avatar { width: 44px; height: 44px; border-radius: 15px; }
  .thread-preview { font-size: 12px; }
  .chat-page { width: 100% !important; }
  .chat-page > .breadcrumb { padding-inline: 12px; }
  .messenger {
    width: 100%; height: calc(100dvh - var(--header-h) - var(--botnav-h) - 96px);
    min-height: 420px; border-radius: 20px 20px 0 0;
  }
  /* A fixed helper over a fixed composer makes the send controls untappable.
     Help remains available in navigation; the focused room gets a clear floor. */
  body:has(.messenger) .sup-fab { display: none !important; }
  .messenger-head { min-height: 66px; padding: 8px; gap: 7px; }
  .messenger-avatar { width: 42px; height: 42px; border-radius: 14px; }
  .messenger-state { max-width: 80px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .chat-box { min-height: 300px; padding: 14px 10px 22px; }
  .msg { max-width: 88%; }
  .msg-bubble { padding: 8px 10px; }
  .msg-file { min-width: min(250px, 72vw); }
  .composer-help span:first-child { display: none; }
  .composer-help { justify-content: flex-end; padding-inline-start: 0; }
}

/* ==========================================================================
   SKELETON LOADING  (v28) — instant, professional feel while cards fill
   ========================================================================== */
.sk { position: relative; overflow: hidden; background: var(--color-muted);
      border-radius: var(--radius-md); }
.sk::after { content: ''; position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 30%,
      color-mix(in oklab, var(--color-background) 55%, transparent) 50%, transparent 70%);
  animation: skShine 1.4s var(--ease-out) infinite; }
@keyframes skShine { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
.sk-card { height: 180px; border-radius: var(--radius-lg); }
.sk-line { height: 12px; margin-top: 8px; border-radius: 6px; width: 80%; }
.sk-line.short { width: 50%; }
@media (prefers-reduced-motion: reduce) { .sk::after { animation: none; } }

/* review photo (v28) */
.review-img { margin-top: 8px; border-radius: var(--radius-md); max-width: 220px; max-height: 220px; object-fit: cover; border: 1px solid var(--glass-hairline); }

/* ==========================================================================
   v31 — STORIES, FLASH DEALS, TOP LISTS
   ========================================================================== */
/* story bar on the homepage */
.stories-bar { display: flex; gap: 14px; overflow-x: auto; padding: 14px 4px;
  scrollbar-width: none; }
.stories-bar::-webkit-scrollbar { display: none; }
.story-ring { display: flex; flex-direction: column; align-items: center; gap: 6px;
  background: none; border: 0; cursor: pointer; flex: none; padding: 0; }
.story-ring-inner { width: 62px; height: 62px; border-radius: 50%; padding: 3px;
  background: var(--ring-conic, conic-gradient(from 150deg, var(--color-primary) 0%, var(--color-foreground) 30%, var(--color-success) 62%, var(--color-primary) 100%));
  transition: transform var(--dur-2) var(--ease-spring); }
.story-ring:hover .story-ring-inner { transform: scale(1.06); }
.story-ring:active .story-ring-inner { transform: scale(.94); }
/* v109: a watched ring greys out — «زنده» فقط برای تازه‌ها */
.story-ring.is-seen .story-ring-inner { background: var(--color-border); }
.story-ring.is-seen .story-name { color: var(--color-faint, var(--color-muted-foreground)); }
.story-ring-inner img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%;
  border: 2px solid var(--color-background); display: block; }
.story-name { font-size: 12px; font-weight: 600; max-width: 68px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; color: var(--color-muted-foreground); }

/* fullscreen story viewer — v109: entrance + slide transitions.
   The progress FILL is driven per-frame by JS (real playback, v103);
   everything else here is pure presentation. */
.story-viewer { position: fixed; inset: 0; z-index: 900; background: #000;
  display: flex; align-items: center; justify-content: center;
  animation: svIn .28s var(--ease-out); }
@keyframes svIn { from { opacity: 0 } to { opacity: 1 } }
.sv-progress { position: absolute; top: max(10px, env(safe-area-inset-top)); inset-inline: 10px;
  display: flex; gap: 5px; z-index: 5; }
.sv-progress span { flex: 1; height: 3.5px; border-radius: 3px; background: rgba(255,255,255,.30); overflow: hidden; }
.sv-progress span.is-done { background: rgba(255,255,255,.30); }
.sv-progress span.is-on { background: rgba(255,255,255,.30); }  /* track stays translucent so the fill shows */
/* v103: the fill width is driven per-frame by JS (real playback), not a CSS timer */
.sv-progress span i { display: block; height: 100%; width: 0; background: #fff; border-radius: 3px;
  box-shadow: 0 0 8px rgba(255,255,255,.55); }
.sv-progress span.is-done i { width: 100%; }
.sv-close { position: absolute; top: max(26px, calc(env(safe-area-inset-top) + 16px)); inset-inline-end: 14px;
  z-index: 6; background: rgba(255,255,255,.15); color: #fff; border: 0; width: 44px; height: 44px;
  border-radius: 50%; font-size: 18px; cursor: pointer;
  animation: svChromeIn .4s .1s var(--ease-out) both; }
.sv-nav { position: absolute; top: 50%; transform: translateY(-50%); z-index: 6;
  background: rgba(255,255,255,.12); color: #fff; border: 0; width: 44px; height: 44px;
  border-radius: 50%; font-size: 26px; line-height: 1; cursor: pointer;
  animation: svChromeIn .4s .12s var(--ease-out) both;
  transition: background-color var(--dur-2), transform var(--dur-2); }
.sv-nav:active { background: rgba(255,255,255,.28); }
.sv-prev { inset-inline-start: 10px; }
.sv-next { inset-inline-end: 10px; }
@keyframes svChromeIn { from { opacity: 0; transform: translateY(-6px) } to { opacity: 1; transform: none } }
.sv-media { max-width: min(560px, 94vw); max-height: 78vh; }
.sv-media img { max-width: 100%; max-height: 78vh; object-fit: contain; border-radius: 14px; }
/* v109: each slide eases in — media + caption move as one beat */
.sv-media > * { animation: svSlide .34s var(--ease-out); }
@keyframes svSlide { from { opacity: 0; transform: scale(.965) } to { opacity: 1; transform: none } }
.sv-caption { position: absolute; bottom: max(90px, calc(env(safe-area-inset-bottom) + 70px));
  inset-inline: 16px; text-align: center; color: #fff; display: flex; flex-direction: column; gap: 4px;
  animation: svCaptionIn .4s .06s var(--ease-out) both; }
@keyframes svCaptionIn { from { opacity: 0; transform: translateY(10px) } to { opacity: 1; transform: none } }
.sv-caption strong { font-size: 15px; text-shadow: 0 1px 10px rgba(0,0,0,.6); }
.sv-caption span { font-size: 13px; opacity: .88; text-shadow: 0 1px 8px rgba(0,0,0,.55); }
.sv-link { position: absolute; bottom: max(30px, calc(env(safe-area-inset-bottom) + 16px));
  inset-inline: 0; text-align: center; color: var(--color-success-text); font-weight: 700; font-size: 14px;
  text-decoration: none; animation: svCaptionIn .45s .14s var(--ease-out) both; }
@media (prefers-reduced-motion: reduce) {
  .story-viewer, .sv-media > *, .sv-caption, .sv-link, .sv-close, .sv-nav { animation: none !important; }
}

/* flash deal cards */
.deal-countdown { font-variant-numeric: tabular-nums; font-weight: 800; font-size: 18px;
  color: var(--color-accent, var(--gold-400, var(--color-primary))); letter-spacing: .03em; }
.deal-countdown.is-done { color: var(--color-muted-foreground); }

/* top-list ranks */
.rank-list { display: flex; flex-direction: column; gap: 12px; }
.rank-item { display: flex; align-items: stretch; gap: 12px; }
.rank-badge { flex: none; width: 40px; height: 40px; border-radius: 12px; display: grid;
  place-items: center; font-weight: 800; font-size: 16px; align-self: center;
  background: var(--color-muted); color: var(--color-foreground); }
.rank-badge.rank-1 { background: var(--color-primary); color: var(--color-on-primary); }
.rank-badge.rank-2 { background: var(--color-muted); color: var(--color-foreground); border: 1px solid var(--color-border-strong); }
.rank-badge.rank-3 { background: color-mix(in oklab, var(--color-warning) 20%, transparent); color: var(--color-warning-text); }
@media (max-width: 480px) {
  .rank-badge { width: 32px; height: 32px; font-size: 14px; border-radius: 10px; }
  .rank-item { gap: 8px; }
}

/* ==========================================================================
   v32 — FOLLOW + NOTIFICATIONS + REVIEW HELPFUL
   ========================================================================== */
.follow-btn { cursor: pointer; background: none; border: 1px solid var(--color-border);
  color: var(--color-muted-foreground); display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--fs-xs); font-weight: 700; padding: 4px 12px; min-height: var(--tap);
  border-radius: var(--radius-pill); }
.follow-btn:hover { border-color: var(--color-destructive); color: var(--color-destructive); }
.follow-btn.is-on, .follow-btn[aria-pressed="true"] {
  color: var(--color-destructive);
  background: color-mix(in oklab, var(--color-destructive) 12%, transparent);
  border-color: color-mix(in oklab, var(--color-destructive) 45%, transparent);
}
.follow-btn.is-on svg, .follow-btn[aria-pressed="true"] svg { fill: currentColor; stroke: currentColor; }
.follow-btn svg { width: 14px; height: 14px; }

.review-helpful { display: inline-flex; align-items: center; gap: 6px; margin-top: 8px;
  background: none; border: 1px solid var(--color-border); border-radius: var(--radius-pill);
  color: var(--color-muted-foreground); font-size: 12px; font-weight: 600;
  padding: 5px 12px; cursor: pointer; min-height: var(--tap); }
.review-helpful:hover, .review-helpful.is-on { border-color: var(--color-destructive); color: var(--color-destructive); }
.review-helpful.is-on svg { fill: currentColor; }
.review-helpful svg { width: 14px; height: 14px; }

.todo-item.is-unread { background: color-mix(in oklab, var(--color-primary) 9%, transparent); }
.todo-item.is-unread strong { color: var(--color-primary); }

/* story ring on business cards + story chip/button (v32) */
.biz-card .card-media.story-ring { border: 3px solid; border-image: none;
  border-color: transparent;
  background-clip: padding-box;
  position: relative; }
.biz-card .card-media.story-ring::before { content: ''; position: absolute; inset: -3px;
  border-radius: inherit; padding: 3px;
  background: var(--ring-conic, conic-gradient(from 150deg, var(--color-primary) 0%, var(--color-foreground) 30%, var(--color-success) 62%, var(--color-primary) 100%));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  pointer-events: none; z-index: 3; }
.story-chip {
  display: inline-flex; align-items: center; gap: 5px;
  background: color-mix(in oklab, var(--color-primary) 12%, var(--color-card));
  color: var(--color-primary-text);
  border: 1px solid color-mix(in oklab, var(--color-primary) 30%, transparent);
  border-radius: var(--radius-pill);
  font-size: var(--fs-xs); font-weight: 700; padding: 10px 14px; cursor: pointer; min-height: 44px;
  position: relative; z-index: 2;
  transition: all var(--dur-2) var(--ease-out);
}
.story-chip:hover {
  background: color-mix(in oklab, var(--color-primary) 22%, var(--color-card));
  transform: translateY(-1px);
}
.story-chip svg { width: 13px; height: 13px; color: var(--color-primary); }
.story-btn { cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
  /* v117/فاز۷: حلقهٔ conic با background-clip نقاشی می‌شد؛ هر استاپ رنگش مثل
     سطح متن خوانده می‌شد (کنتراست ۲٫۱) و در حالت forced-colors هم می‌شکست.
     حالا سطح صاف کارت + حاشیهٔ رنگ‌میکس — همان حس، بدون شکست AA. */
  background: var(--color-card); border: 1.5px solid;
  border-color: color-mix(in oklab, var(--color-primary) 55%, var(--color-border));
  color: var(--color-foreground); font-size: var(--fs-xs); font-weight: 700;
  padding: 4px 12px; min-height: var(--tap); border-radius: var(--radius-pill); }
.story-btn svg { width: 14px; height: 14px; color: var(--gold-400, var(--color-primary)); }
.follow-btn small, .story-btn small { font-size: 12px; }  /* v117/فاز۷: شمارنده ۱۱px بود */

/* owner story card on dashboard (v32) */
.story-own-row { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; }
.story-own-thumbs { display: flex; gap: 8px; flex-wrap: wrap; }
.story-own-thumbs img { width: 56px; height: 56px; object-fit: cover; border-radius: 50%;
  padding: 2px; background: var(--ring-conic, conic-gradient(from 150deg, var(--color-primary) 0%, var(--color-foreground) 30%, var(--color-success) 62%, var(--color-primary) 100%));
  box-shadow: 0 2px 8px rgba(0,0,0,.18); }
.story-own-form { display: flex; gap: 8px; align-items: center; flex: 1; min-width: 240px; flex-wrap: wrap; }
.story-own-form .input { flex: 1; min-width: 160px; }
@media (max-width: 480px) {
  .story-own-row { flex-direction: column; align-items: stretch; }
  .story-own-form { width: 100%; }
}

/* story video tag + viewer video (v37) */
.story-vid-tag { display: grid; place-items: center; width: 100%; height: 100%;
  border-radius: 50%; color: #fff; font-size: 18px;
  background: linear-gradient(150deg, var(--color-primary), var(--color-primary-hover)); }
.sv-media video { max-width: 100%; max-height: 78vh; border-radius: 14px; background: #000; }

/* ==========================================================================
   v37 — CITIES (nationwide, Divar-style city picker)
   ========================================================================== */
.city-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.city-tabs .tab { min-height: var(--tap); padding: 7px 14px; border-radius: var(--radius-pill);
  border: 1px solid var(--color-border); background: var(--color-muted); cursor: pointer;
  font-weight: 700; font-size: 13px; color: var(--color-foreground); }
.city-tabs .tab.is-active, .city-tabs .tab[aria-selected="true"] {
  background: var(--color-primary); color: var(--color-on-primary);
  border-color: transparent; }
.city-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.city-chip { display: inline-flex; align-items: center; gap: 6px; padding: 8px 14px;
  min-height: var(--tap); border-radius: var(--radius-md); border: 1px solid var(--color-border);
  background: var(--color-muted); color: var(--color-foreground); text-decoration: none;
  font-size: 13px; font-weight: 600; }   /* v116-audit: duplicate min-height 38px removed — var(--tap) above wins */
.city-chip:hover { border-color: var(--color-primary); color: var(--color-primary); }
.dir-citybar { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; }
.city-chip .badge { font-size: 12px; padding: 1px 6px; }

/* business owner cards (v37 + v124 mobile-standard) */
.biz-own-list { display: flex; flex-direction: column; gap: 14px; }
.biz-own-card {
  display: flex; flex-direction: column;
  padding: 16px; border-radius: var(--radius-xl);
  background: var(--color-card);
  border: 1px solid var(--color-border);
  box-shadow: var(--e1);
}
.biz-own-head {
  display: flex; gap: 16px; align-items: stretch; flex-direction: column;
}
@media (min-width: 768px) {
  .biz-own-head { flex-direction: row; }
}
.biz-own-media {
  position: relative; border-radius: var(--radius-lg);
  overflow: hidden; width: 100%; height: 160px;
  background: var(--color-muted); flex: none;
}
@media (min-width: 768px) {
  .biz-own-media { width: 200px; height: auto; min-height: 150px; flex: 0 0 200px; }
}
.biz-own-cover {
  width: 100% !important; height: 100% !important;
  object-fit: cover !important; border-radius: inherit; display: block;
}
.biz-own-art {
  display: grid; place-items: center;
  background: radial-gradient(70% 90% at 50% 15%, color-mix(in oklab, var(--brand-300) 42%, transparent), transparent 72%),
              linear-gradient(160deg, color-mix(in oklab, var(--brand-500) 26%, var(--color-muted)), color-mix(in oklab, var(--accent-400) 16%, var(--color-muted)));
}
.biz-own-badge {
  position: absolute; top: 8px; inset-inline-end: 8px; z-index: 2;
  box-shadow: var(--e2); font-size: 12px; padding: 2px 8px;
}
.biz-own-main {
  flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; justify-content: space-between;
}
.biz-own-stats {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px;
  padding: 10px 8px;
  background: color-mix(in oklab, var(--color-muted) 40%, var(--color-card));
  border-radius: var(--radius-md);
  margin-top: 10px; margin-bottom: 12px;
}
.biz-stat-item {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  font-size: 12px; color: var(--color-muted-foreground); gap: 2px;  /* v160 */
}
.biz-stat-item strong {
  font-size: 14px; font-weight: 800; color: var(--color-foreground);
}
.biz-stat-item svg {
  width: 14px; height: 14px; color: var(--color-primary);
}
.biz-own-actions {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px;
}
@media (max-width: 420px) {
  .biz-own-actions { grid-template-columns: repeat(2, 1fr); }
}
.biz-own-actions .btn {
  justify-content: center; padding: 8px 6px; font-size: 12px; font-weight: 700;
  min-height: 40px; border-radius: var(--radius-md);
}

/* homepage: collapsed "more categories" (v39) */
.more-cats summary { list-style: none; display: inline-flex; cursor: pointer;
  align-items: center; gap: 8px; }
.more-cats summary::-webkit-details-marker { display: none; }

/* v75 category art: individual lossless WebP files, fetched lazily only when
   visible. `.ic` also remains the hook used by client-rendered map cards. */
.ic { display: inline-block; background-repeat: no-repeat; vertical-align: middle; flex: none; }
img.cat-icon-file { object-fit: contain; border-radius: 12px; }
.icon-preview .ic { border-radius: 12px; }

/* category art fills its allocated container without stretching the page */
.cat-tile .art .ic, .biz-thumb-art .ic, .biz-own-art .ic { width: 100% !important; height: 100% !important; }
.cat-tile.is-group:has([aria-expanded="true"]) .art .ic { width: 56px !important; height: 56px !important; }

/* ==========================================================================
   PERFORMANCE (v51) — the two most expensive visual effects on a phone GPU
   are the per-frame WebGL scene and the dozens of backdrop-filter blurs.
   On touch devices both are dialled back: glass turns more opaque so the
   blur radius can shrink, and the animated background orbs are trimmed.
   ========================================================================== */
@media (pointer: coarse) {
  .glass, .cat-tile, .chip, .hero-panel, .hero-search, .stat-card,
  .map-item, .accordion-trigger, .badge, .btn-glass {
    -webkit-backdrop-filter: blur(6px) saturate(140%);
    backdrop-filter: blur(6px) saturate(140%);
  }
  .spatial-bg .orb-1 { display: none; }
}

/* ==========================================================================
   PERFORMANCE (v54) — THE SMOOTHNESS FIX
   Root cause of the jank: `backdrop-filter: blur()` on ~99 elements per page.
   Every blurred layer forces the GPU to re-sample and re-composite the whole
   backdrop on every scroll frame — on a phone this is the single biggest
   source of "not smooth". The glass LOOK is kept via a more opaque solid
   translucency (no blur), which costs nothing.

   Second: the scroll-reveal hid 60+ elements behind opacity:0 and animated
   them in with a 780ms perspective transform. Content must be visible
   immediately — no staggered fade-in on touch devices.
   ========================================================================== */

/* 1) Kill backdrop blur everywhere — the glass stays, the GPU cost goes. */
*, *::before, *::after {
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}

/* 2) (v110) glass translucency now lives ONLY in tokens.css — the old v65
      green :root redeclaration sat on top of every theme and is gone. */

/* 3) On touch devices, content shows instantly — no opacity:0 stagger, no
      perspective pop-in. Reveal becomes a no-op so nothing waits for JS. */
@media (pointer: coarse) {
  .js .reveal, .js .reveal-3d {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .reveal-3d, .tilt, .card-hover {
    transform: none !important;
    perspective: none !important;
  }
  /* decorative blurred orbs are the last GPU cost — drop them entirely */
  .spatial-bg::before, .spatial-bg::after, .spatial-bg .orb { display: none; }
}

/* ==========================================================================
   SUBTLE MOTION (v63) — gentle "soul" animations, GPU-cheap, reduced-motion
   safe. Only transform/opacity; nothing that can collide with tilt/reveal.
   ========================================================================== */

/* 1) Story rings breathe softly so the stories bar feels alive (Instagram) */
.story-ring-inner {
  animation: storyBreathe 3.4s ease-in-out infinite;
}
@keyframes storyBreathe {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.05); }
}

/* 2) Hero copy drifts in gently on first paint (one-time, staggered) */
.hero-copy > * {
  animation: heroRise .7s var(--ease-out) both;
}
.hero-copy > *:nth-child(1) { animation-delay: .05s; }
.hero-copy > *:nth-child(2) { animation-delay: .15s; }
.hero-copy > *:nth-child(3) { animation-delay: .25s; }
.hero-copy > *:nth-child(4) { animation-delay: .35s; }
.hero-copy > *:nth-child(5) { animation-delay: .45s; }
@keyframes heroRise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .story-ring-inner, .hero-copy > * { animation: none !important; }
}

/* ---- v90: PWA install banner + Leaflet zoom touch target ---- */
.pwa-install {
  position: fixed; inset-inline: 12px;
  /* v281: بالاتر از نوار «دستیار هوشمند دست گیر» تا اولِ چشم باشد و هم‌پوشانی نکند */
  bottom: calc(var(--botnav-h, 64px) + env(safe-area-inset-bottom, 0px) + 78px);
  z-index: 90; display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; border-radius: 16px;
  background: var(--color-card, var(--color-muted)); border: 1px solid var(--color-border, var(--color-muted));
  box-shadow: 0 12px 36px rgba(0,0,0,.45);
  transform: translateY(160%); opacity: 0;
  transition: transform .26s cubic-bezier(.2,.8,.3,1), opacity .26s;
}
.pwa-install.show { transform: none; opacity: 1; }
.pwa-install-txt { flex: 1; display: flex; flex-direction: column; line-height: 1.35; min-width: 0; }
.pwa-install-txt strong { font-size: 14px; font-weight: 700; }
.pwa-install-txt span { font-size: 12px; color: var(--color-muted-foreground); }
.pwa-install-x { width: 34px; height: 34px; flex: none; border-radius: 10px; color: var(--color-muted-foreground); font-size: 16px; line-height: 1; }
.pwa-install-x:active { background: rgba(255,255,255,.06); }
/* v113 formal map zoom: a real 44px touch target whose VISUAL tile stays a
   quiet 28px chip — the glyph sits on the chip, the hit area fills the cell. */
.leaflet-control-zoom { border-radius: 8px !important; overflow: visible;
  border: 0 !important; background: transparent !important; box-shadow: none !important; }
.leaflet-control-zoom a { position: relative; width: 30px !important; height: 30px !important;
  display: grid; place-items: center; line-height: 1 !important; font-size: 14px !important;
  color: var(--color-foreground); background: transparent !important; border: 0 !important; }
/* v118: quiet, see-through zoom buttons — a faint glass chip instead of a
   solid card, so the map stays the subject. */
.leaflet-control-zoom a::before { content: ''; position: absolute; width: 26px; height: 26px;
  border-radius: 7px; background: color-mix(in oklab, var(--color-card) 40%, transparent);
  border: 1px solid color-mix(in oklab, var(--color-border) 55%, transparent); }
.leaflet-control-zoom a:hover::before { background: color-mix(in oklab, var(--color-card) 70%, transparent); }
.leaflet-control-zoom a:active::before { background: var(--color-muted); }

/* v111: the day/night fade, designed with the palette. When the toggle flips
   the attribute, every colour-carrying property eases in one shared beat —
   text, surfaces, borders, icon strokes — so fonts visibly cross-fade
   between the two palettes instead of snapping. The class exists only during
   the flip (app.js adds/removes it), so the first paint never animates. */
html.theme-fade, html.theme-fade *, html.theme-fade *::before, html.theme-fade *::after {
  transition:
    background-color var(--dur-4) var(--ease-inout),
    color var(--dur-4) var(--ease-inout),
    border-color var(--dur-4) var(--ease-inout),
    fill var(--dur-4) var(--ease-inout),
    stroke var(--dur-4) var(--ease-inout),
    outline-color var(--dur-4) var(--ease-inout),
    text-decoration-color var(--dur-4) var(--ease-inout),
    box-shadow var(--dur-4) var(--ease-inout) !important;
}
@media (prefers-reduced-motion: reduce) {
  html.theme-fade, html.theme-fade *, html.theme-fade *::before, html.theme-fade *::after {
    transition: none !important;
  }
}

/* v109: the toggle icon morphs (old glyph spins/fades out, new one settles in)
   so the sun/moon swap is itself part of the day/night transition. */
.theme-toggle { position: relative; }
.theme-toggle svg { transition: transform .42s var(--ease-spring), opacity .3s ease; }
.theme-toggle.is-swapping svg { transform: rotate(140deg) scale(.4); opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .theme-toggle svg { transition: none; }
  .theme-toggle.is-swapping svg { transform: none; opacity: 1; }
}

/* ── v177: تاریخچهٔ استوری‌ها (/b/{slug}/stories) ───────────────── */
.arch-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: var(--space-md);
}
.arch-card {
  display: flex; flex-direction: column; gap: var(--space-sm);
  padding: 0; border: 1px solid var(--color-border); border-radius: var(--radius-lg);
  background: var(--color-card); overflow: hidden; cursor: pointer;
  text-align: start; min-height: 44px;
  transition: transform var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out);
}
.arch-card:active { transform: scale(.98); }
.arch-card:hover { box-shadow: var(--shadow-2); }
.arch-thumb { position: relative; display: block; aspect-ratio: 3 / 4; background: var(--color-muted); }
.arch-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.arch-meta { display: flex; flex-direction: column; gap: 2px; padding: 0 var(--space-sm) var(--space-sm); font-size: 13px; }
.arch-meta strong { font-size: 12px; color: var(--color-muted-foreground); }
.arch-cap { font-size: 13px; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.arch-live, .arch-old {
  align-self: flex-start; font-size: 12px; border-radius: 999px; padding: 1px 8px;
}
.arch-live { background: color-mix(in oklab, var(--brand-600) 14%, transparent); color: var(--brand-700); }
.arch-old { background: var(--color-muted); color: var(--color-muted-foreground); }

/* ── v177: بازیابی فایل‌ها — پیش‌نمایش + لایت‌باکس ────────────────── */
.trash-thumb {
  width: 56px; height: 56px; border-radius: 12px; overflow: hidden; flex: none;
  border: 1px solid var(--color-border); background: var(--color-muted);
  display: grid; place-items: center; padding: 0; cursor: zoom-in; min-height: 44px; min-width: 44px;
}
.trash-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.trash-thumb.is-empty { color: var(--color-muted-foreground); cursor: default; }
.zi-lightbox {
  position: fixed; inset: 0; z-index: 90; display: grid; place-items: center;
  background: rgba(8, 14, 12, .82); backdrop-filter: blur(3px); padding: var(--space-lg);
}
.zi-lb-img { max-width: min(92vw, 900px); max-height: 82vh; border-radius: var(--radius-lg); box-shadow: var(--shadow-3); }
.zi-lb-close {
  position: absolute; top: max(12px, env(safe-area-inset-top)); inset-inline-end: 14px;
  width: 44px; height: 44px; border-radius: 999px; border: 0; cursor: pointer;
  background: rgba(255,255,255,.14); color: #fff; font-size: 18px;
}
.zi-lb-back { position: absolute; inset: 0; border: 0; background: transparent; cursor: zoom-out; }
.zi-lightbox[hidden] { display: none; }   /* v177: hidden غلبه بر display:grid */

/* ── v177: فرم سریع «موجود شد خبرم کن» در چت ─────────────────────── */
.stock-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.stock-chip { position: relative; }
.stock-chip input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.stock-chip span {
  display: inline-flex; align-items: center; gap: 6px; min-height: 44px;
  padding: 8px 14px; border-radius: 999px; border: 1px solid var(--color-border);
  background: var(--color-card); font-size: 14px; cursor: pointer;
  transition: background var(--dur-2) var(--ease-out), border-color var(--dur-2) var(--ease-out);
}
.stock-chip input:checked + span {
  background: color-mix(in oklab, var(--brand-600) 14%, transparent);
  border-color: var(--brand-600); font-weight: 700;
}
.stock-chip input:focus-visible + span { outline: 2px solid var(--brand-600); outline-offset: 2px; }
.stock-oos { font-size: 12px; color: var(--color-danger, #b3261e); font-weight: 700; }
.stock-qty { display: inline-flex; align-items: center; gap: 10px; }
.stock-qty .input { width: 72px; text-align: center; font-weight: 800; }

/* ==========================================================================
   v281 — پوستهٔ شبِ گرم: پرکردن دکمه‌ها و کاشی دسته‌ها هم‌رنگ اسکرین‌شات تولید
   (پس‌زمینهٔ قهوه‌ای تیره + سطح مشکی خنثی + کاشی سبز + CTA نارنجی آجری)
   ========================================================================== */
:root[data-theme="dark"] .btn-primary,
:root[data-theme="night"] .btn-primary,
:root[data-theme="luxury"] .btn-primary {
  background: linear-gradient(145deg, #115e59, #0f766e);
  color: #ecfdf5;
}
:root[data-theme="dark"] .btn-primary:hover,
:root[data-theme="night"] .btn-primary:hover,
:root[data-theme="luxury"] .btn-primary:hover { background: linear-gradient(145deg, #0f766e, #0d9488); }
:root[data-theme="dark"] .btn-accent,
:root[data-theme="night"] .btn-accent,
:root[data-theme="luxury"] .btn-accent {
  background: linear-gradient(145deg, #9a4a12, #92400e);
  color: #fff7ed;
}
:root[data-theme="dark"] .btn-accent:hover,
:root[data-theme="night"] .btn-accent:hover,
:root[data-theme="luxury"] .btn-accent:hover { background: linear-gradient(145deg, #b45309, #9a4a12); }
:root[data-theme="dark"] .catcard,
:root[data-theme="night"] .catcard,
:root[data-theme="luxury"] .catcard,
:root[data-theme="dark"] .h-catcard,
:root[data-theme="night"] .h-catcard,
:root[data-theme="luxury"] .h-catcard {
  background: linear-gradient(165deg, #105246 0%, #01362c 100%);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border-color: rgba(255, 255, 255, .06);
}

/* v283: نشان‌های اعتماد (اینماد) — کاشی سفید استاندارد روی فوتر؛
   لوگو همیشه زنده از سرور اینماد می‌آید (سرویس‌ورکر ما دامنهٔ بیرونی را
   کش نمی‌کند) و referrerpolicy=origin روی خود عنصر، تأیید اینماد را تضمین
   می‌کند. */
.trust-row{display:flex;justify-content:center;align-items:center;gap:12px;
  padding:16px 0 2px}
.trust-row a{display:inline-flex;background:#fff;border-radius:10px;padding:6px;
  border:1px solid var(--glass-hairline, rgba(255,255,255,.16));
  box-shadow:0 6px 18px rgba(0,0,0,.28)}
.trust-row img{display:block;width:80px;height:80px;border-radius:6px}

/* v284: روش دوم ورود — پنل کلید یک‌بارمصرف در صفحهٔ انتظار */
.lk-fallback{margin-top:4px}
.lk-fallback>summary{list-style:none;cursor:pointer}
.lk-fallback>summary::-webkit-details-marker{display:none}
.lk-body{padding:12px 2px 2px}
.lk-steps{font-size:12.5px;line-height:2;text-align:right;color:var(--color-text-muted)}
.lk-box{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:13px;
  letter-spacing:.4px;overflow-wrap:anywhere;text-align:left;direction:ltr}
.lk-panel{margin-top:2px}

/* v285: رسانهٔ اخبار/رویدادها + سرفصل‌های صفحهٔ قوانین */
.blog-thumb{width:100%;aspect-ratio:16/9;object-fit:cover;border-radius:var(--radius-lg);margin-bottom:10px}
.news-hero-img{width:100%;max-height:420px;object-fit:cover;border-radius:var(--radius-xl);
  margin-bottom:var(--space-lg);box-shadow:var(--e-glow)}
.embed-169{position:relative;width:100%;aspect-ratio:16/9;border-radius:var(--radius-xl);
  overflow:hidden;margin:0 0 var(--space-lg);background:#000;box-shadow:var(--e-glow)}
.embed-169 iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.news-video{width:100%;max-height:420px;border-radius:var(--radius-xl);
  margin-bottom:var(--space-lg);background:#000;box-shadow:var(--e-glow)}
.panel-media-prev{max-width:100%;max-height:180px;border-radius:var(--radius-md);
  object-fit:cover;display:block;margin-bottom:6px}
.rules-h{font-size:1.05rem;margin:var(--space-lg) 0 var(--space-sm);
  color:var(--color-primary-text, var(--color-primary));
  border-inline-start:3px solid var(--color-accent);padding-inline-start:10px}

/* v285: کنترل‌های پرسش‌وپاسخ — ویرایش/حذف پیام خودی + برچسب ویرایش */
.qa-edited{display:inline-block;font-size:10.5px;line-height:1.6;padding:0 6px;
  border-radius:999px;background:rgba(127,127,127,.14);
  color:var(--color-text-muted);vertical-align:middle;margin-inline-start:4px}
.qa-ctrl{display:inline-flex;gap:6px;align-items:center;margin-inline-start:auto}
.qa-ctrl form{display:inline}
.qa-ctrl .btn-sm{font-size:11.5px;padding:2px 9px;min-height:0}
.qa-edit{position:relative}
.qa-edit>summary{cursor:pointer;font-size:11.5px;color:var(--color-primary-text,
  var(--color-primary));padding:2px 9px;border-radius:999px;
  background:rgba(127,127,127,.10);list-style:none}
.qa-edit>summary::-webkit-details-marker{display:none}
.qa-edit form{position:absolute;inset-inline:0 0;bottom:calc(100% + 6px);z-index:30;
  background:var(--color-card, #fff);border:1px solid var(--color-border, #ddd);
  border-radius:var(--radius-md);padding:10px;box-shadow:0 12px 32px rgba(0,0,0,.18);
  min-width:min(92vw, 420px)}
:root[data-theme="dark"] .qa-edit form{background:#1a1f26}

/* v285: شعار کسب‌وکار + قفسهٔ طلایی محصولات ویژه */
.biz-slogan{display:flex;align-items:center;gap:8px;margin:0 0 10px;
  padding:10px 14px;border-radius:var(--radius-lg);font-weight:700;font-size:15px;
  color:var(--color-accent-text, var(--color-accent));
  background:linear-gradient(135deg, rgba(245,158,11,.12), rgba(180,83,9,.06));
  border-inline-start:3px solid var(--color-accent, #b45309)}
.biz-slogan svg{flex:none;opacity:.9}
.special-card{border:1px solid rgba(245,158,11,.42);box-shadow:var(--e-glow-gold)}
.special-card .card-title{color:var(--color-accent-text, inherit)}

/* v285: تعرفه‌ها (چیب امکانات + نوار اعتماد) و صفحهٔ بارکد QR */
/* v289: was a hardcoded 11.5px, below the 12px floor. --fs-xs is the project's
   own smallest text token, so the chip scales with the rest of the type. */
.plan-chip{font-size:var(--fs-xs);padding:3px 10px}
.plan-chips{justify-content:center}
.plan-trust .card-pad{padding:18px 14px}
.plan-trust h3{font-size:.95rem}
.plan-trust svg{color:var(--color-accent)}
.qr-box-lg img{width:min(320px, 70vw);height:auto;background:#fff;
  padding:14px;border-radius:18px;box-shadow:0 8px 28px rgba(0,0,0,.18)}
@media print{
  body *{visibility:hidden !important}
  .qr-page,.qr-page *{visibility:visible !important}
  .qr-page{position:absolute;top:0;inset-inline:0;display:block;text-align:center}
  .qr-page .cluster,.qr-page button,.qr-page script{display:none !important}
}
/* ===== END main.css ===== */

/* ===== BEGIN pages.css sha256:b34fc28bc65b8d76 ===== */
/* ==========================================================================
   Bazarche Najafabad — Page-level composition
   ========================================================================== */

/* Rating stars */
.stars { display: inline-flex; gap: 1px; vertical-align: -2px; }

/* ==========================================================================
   HERO — full-bleed WebGL stage
   ========================================================================== */
.hero {
  position: relative;
  z-index: 20;              /* v64: lift above the sections below so the live
                               search dropdown is never clipped behind them */
  min-height: min(94dvh, 900px);
  display: grid;
  align-items: center;
  padding-block: var(--space-3xl) var(--space-4xl);
  /* overflow moved OFF .hero so the search dropdown can overflow downward;
     .hero-visual / .hero-shade are themselves overflow:hidden / inset:0 */
  overflow: visible;
}
/* The "open now" panel — the one thing a visitor acts on. It sits in the
   left column sharing a baseline with the copy. */
.hero-side {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  min-width: 0;
}

@media (max-width: 1024px) {
  .hero-side { gap: var(--space-md); }
}

.hero-inner {
  position: relative; z-index: 2;
  display: grid; gap: var(--space-2xl);
  grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  /* start, not center: the columns have different natural heights, and
     centring each one independently is what produced the ragged middle */
  align-items: start;
}
@media (max-width: 1024px) {
  .hero-inner { grid-template-columns: 1fr; }
  .hero { min-height: auto; }
}

.hero-copy {
  max-width: 58ch;
  position: relative; z-index: 1;
}
/* A soft scrim behind the headline only. The 3D city is bright around the
   dome, and white-ish text crossing it lost contrast; this keeps the art
   fully visible while guaranteeing the words stay readable. It fades to
   nothing well before the artwork, so it never reads as a box. */
.hero-copy::before {
  content: ''; position: absolute; z-index: -1;
  inset: -6% -8% -6% -12%;
  background: radial-gradient(
      70% 60% at 78% 45%,
      color-mix(in oklab, var(--color-background) 82%, transparent) 0%,
      color-mix(in oklab, var(--color-background) 55%, transparent) 45%,
      transparent 78%);
  pointer-events: none;
}
/* Keep the scrim on phones too: with the 3D city now visible behind the
   headline, the words need the same soft backing to stay readable. */
@media (max-width: 1024px) {
  .hero-copy::before { background: radial-gradient(
      80% 60% at 50% 40%,
      color-mix(in oklab, var(--color-background) 80%, transparent) 0%,
      color-mix(in oklab, var(--color-background) 50%, transparent) 55%,
      transparent 80%); }
}
.hero-badge {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 16px; border-radius: var(--radius-pill);
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: blur(14px) saturate(180%); backdrop-filter: blur(14px) saturate(180%);
  border: 1px solid var(--glass-border);
  box-shadow: var(--e2), var(--e-inset-top);
  font-size: var(--fs-sm); font-weight: 700;
  margin-bottom: var(--space-lg);
}
.hero-badge svg { width: 17px; height: 17px; color: var(--color-accent); }
.hero-badge .dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--color-success);
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--color-success) 22%, transparent);
  animation: pulseDot 2.4s var(--ease-inout) infinite;
}
@keyframes pulseDot { 0%,100% { opacity: 1 } 50% { opacity: .45 } }
@media (prefers-reduced-motion: reduce) { .hero-badge .dot { animation: none; } }

.hero h1 {
  font-size: var(--fs-4xl);

  line-height: 1.08;
}
.hero h1 .grad {
  /* v111 formal: a headline is ink, not a gradient. The token carries the
     day/night colour, so it can never fade in either mode. */
  background: none;
  -webkit-background-clip: border-box; background-clip: border-box;
  -webkit-text-fill-color: currentColor; color: var(--color-foreground);
}
.hero-lead {
  margin-top: var(--space-lg);
  font-size: var(--fs-lg);
  color: var(--color-muted-foreground);
  max-width: 52ch;
}
.hero-cta { display: flex; flex-wrap: wrap; gap: var(--space-md); margin-top: var(--space-xl); }

/* Hero search bar — floats above the 3D stage */
.hero-search {
  margin-top: var(--space-xl);
  padding: var(--space-sm);
  border-radius: var(--radius-xl);
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: blur(var(--glass-blur-lg)) saturate(190%);
  backdrop-filter: blur(var(--glass-blur-lg)) saturate(190%);
  border: 1px solid var(--glass-border);
  box-shadow: var(--e4), var(--e-inset-top);
  display: flex; gap: var(--space-sm); flex-wrap: wrap;
}
.hero-search .search-wrap { flex: 1 1 240px; position: relative; }
.hero-search .input { border: 0; background: transparent; box-shadow: none; min-height: 52px; }
.hero-search .input:focus { box-shadow: none; }
.hero-search .btn { flex: none; }

/* Live search suggestions (v50) */
.live-sugg {
  position: absolute; top: calc(100% + 6px); inset-inline: 0; z-index: 50;
  max-height: 320px; overflow-y: auto;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--e4);
  padding: 6px;
}
.live-sugg[hidden] { display: none; }
.live-sugg button {
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: 10px 12px; border: 0; background: none;
  border-radius: var(--radius-sm); cursor: pointer;
  font: inherit; color: var(--color-foreground); text-align: start;
}
.live-sugg button:hover, .live-sugg button.is-active {
  background: var(--color-muted);
}
.live-sugg .sugg-ic {
  flex: none; width: 30px; height: 30px; border-radius: 8px;
  display: grid; place-items: center;
  background: color-mix(in oklab, var(--color-primary) 12%, transparent);
  color: var(--color-primary-text);
}
.live-sugg .sugg-ic svg { width: 16px; height: 16px; }
.live-sugg .sugg-main {
  flex: 1; min-width: 0;
  display: grid; gap: 3px; align-content: center;
}
.live-sugg .sugg-name,
.live-sugg .sugg-sub {
  display: block; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.live-sugg .sugg-name { font-weight: 700; font-size: var(--fs-sm); line-height: 1.45; }
.live-sugg .sugg-sub {
  font-size: var(--fs-xs); line-height: 1.5;
  color: var(--color-muted-foreground);
}
.live-sugg .sugg-empty { padding: 12px; font-size: var(--fs-sm); color: var(--color-muted-foreground); text-align: center; }

/* ---- map search panel (v65): search + sort chips above the map ---- */
.map-hero { padding-block-end: var(--space-sm); }
.map-search { margin-bottom: var(--space-md); }
.map-search .search-wrap { position: relative; display: block; }
.map-search .live-sugg { position: absolute; top: calc(100% + 6px); inset-inline: 0; z-index: 60; }
.map-chips {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  margin-top: var(--space-md);
}
.map-chips .chip { min-height: 44px; }
.map-chips .chip.is-active { border-color: var(--color-primary); color: var(--color-primary-text); background: color-mix(in oklab, var(--color-primary) 16%, transparent); }
.select-chip { display: inline-flex; }
.select-chip .select { min-height: 44px; max-width: 200px; }
.map-search .dir-row { grid-template-columns: minmax(0, 1fr) auto; }
.map-search .search-wrap { min-width: 0; }
.map-search .map-geo-hint { display: block; min-width: 0; }
/* The map hint is helpful, but an auto-width second grid column collapsed the
   disabled category-first search field to a few pixels on a phone. Keep the
   search usable and move the hint below it in the narrow layout. */
@media (max-width: 640px) {
  .map-search .dir-row { grid-template-columns: minmax(0, 1fr); }
  .map-search .map-geo-hint { grid-column: 1; line-height: 1.65; }
}

.hero-trust {
  display: flex; flex-wrap: wrap; gap: var(--space-lg);
  margin-top: var(--space-xl);
  font-size: var(--fs-sm); color: var(--color-muted-foreground);
}
.hero-trust > span { display: inline-flex; align-items: center; gap: 7px; }
.hero-trust svg { width: 17px; height: 17px; color: var(--color-primary); }

/* Floating glass panel on the hero's right — 3D counterweight */
.hero-panel {
  position: relative;
  padding: var(--space-lg);
  border-radius: var(--radius-2xl);
  /* Sits at the top of .hero-side; the art follows directly beneath it. */
  z-index: 2;
}
@media (max-width: 1024px) { .hero-panel { align-self: auto; } }
.hero-panel-title { display: flex; align-items: center; gap: 10px; font-weight: 800; margin-bottom: var(--space-md); }
.hero-panel-title svg { width: 20px; height: 20px; color: var(--color-primary); }
.hero-mini-list { display: grid; gap: 10px; }
.hero-mini {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 13px; border-radius: var(--radius-md);
  background: var(--glass-bg-weak);
  border: 1px solid var(--glass-hairline);
  /* v89: the row is now a real link to the shop, so it must not pick up the
     default anchor underline/colour — it should look exactly like before. */
  color: inherit; text-decoration: none; cursor: pointer;
  transition: transform var(--dur-3) var(--ease-out), background-color var(--dur-3) var(--ease-out);
  /* Measured at 360px: the row rendered 353px wide starting at left:-22, i.e.
     hanging off both edges. A grid item defaults to min-width:auto, so the
     open/closed badge and the shop name refused to shrink and pushed the row
     past its track. Same trap as the category grid. */
  min-width: 0;
}
.hero-mini:hover { transform: translateX(-5px); background: var(--glass-bg); }
.hero-mini:focus-visible { outline: 2px solid var(--brand-400); outline-offset: 2px; }
.hero-mini:active { transform: scale(.98); }
.hero-mini img { width: 40px; height: 40px; flex: none; }
/* The badge must never be the thing that widens the row — the name truncates
   instead, because "باز است" is worth more than the fourth word of a shop name. */
.hero-mini .badge { flex: none; max-width: 46%; }
@media (max-width: 400px) {
  /* On a 360px phone even a shrunk badge crowds the name out; the open-state
     dot in the panel header already carries the same information. */
  .hero-mini { gap: 9px; padding: 10px 11px; }
  .hero-mini img { width: 34px; height: 34px; }
  .hero-mini .badge { max-width: 40%; font-size: var(--fs-xs); }
}
/* name above address — as inline spans they ran together into one line */
.hero-mini-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.hero-mini .t {
  font-weight: 700; font-size: var(--fs-sm);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.hero-mini .s {
  font-size: var(--fs-xs); color: var(--color-muted-foreground);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.hero-mini .badge { margin-inline-start: auto; }

/* Scroll cue */
.scroll-cue {
  position: absolute; bottom: 22px; inset-inline-start: 50%;
  transform: translateX(50%);
  z-index: 3; display: grid; place-items: center; gap: 6px;
  font-size: var(--fs-xs); color: var(--color-muted-foreground);
}
.scroll-cue .mouse {
  width: 26px; height: 42px; border-radius: 14px;
  border: 2px solid var(--color-border-strong);
  position: relative;
}
.scroll-cue .mouse::after {
  content: ''; position: absolute; top: 7px; left: 50%; margin-left: -2.5px;
  width: 5px; height: 8px; border-radius: 3px; background: var(--color-primary);
  animation: wheel 1.8s var(--ease-inout) infinite;
}
@keyframes wheel { 0% { transform: translateY(0); opacity: 1 } 70% { transform: translateY(13px); opacity: 0 } 100% { opacity: 0 } }
@media (prefers-reduced-motion: reduce) { .scroll-cue .mouse::after { animation: none; } }
@media (max-width: 1024px) { .scroll-cue { display: none; } }

/* ==========================================================================
   CATEGORY TILES — 3D icon plates
   ========================================================================== */
.cat-search {
  max-width: 560px; margin: 0 auto var(--space-lg);
}
.cat-search .search-wrap .input { min-height: var(--tap); font-size: var(--fs-base); }

/* ==========================================================================
   BROWSE ALL CATEGORIES (/categories) — the full 173-trade index (v49)
   ========================================================================== */
.catgroup {
  margin-bottom: var(--space-xl);
  padding-bottom: var(--space-xl);
  border-bottom: 1px solid var(--color-border);
  scroll-margin-top: 130px;
}
.catgroup:last-child { border-bottom: 0; margin-bottom: 0; }
.catgroup-head {
  display: flex; align-items: center; gap: var(--space-md);
  margin-bottom: var(--space-lg);
}
.catgroup-photo {
  flex: none; width: 64px; height: 64px; border-radius: var(--radius-lg);
  overflow: hidden; display: grid; place-items: center;
  background: var(--color-muted);
  box-shadow: var(--e2);
}
.catgroup-photo img { width: 100%; height: 100%; object-fit: cover; }
.catgroup-photo .ic { width: 40px; height: 40px; }
.catgroup-meta { flex: 1; min-width: 0; }
.catgroup-title { font-size: var(--fs-xl); font-weight: 800; }
.catgroup-blurb { margin-top: 3px; font-size: var(--fs-sm); color: var(--color-muted-foreground); }
.catgroup-all {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  min-height: var(--tap); /* v77: هدف لمسی ≥۴۴px */
  font-size: var(--fs-sm); font-weight: 700; color: var(--color-primary-text);
  padding: 8px 14px; border-radius: var(--radius-pill);
  background: color-mix(in oklab, var(--color-primary) 10%, transparent);
  border: 1px solid color-mix(in oklab, var(--color-primary) 25%, transparent);
  white-space: nowrap;
}
.catgroup-all svg { width: 15px; height: 15px; }

/* Category Navigation Tabs on /categories */
.cats-nav-bar {
  position: sticky; top: 60px; z-index: 20;
  background: color-mix(in oklab, var(--color-background) 90%, transparent);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  padding: 8px 0; border-bottom: 1px solid var(--glass-border);
}
.cats-nav-scroll {
  display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none;
  padding: 4px 2px; -webkit-overflow-scrolling: touch;
}
.cats-nav-scroll::-webkit-scrollbar { display: none; }
.cats-nav-scroll .chip {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  min-height: 44px; padding: 6px 14px; border-radius: var(--radius-pill);
  font-size: var(--fs-xs); font-weight: 700; text-decoration: none;
  background: var(--color-surface); border: 1px solid var(--color-border);
  color: var(--color-foreground); transition: all var(--dur-2) var(--ease-out);
}
.cats-nav-scroll .chip.is-active,
.cats-nav-scroll .chip:hover {
  background: var(--color-primary); color: var(--color-on-primary);
  border-color: var(--color-primary);
}

.catcard-grid {
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
}
.catcard {
  position: relative; display: flex; align-items: center; gap: 10px;
  min-height: 48px; padding: 10px 12px; border-radius: var(--radius-lg);
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  border: 1px solid var(--glass-border);
  box-shadow: var(--e1);
  text-decoration: none; color: inherit;
  transition: transform var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out),
              border-color var(--dur-2) var(--ease-out);
  /* v330/کارایی: صفحهٔ /categories ۱۵۱ کارت دارد و با وجود loading="lazy"
     مرورگر تقریباً همهٔ ۲۰۰ تصویر را در بارگذاری اول می‌گرفت (۳٫۳ مگابایت).
     content-visibility رندر و در نتیجه واکشیِ کارت‌های بیرون از نما را به
     تعویق می‌اندازد.
     مقدار ۳۸px تصادفی نیست: کارت دقیقاً ۶۰px ارتفاع دارد و چون
     contain-intrinsic-* اندازهٔ «جعبهٔ محتوا» را می‌گیرد، باید
     ۱۰+۱۰ padding و ۱+۱ border کم شود. با ۶۰px ارتفاع صفحه در دسکتاپ
     ۵۲۸px و در موبایل ۲۹۷۰px اشتباه می‌شد و CLS از صفر درمی‌آمد؛ با ۳۸px
     ارتفاع صفحه در ۳۶۰/۷۶۸/۱۳۶۶ دقیقاً برابر قبل و CLS صفر می‌ماند.
     اندازه‌گیری: ۴۴٪ کمتر بایت در دسکتاپ، ۳۸٪ در تبلت، ۳۳٪ در موبایل.
     مرورگرهای قدیمی این دو خط را نادیده می‌گیرند و رفتار فعلی را دارند. */
  content-visibility: auto;
  contain-intrinsic-height: auto 38px;
}
.catcard:hover {
  transform: translateY(-2px); box-shadow: var(--e3);
  border-color: color-mix(in oklab, var(--color-primary) 35%, transparent);
}
.catcard-thumb {
  flex: none; width: 38px; height: 38px; border-radius: 10px; overflow: hidden;
  display: grid; place-items: center; background: var(--color-muted);
}
.catcard-thumb img { width: 100%; height: 100%; object-fit: cover; }
.catcard-thumb .ic { width: 24px; height: 24px; }
.catcard-name {
  flex: 1; min-width: 0; font-size: var(--fs-xs); font-weight: 700;
  line-height: 1.35; word-break: break-word;
}
.catcard-n {
  flex: none; font-size: 12px; font-weight: 700; color: var(--color-muted-foreground);  /* v160 */
  background: var(--color-muted); padding: 2px 7px; border-radius: 999px;
}
@media (max-width: 640px) {
  .catcard-grid { grid-template-columns: repeat(2, 1fr); gap: 8px; }
  .catgroup-head {
    display: grid; grid-template-columns: 48px minmax(0, 1fr);
    gap: 10px; align-items: center;
  }
  .catgroup-photo { width: 48px; height: 48px; }
  .catgroup-title { font-size: var(--fs-lg); }
  .catgroup-blurb { font-size: var(--fs-xs); }
  .catgroup-all { grid-column: 1 / -1; width: 100%; justify-content: center; }
}
@media (max-width: 360px) {
  .catcard-grid { grid-template-columns: 1fr; gap: 6px; }
}

.cat-grid {
  display: grid; gap: var(--space-md);
  /* 165px keeps two trade tiles per row on a 360px phone — the owner wants all
     165 categories browsable, and one-per-row made that a marathon. */
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 158px), 1fr));
  align-items: start;          /* a tile must not stretch to its row's height */
}
/* 360px measured: track 336px, and a 16px gap left 160px per column — just
   under the minimum, so it collapsed to one. Tightening the gap on narrow
   phones buys the second column back. */
@media (max-width: 400px) {
  .cat-grid { gap: 10px; }
}
/* An open accordion spans the full row so its pills get real space instead
   of stacking one-per-line inside a narrow column. */
.cat-tile.is-group:has([aria-expanded="true"]) { grid-column: 1 / -1; }
.cat-tile.is-group:has([aria-expanded="true"]) .cat-tile-head {
  display: grid;
  grid-template-columns: auto minmax(0,1fr) auto;
  align-items: center; gap: 14px; text-align: start;
}
.cat-tile.is-group:has([aria-expanded="true"]) .art { margin: 0; }
.cat-tile.is-group:has([aria-expanded="true"]) .art img { width: 56px; height: 56px; }
.cat-tile.is-group:has([aria-expanded="true"]) .blurb { grid-column: 2; }
.cat-tile.is-group:has([aria-expanded="true"]) .cat-chevron { position: static; }

.cat-tile {
  position: relative;
  display: grid; gap: 8px; justify-items: center; text-align: center;
  padding: var(--space-lg) var(--space-md);
  border-radius: var(--radius-xl);
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(180%);
  backdrop-filter: blur(var(--glass-blur)) saturate(180%);
  border: 1px solid var(--glass-border);
  box-shadow: var(--e2), var(--e-inset-top);
  cursor: pointer;
  transition: box-shadow var(--dur-3) var(--ease-out), border-color var(--dur-3) var(--ease-out);
}
.cat-tile:hover { box-shadow: var(--e4); border-color: color-mix(in oklab, var(--color-primary) 35%, var(--glass-border)); }
.cat-tile .art {
  width: 82px; height: 82px;
  display: grid; place-items: center;
  filter: drop-shadow(0 12px 18px rgba(6, 40, 32, .22));
  transition: transform var(--dur-4) var(--ease-spring);
}
.cat-tile:hover .art { transform: translateZ(40px) scale(1.09) rotate(-4deg); }
.cat-tile .art img { width: 100%; height: 100%; object-fit: contain; }

/* Documentary photo banner on a category tile (v49). A warm hands-at-work
   image across the top with the trade icon pinned in the corner — the
   "soul" of a real market instead of a flat icon plate. */
.cat-photo {
  display: block; width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-md);
  overflow: hidden; position: relative;
  margin-bottom: 6px;
}
.cat-photo img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform var(--dur-4) var(--ease-out);
}
.cat-photo::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, transparent 45%, rgba(6, 40, 32, .30));
}
.cat-tile:hover .cat-photo img { transform: scale(1.06); }
.cat-tile .name { font-weight: 800; font-size: var(--fs-sm); }
.cat-tile .count { font-size: var(--fs-xs); color: var(--color-muted-foreground); }
.cat-tile .blurb {
  font-size: var(--fs-xs); color: var(--color-muted-foreground);
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* ==========================================================================
   BUSINESS CARD thumb — 3D icon on a gradient plate
   ========================================================================== */
.biz-thumb {
  aspect-ratio: 16 / 9;
  display: grid; place-items: center;
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(70% 90% at 50% 15%, color-mix(in oklab, var(--brand-300) 42%, transparent), transparent 72%),
    linear-gradient(160deg, color-mix(in oklab, var(--brand-500) 26%, var(--color-muted)), color-mix(in oklab, var(--accent-400) 16%, var(--color-muted)));
}
.biz-thumb:not(.has-photo)::after { display: none !important; }
.biz-thumb-art {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  transition: transform var(--dur-5) var(--ease-out);
  z-index: 1;
}
.card-hover:hover .biz-thumb-art { transform: scale(1.05); }
.biz-thumb-art img,
.biz-thumb-art .ic { width: 100% !important; height: 100% !important; object-fit: cover !important; }
.biz-cover { width: 100% !important; height: 100% !important; object-fit: cover !important; }
.biz-card .card-title { font-size: var(--fs-base); }
.biz-card .card-title-wrap { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.biz-card .card-badges-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.biz-card .card-foot .card-arrow {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; color: var(--color-muted-foreground);
}
.biz-card .card-foot .card-arrow svg { width: 18px; height: 18px; }
.biz-card .card-foot .card-meta span:not(:has(svg)) {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 24ch;
}

/* Corner badge on shop thumbnail (only verified badge) */
.media-corner-badge {
  position: absolute;
  top: 6px;
  inset-inline-end: 6px;
  z-index: 3;
}
.media-corner-badge .badge {
  font-size: var(--fs-xs);
  font-weight: 700;
  padding: 2px 7px;
  border-radius: var(--radius-pill);
  box-shadow: var(--e1);
  display: inline-flex;
  align-items: center;
  gap: 3px;
}
.media-corner-badge .badge svg {
  width: 12px;
  height: 12px;
}

/* Card favorite button - placed neatly in card header */
.card-fav-btn {
  position: relative !important;
  inset: auto !important;
  top: auto !important;
  inset-inline-end: auto !important;
  width: 44px !important;
  height: 44px !important;
  min-width: 44px !important;
  min-height: 44px !important;
  flex: 0 0 44px !important;
  border-radius: 50% !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  background: var(--color-secondary) !important;
  border: 1px solid var(--color-border) !important;
  color: var(--color-muted-foreground) !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  z-index: 2 !important;
  cursor: pointer !important;
  margin: 0 !important;
  padding: 0 !important;
  transition: transform var(--dur-2) var(--ease-out), color var(--dur-2) var(--ease-out), background-color var(--dur-2) var(--ease-out), border-color var(--dur-2) var(--ease-out) !important;
}
.card-fav-btn:hover {
  transform: scale(1.08) !important;
  color: var(--color-destructive) !important;
  background: color-mix(in oklab, var(--color-destructive) 8%, var(--color-card)) !important;
  border-color: color-mix(in oklab, var(--color-destructive) 35%, var(--color-border)) !important;
}
.card-fav-btn svg { width: 18px !important; height: 18px !important; }

/* Inline story chip inside card meta */
.story-chip-inline {
  position: relative !important;
  inset: auto !important;
  bottom: auto !important;
  inset-inline-start: auto !important;
  display: inline-flex !important;
  align-items: center !important;
  gap: 4px !important;
  padding: 2px 8px !important;
  border-radius: var(--radius-pill) !important;
  background: color-mix(in oklab, var(--color-primary) 12%, var(--color-card)) !important;
  color: var(--color-primary-text) !important;
  border: 1px solid color-mix(in oklab, var(--color-primary) 30%, transparent) !important;
  font-size: var(--fs-xs) !important;
  font-weight: 700 !important;
  cursor: pointer !important;
  min-height: 44px !important; /* v176: استاندارد لمس ≥۴۴px (قبلاً ۲۸px) */
  z-index: 2 !important;
  margin-inline-start: 4px !important;
  transition: all var(--dur-2) var(--ease-out) !important;
}
.story-chip-inline:hover {
  background: color-mix(in oklab, var(--color-primary) 22%, var(--color-card)) !important;
  transform: translateY(-1px);
}
.story-chip-inline svg {
  width: 13px !important;
  height: 13px !important;
  color: var(--color-primary) !important;
}
/* v131: keep the pill visually compact but guarantee a 44px touch target —
   the hit area expands invisibly instead of fattening the card layout. */
.story-chip-inline::after {
  content: "";
  position: absolute;
  inset: -8px;
  border-radius: inherit;
}

/* ==========================================================================
   FEATURE / STEP CARDS
   ========================================================================== */
.feature {
  position: relative; padding: var(--space-xl);
  border-radius: var(--radius-xl);
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur)); backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--glass-border);
  box-shadow: var(--e2), var(--e-inset-top);
  transition: box-shadow var(--dur-3) var(--ease-out);
}
.feature:hover { box-shadow: var(--e4); }
.feature .f-icon {
  width: 56px; height: 56px; border-radius: var(--radius-lg);
  display: grid; place-items: center; margin-bottom: var(--space-md);
  background: var(--color-primary);
  color: var(--color-on-primary); box-shadow: var(--e3);
}
.feature .f-icon.alt { background: var(--color-primary); }
.feature .f-icon svg { width: 27px; height: 27px; }
.feature h3 { font-size: var(--fs-lg); }
.feature p { margin-top: 9px; color: var(--color-muted-foreground); font-size: var(--fs-sm); }

.step-num {
  position: absolute; top: var(--space-lg); inset-inline-end: var(--space-lg);
  font-size: 3.4rem; font-weight: 800; line-height: 1;
  color: color-mix(in oklab, var(--color-primary) 14%, transparent);
  font-variant-numeric: tabular-nums; pointer-events: none;
}

/* ==========================================================================
   CITY GALLERY — parallax depth strip
   ========================================================================== */
.city-strip {
  display: grid; gap: var(--space-md);
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 150px;
}
@media (max-width: 900px) { .city-strip { grid-template-columns: repeat(2, 1fr); } }
.city-cell {
  position: relative; overflow: hidden;
  border-radius: var(--radius-lg);
  border: 1px solid var(--glass-border);
  box-shadow: var(--e2);
  display: grid; place-items: center;
  background: linear-gradient(160deg, color-mix(in oklab, var(--brand-500) 30%, var(--color-muted)), color-mix(in oklab, var(--accent-500) 18%, var(--color-muted)));
  transition: box-shadow var(--dur-3) var(--ease-out);
}
.city-cell:hover { box-shadow: var(--e4); }
.city-cell.tall { grid-row: span 2; }
.city-cell.wide { grid-column: span 2; }
.city-cell .cc-art { width: 62%; max-width: 120px; opacity: .95; filter: drop-shadow(0 12px 18px rgba(4,30,24,.28)); }
.city-cell figcaption {
  position: absolute; inset-inline: 0; bottom: 0;
  padding: 22px 14px 12px;
  background: linear-gradient(180deg, transparent, rgba(3, 22, 18, .72));
  color: #fff; font-size: var(--fs-xs); font-weight: 700;
}

/* ==========================================================================
   CTA BAND
   ========================================================================== */
/* v111 formal: one flat card band. The drifting colour washes and the
   on-primary text (white-on-grey in day mode) are gone. */
.cta-band {
  position: relative; overflow: hidden;
  border-radius: var(--radius-2xl);
  padding: var(--space-4xl) var(--space-xl);
  text-align: center;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  color: var(--color-card-foreground);
  box-shadow: var(--e2);
  isolation: isolate;
}
.cta-band::before { display: none; }
.cta-band h2 { font-size: var(--fs-3xl); color: var(--color-foreground); }
.cta-band p { margin-top: var(--space-md); max-width: 56ch; margin-inline: auto; font-size: var(--fs-lg); color: var(--color-muted-foreground); }
.cta-band .cluster { justify-content: center; margin-top: var(--space-xl); }
.cta-band .btn-glass { background: var(--color-muted); border-color: var(--color-border-strong); color: var(--color-foreground); }
.cta-band .btn-glass:hover { background: var(--color-border); }

/* ==========================================================================
   DIRECTORY TOOLBAR
   ========================================================================== */
.dir-toolbar {
  position: sticky; top: calc(var(--header-h) + 10px);
  z-index: var(--z-sticky);
  padding: var(--space-md);
  border-radius: var(--radius-xl);
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: blur(var(--glass-blur-lg)) saturate(190%);
  backdrop-filter: blur(var(--glass-blur-lg)) saturate(190%);
  border: 1px solid var(--glass-border);
  box-shadow: var(--e3), var(--e-inset-top);
  margin-bottom: var(--space-lg);
}
.dir-row { display: grid; gap: var(--space-sm); grid-template-columns: 1fr auto auto auto; align-items: center; }
@media (max-width: 900px) { .dir-row { grid-template-columns: 1fr auto; } }
@media (max-width: 520px) { .dir-row { grid-template-columns: 1fr auto; } }
.dir-toolbar-static { position: static; top: auto; }
.search-wrap-wide { flex: 2 1 280px; }
.panel-object { display: flex; align-items: center; gap: 10px; min-width: 0; }
.panel-align-start { align-items: flex-start; }
.flex-1 { flex: 1; min-width: 0; }
.mt-xxs { margin-top: 3px; }
.check-compact { min-height: 0; }
.inline-form { display: inline; }
.is-danger { color: var(--color-destructive) !important; }
.empty-state-roomy { padding: var(--space-2xl); }
.cell-select { width: 36px; }
.textarea-short { min-height: 80px; }
.dir-chips { display: flex; gap: 8px; overflow-x: auto; padding: var(--space-md) 2px 2px; scrollbar-width: thin; }
.dir-chips::-webkit-scrollbar { height: 6px; }
.dir-chips::-webkit-scrollbar-thumb { background: var(--color-border-strong); border-radius: 3px; }
.dir-meta { display: flex; flex-wrap: wrap; gap: var(--space-md); align-items: center; justify-content: space-between; margin-bottom: var(--space-lg); font-size: var(--fs-sm); color: var(--color-muted-foreground); }
.ux-scope-card {
  position: relative;
  overflow: hidden;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: var(--space-md);
  align-items: center;
  margin: -2px 0 var(--space-lg);
  padding: var(--space-lg);
  border-radius: var(--radius-xl);
  border: 1px solid color-mix(in oklab, var(--color-primary) 28%, var(--color-border));
  background:
    radial-gradient(circle at 100% 0, color-mix(in oklab, var(--color-primary) 18%, transparent), transparent 34%),
    linear-gradient(135deg, color-mix(in oklab, var(--color-primary) 11%, var(--color-card)), var(--color-card));
  box-shadow: var(--e2);
}
.ux-scope-card::before {
  content: "";
  position: absolute;
  inset-block: 14px;
  inset-inline-start: 0;
  width: 5px;
  border-radius: 999px;
  background: var(--color-primary);
}
.ux-scope-card-catalog {
  border-color: color-mix(in oklab, var(--accent-500) 32%, var(--color-border));
  background:
    radial-gradient(circle at 100% 0, color-mix(in oklab, var(--accent-500) 18%, transparent), transparent 34%),
    linear-gradient(135deg, color-mix(in oklab, var(--accent-500) 10%, var(--color-card)), var(--color-card));
}
.ux-scope-card-catalog::before { background: var(--accent-500); }
.ux-scope-icon {
  width: 52px;
  height: 52px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-lg);
  color: var(--color-primary);
  background: color-mix(in oklab, var(--color-primary) 13%, var(--color-muted));
  border: 1px solid color-mix(in oklab, var(--color-primary) 20%, var(--color-border));
}
.ux-scope-card-catalog .ux-scope-icon {
  color: var(--accent-600);
  background: color-mix(in oklab, var(--accent-500) 12%, var(--color-muted));
  border-color: color-mix(in oklab, var(--accent-500) 22%, var(--color-border));
}
.ux-scope-icon svg { width: 26px; height: 26px; }
.ux-scope-copy { min-width: 0; }
.ux-scope-copy strong { display: block; color: var(--color-foreground); font-size: var(--fs-lg); margin-bottom: 4px; }
.ux-scope-copy span,
.ux-scope-copy small { display: block; color: var(--color-muted-foreground); line-height: 1.9; }
.ux-scope-copy small { margin-top: 3px; font-size: var(--fs-xs); }
.ux-scope-copy small svg { width: 14px; height: 14px; vertical-align: -3px; color: var(--color-primary); }
.ux-scope-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.scope-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 40px;
  padding: 8px 12px;
  border-radius: 999px;
  border: 1px solid var(--color-border-strong);
  background: var(--color-card);
  color: var(--color-foreground);
  font-size: var(--fs-sm);
  font-weight: 800;
  text-decoration: none;
  box-shadow: var(--e1);
}
.scope-pill svg { width: 16px; height: 16px; }
.scope-pill.is-current {
  border-color: color-mix(in oklab, var(--color-primary) 48%, var(--color-border));
  color: var(--color-primary);
  background: color-mix(in oklab, var(--color-primary) 9%, var(--color-card));
}
.scope-pill[href]:hover { transform: translateY(-1px); border-color: var(--color-primary); color: var(--color-primary); }
@media (max-width: 720px) {
  .ux-scope-card { grid-template-columns: auto minmax(0, 1fr); padding: var(--space-md); }
  .ux-scope-actions { grid-column: 1 / -1; justify-content: stretch; }
  .scope-pill { flex: 1 1 130px; justify-content: center; }
}

/* Category header banner */
.cat-banner {
  position: relative; overflow: hidden;
  border-radius: var(--radius-2xl);
  padding: var(--space-2xl);
  display: flex; align-items: center; gap: var(--space-xl); flex-wrap: wrap;
  background: linear-gradient(150deg, color-mix(in oklab, var(--brand-500) 30%, var(--color-card)), color-mix(in oklab, var(--accent-400) 18%, var(--color-card)));
  border: 1px solid var(--glass-border);
  box-shadow: var(--e3);
  margin-bottom: var(--space-xl);
}
.cat-banner .art { width: 120px; height: 120px; flex: none; filter: drop-shadow(0 18px 26px rgba(4,30,24,.3)); }
.cat-banner h1 { font-size: var(--fs-3xl); }
.cat-banner p { color: var(--color-muted-foreground); margin-top: 6px; max-width: 52ch; }

/* ==========================================================================
   BUSINESS DETAIL
   ========================================================================== */
.biz-layout { display: grid; gap: var(--space-xl); grid-template-columns: minmax(0, 1fr) 340px; align-items: start; }
@media (max-width: 1024px) { .biz-layout { grid-template-columns: 1fr; } }

.biz-hero {
  position: relative; overflow: hidden;
  border-radius: var(--radius-2xl);
  padding: var(--space-2xl);
  background: linear-gradient(150deg, color-mix(in oklab, var(--gold-400) 10%, var(--color-card)), var(--color-card) 58%, color-mix(in oklab, var(--aurora-v) 6%, var(--color-card)));
  border: 1px solid color-mix(in oklab, var(--gold-400) 16%, var(--glass-border));
  box-shadow: var(--e3);
  display: flex; gap: var(--space-xl); align-items: center; flex-wrap: wrap;
  margin-bottom: var(--space-xl);
}
.biz-hero .art { width: 140px; height: 140px; flex: none; filter: drop-shadow(0 20px 28px rgba(0,0,0,.35)); }
.biz-hero h1 { font-size: var(--fs-3xl); }
.biz-hero .sub { color: var(--color-muted-foreground); margin-top: 8px; }

.gallery-main {
  aspect-ratio: 16 / 9; border-radius: var(--radius-xl); overflow: hidden;
  border: 1px solid var(--glass-border); box-shadow: var(--e3);
  display: grid; place-items: center;
  background: linear-gradient(160deg, color-mix(in oklab, var(--brand-500) 22%, var(--color-muted)), color-mix(in oklab, var(--accent-400) 14%, var(--color-muted)));
}
.gallery-main img { width: 40%; max-width: 190px; filter: drop-shadow(0 20px 28px rgba(4,30,24,.3)); }
.gallery-thumbs { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 10px; margin-top: 10px; }
.gallery-thumbs button {
  aspect-ratio: 1; border-radius: var(--radius-md); overflow: hidden; cursor: pointer;
  border: 2px solid transparent; display: grid; place-items: center;
  background: var(--color-muted);
  transition: border-color var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out);
}
.gallery-thumbs button:hover { transform: translateY(-3px); }
.gallery-thumbs button[aria-current="true"] { border-color: var(--color-primary); }
.gallery-thumbs img { width: 62%; }

.info-row {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 13px 0; border-bottom: 1px solid var(--glass-hairline);
  font-size: var(--fs-sm);
}
.info-row:last-child { border-bottom: 0; }
.info-row > svg { width: 19px; height: 19px; flex: none; color: var(--color-primary); margin-top: 2px; }
.info-row .k { color: var(--color-muted-foreground); min-width: 92px; }
.info-row .v { font-weight: 600; }

.hours-table { width: 100%; font-size: var(--fs-sm); }
.hours-table td { padding: 8px 0; border-bottom: 1px solid var(--glass-hairline); }
.hours-table tr:last-child td { border-bottom: 0; }
.hours-table .d { color: var(--color-muted-foreground); }
.hours-table .h { text-align: end; font-variant-numeric: tabular-nums; font-weight: 600; }
.hours-table tr.today .d, .hours-table tr.today .h { color: var(--color-primary); font-weight: 800; }

/* Reviews */
.review { padding: var(--space-lg) 0; border-bottom: 1px solid var(--glass-hairline); }
.review:last-child { border-bottom: 0; }
.review-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.avatar {
  width: 44px; height: 44px; border-radius: 50%; flex: none;
  display: grid; place-items: center; font-weight: 800;
  background: var(--color-primary);
  color: var(--color-on-primary); box-shadow: var(--e1);
}
.review-body { margin-top: 11px; font-size: var(--fs-sm); color: var(--color-muted-foreground); }
.review-reply {
  margin-top: var(--space-md);
  margin-inline-start: var(--space-xl);
  padding: 13px 16px;
  border-radius: var(--radius-md);
  background: color-mix(in oklab, var(--color-primary) 8%, transparent);
  border: 1px solid color-mix(in oklab, var(--color-primary) 20%, transparent);
  font-size: var(--fs-sm);
}
.review-reply strong { color: var(--color-primary); display: flex; align-items: center; gap: 6px; margin-bottom: 5px; }
.review-reply strong svg { width: 15px; height: 15px; }

.rating-summary { display: flex; gap: var(--space-xl); align-items: center; flex-wrap: wrap; }
.rating-big { font-size: 3.2rem; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }
.rating-bars { flex: 1 1 220px; display: grid; gap: 7px; }
.rating-bar { display: flex; align-items: center; gap: 10px; font-size: var(--fs-xs); }
.rating-bar .track { flex: 1; height: 8px; border-radius: 4px; background: var(--color-muted); overflow: hidden; }
.rating-bar .fill { height: 100%; border-radius: 4px; background: linear-gradient(90deg, var(--accent-400), var(--accent-600)); }

.rating-input { display: flex; gap: 4px; }
.rating-input button {
  width: 44px; height: 44px; display: grid; place-items: center; cursor: pointer;
  color: var(--color-border-strong); transition: color var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out);
}
.rating-input button:hover { transform: scale(1.15); }
.rating-input button[aria-pressed="true"] { color: var(--accent-500); }
.rating-input svg { width: 26px; height: 26px; fill: currentColor; stroke: none; }

/* v158: نسخهٔ چندمعیاره — کادر تمام‌عرض + برچسب سطح کنار عنوان معیار */
.rating-box-wide { max-width: none; }
.crit-lvl { display: none; margin-inline-start: 6px; font-size: 12px; font-weight: 800;
  color: var(--accent-600, var(--accent-500)); }
.crit-lvl:not(:empty) { display: inline; }
.crit-input .row > span:first-child { font-size: 13px; font-weight: 700; }

/* v158: امتیاز داخل کادر خط‌دار — برچسب فارسی انتخاب بالای کادر و ستارهٔ
   انتخابی توپُر؛ هر ستاره خانه‌ای جدول‌مانند با لمس ۴۴px. */
.rating-box {
  border: 1.5px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  padding: 10px 12px 12px;
  max-width: 330px;
}
.rating-label {
  display: flex; align-items: center; gap: 6px;
  min-height: 22px; margin-bottom: 8px;
  font-size: 13px; font-weight: 800;
  color: var(--color-muted-foreground);
}
.rating-label.is-set { color: var(--accent-600, var(--accent-500)); }
.rating-box .rating-input { justify-content: space-between; }
.rating-box .rating-input button {
  border: 1px solid var(--color-border); border-radius: 10px;
  background: none; transition: color var(--dur-2) var(--ease-out),
  border-color var(--dur-2) var(--ease-out), background-color var(--dur-2) var(--ease-out);
}
.rating-box .rating-input button:hover { transform: none; border-color: var(--accent-400); }
.rating-box .rating-input button[aria-pressed="true"] {
  color: var(--accent-500);
  border-color: var(--accent-500);
  background: color-mix(in oklab, var(--accent-500) 10%, transparent);
}

/* Sticky sidebar */
.biz-aside { position: sticky; top: calc(var(--header-h) + 20px); display: grid; gap: var(--space-md); }
@media (max-width: 1024px) { .biz-aside { position: static; } }

/* ==========================================================================
   MAP
   ========================================================================== */
.map-layout { display: grid; gap: var(--space-lg); grid-template-columns: 330px minmax(0, 1fr); align-items: start; }
@media (max-width: 1024px) { .map-layout { grid-template-columns: 1fr; } }
.map-stage {
  position: relative; overflow: hidden;
  border-radius: var(--radius-2xl);
  border: 1px solid var(--glass-border);
  box-shadow: var(--e3);
  min-height: 560px;
  background:
    radial-gradient(70% 70% at 30% 25%, color-mix(in oklab, var(--brand-400) 22%, transparent), transparent 70%),
    linear-gradient(160deg, var(--color-muted), color-mix(in oklab, var(--brand-500) 10%, var(--color-muted)));
}
.map-stage canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.map-grid-overlay {
  position: absolute; inset: 0; pointer-events: none; opacity: .35;
  background-image:
    linear-gradient(to right, color-mix(in oklab, var(--color-primary) 18%, transparent) 1px, transparent 1px),
    linear-gradient(to bottom, color-mix(in oklab, var(--color-primary) 18%, transparent) 1px, transparent 1px);
  background-size: 56px 56px;
  mask-image: radial-gradient(70% 70% at 50% 45%, #000 40%, transparent 100%);
  -webkit-mask-image: radial-gradient(70% 70% at 50% 45%, #000 40%, transparent 100%);
}
.map-stage-head {
  position: absolute; top: 12px; left: 12px; right: auto;
  z-index: 1000;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 4px 3px 8px;
  border-radius: var(--radius-pill);
  background: color-mix(in oklab, var(--color-card) 60%, transparent);
  border: 1px solid color-mix(in oklab, var(--color-border) 50%, transparent);
  box-shadow: 0 2px 8px rgba(0,0,0,.12);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.map-head-title {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 12px; font-weight: 700;   /* v160: حداقل ۱۲px قانون موبایل */
  color: var(--color-muted-foreground);
  padding-inline-start: 4px;
}
.map-head-title svg { width: 14px; height: 14px; color: var(--color-primary); }

.map-me {
  display: inline-flex; align-items: center; gap: 5px;
  min-height: 44px; padding: 2px 14px; /* v176: لمس ≥۴۴px (قبلاً ۳۲px) */
  border-radius: var(--radius-pill);
  border: 1px solid color-mix(in oklab, var(--color-primary) 30%, transparent);
  cursor: pointer;
  background: var(--color-primary);
  color: var(--color-on-primary);
  font-weight: 700; font-size: 12px;
  box-shadow: 0 1px 4px rgba(0,0,0,.18);
  transition: all var(--dur-2) var(--ease-out);
}
.map-me svg { width: 14px; height: 14px; }
.map-me:hover { opacity: .92; transform: translateY(-1px); }
.map-me.is-busy { opacity: .6; pointer-events: none; }
.map-me.is-on { background: var(--color-success); border-color: var(--color-success); color: var(--color-on-success); }

.leaflet-control-attribution { display: none !important; }

.leaflet-top.leaflet-right {
  top: 12px !important;
  right: 12px !important;
  left: auto !important;
  z-index: 1000 !important;
}
.leaflet-control-zoom {
  border: 1px solid var(--color-border) !important;
  border-radius: var(--radius-md) !important;
  box-shadow: var(--e3) !important;
  overflow: hidden;
  margin: 0 !important;
}
.leaflet-control-zoom a {
  background: var(--color-card) !important;
  color: var(--color-foreground) !important;
  width: 44px !important;
  height: 44px !important;
  line-height: 44px !important;
  font-size: 18px !important;
  font-weight: 800 !important;
  border-bottom: 1px solid var(--color-border) !important;
  transition: background var(--dur-2) var(--ease-out);
}
.leaflet-control-zoom a:hover {
  background: var(--color-muted) !important;
}
.map-list { display: grid; gap: 10px; max-height: 620px; overflow-y: auto; padding-inline-end: 4px; }
.map-item {
  display: flex; gap: 12px; align-items: center;
  padding: 12px; border-radius: var(--radius-md);
  background: var(--glass-bg); border: 1px solid var(--glass-hairline);
  cursor: pointer; transition: all var(--dur-2) var(--ease-out);
}
.map-item:hover { transform: translateX(-4px); box-shadow: var(--e2); border-color: var(--color-primary); }
.map-item img { width: 42px; height: 42px; flex: none; }
.map-item-dot {
  flex: none; width: 36px; height: 36px; border-radius: 50%;
  display: grid; place-items: center;
  background: color-mix(in oklab, var(--color-primary) 12%, transparent);
  color: var(--color-primary-text);
}
.map-item-dot svg { width: 18px; height: 18px; }
.map-item-dist {
  flex: none; font-size: var(--fs-xs); font-weight: 700;
  color: var(--color-primary-text);
  background: color-mix(in oklab, var(--color-primary) 10%, transparent);
  padding: 2px 8px; border-radius: 999px; white-space: nowrap;
}
.map-item .t { font-weight: 700; font-size: var(--fs-sm); }
.map-item .s { font-size: var(--fs-xs); color: var(--color-muted-foreground); }
.map-item-copy { flex: 1; min-width: 0; text-align: start; display: grid; gap: 2px; }
.map-item-copy strong { font-size: var(--fs-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.map-item-meta { color: var(--color-muted-foreground); font-size: var(--fs-xs); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.map-item-chevron { flex: none; font-size: 24px; line-height: 1; color: var(--color-muted-foreground); }
.map-list-note { padding: 10px 12px; text-align: center; border-top: 1px dashed var(--color-border); }
.bz-map-tooltip {
  border: 0 !important; border-radius: 9px !important;
  background: var(--color-card) !important; color: var(--color-foreground) !important;
  box-shadow: var(--e2) !important; font-family: inherit !important;
  font-weight: 750; direction: rtl;
}
.bz-map-tooltip::before { border-top-color: var(--color-card) !important; }

/* ==========================================================================
   PRICING
   ========================================================================== */
.price-grid { display: grid; gap: var(--space-lg); grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); align-items: start; }
.price-card {
  position: relative; padding: var(--space-xl);
  border-radius: var(--radius-2xl);
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur)); backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--glass-border);
  box-shadow: var(--e2), var(--e-inset-top);
  transition: box-shadow var(--dur-3) var(--ease-out), border-color var(--dur-3) var(--ease-out);
}
.price-card:hover { box-shadow: var(--e4); }
.price-card.popular {
  border-color: color-mix(in oklab, var(--color-primary) 45%, transparent);
  box-shadow: var(--e-glow), var(--e3);
}
.price-card.popular::before {
  content: 'محبوب‌ترین';
  position: absolute; top: -13px; inset-inline-start: 50%; transform: translateX(50%);
  padding: 5px 18px; border-radius: var(--radius-pill);
  background: var(--color-primary);
  color: var(--color-on-primary); font-size: var(--fs-xs); font-weight: 800;
  box-shadow: 0 6px 18px rgba(234,88,12,.36); white-space: nowrap;
}
.price-name { font-size: var(--fs-xl); font-weight: 800; }
.price-desc { color: var(--color-muted-foreground); font-size: var(--fs-sm); margin-top: 5px; }
.price-amount { margin: var(--space-lg) 0; display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; }
.price-amount .n { font-size: var(--fs-3xl); font-weight: 800; font-variant-numeric: tabular-nums; }
.price-amount .u { font-size: var(--fs-sm); color: var(--color-muted-foreground); }
.price-feats { display: grid; gap: 11px; margin: var(--space-lg) 0; }
.price-feat { display: flex; align-items: flex-start; gap: 10px; font-size: var(--fs-sm); }
.price-feat svg { width: 19px; height: 19px; flex: none; margin-top: 1px; }
.price-feat.yes svg { color: var(--color-success); }
.price-feat.no { color: var(--color-muted-foreground); }
.price-feat.no svg { color: var(--color-border-strong); }

/* جدول مقایسهٔ پلن‌ها — اسکرول افقی روی موبایل، بدون بریدن صفحه */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.compare-table {
  width: 100%; min-width: 560px; border-collapse: collapse;
  font-size: var(--fs-sm); text-align: center;
}
.compare-table th, .compare-table td {
  padding: 12px 14px; border-bottom: 1px solid var(--color-border);
}
.compare-table thead th {
  font-size: var(--fs-md); font-weight: 800; color: var(--color-primary);
  background: var(--color-secondary); white-space: nowrap;
}
.compare-table thead th:first-child,
.compare-table tbody th { text-align: start; font-weight: 700; color: var(--color-foreground); }
.compare-table tbody th { background: var(--color-background-2); white-space: nowrap; }
.compare-table tbody tr:last-child td, .compare-table tbody tr:last-child th { border-bottom: none; }

.subscribe-grid {
  display: grid; gap: var(--space-lg);
  grid-template-columns: minmax(0, 1fr) minmax(0, 380px);
  align-items: start;
}
@media (max-width: 860px) {
  .subscribe-grid {
    grid-template-columns: 1fr;
    gap: var(--space-md);
  }
}

/* ==========================================================================
   AUTH
   ========================================================================== */
.auth-wrap { display: grid; place-items: center; min-height: calc(100dvh - var(--header-h) - 90px); padding-block: var(--space-2xl); }
.auth-card { width: min(100%, 470px); padding: var(--space-2xl); border-radius: var(--radius-2xl); }
.auth-head { text-align: center; margin-bottom: var(--space-xl); }
.auth-head .mark {
  width: 62px; height: 62px; margin: 0 auto var(--space-md);
  border-radius: var(--radius-lg); display: grid; place-items: center;
  background: var(--color-primary);
  color: var(--color-on-primary); box-shadow: var(--e3);
}
.auth-head .mark svg { width: 30px; height: 30px; }
.auth-head h1 { font-size: var(--fs-2xl); }
.auth-head p { color: var(--color-muted-foreground); margin-top: 7px; font-size: var(--fs-sm); }
.auth-foot { text-align: center; margin-top: var(--space-lg); font-size: var(--fs-sm); color: var(--color-muted-foreground); }
.auth-foot a {
  color: var(--color-primary); font-weight: 700;
  display: inline-flex; align-items: center; min-height: var(--tap); padding-inline: 4px;
}
/* standalone auth links (forgot password) need a real hit area too */
.auth-card .between > a {
  display: inline-flex; align-items: center; min-height: var(--tap); padding-inline: 4px;
  border-radius: var(--radius-xs);
}

/* ==========================================================================
   PANEL / ADMIN
   ========================================================================== */
.panel-layout { display: grid; gap: var(--space-lg); grid-template-columns: minmax(0, 286px) minmax(0, 1fr); align-items: start; padding-block: var(--space-xl); min-width: 0; }
.panel-layout > * { min-width: 0; }
@media (max-width: 1024px) { .panel-layout { grid-template-columns: 1fr; } }

.panel-side {
  position: sticky; top: calc(var(--header-h) + 16px);
  padding: var(--space-lg); border-radius: var(--radius-xl);
  /* v134: this sidebar is the panel's only desktop menu. It used to be the
     tallest item in its grid row, so `sticky` had no room to travel and the
     whole menu scrolled away with the page (looked like «منو برداشته شد»).
     Cap it to the viewport and let its long link list scroll internally, so
     the menu stays visible the entire way down the page. */
  max-height: calc(100dvh - var(--header-h) - 32px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* v134: on desktop the sidebar must NEVER scroll away. `sticky` is bounded
   by its grid row (the content column), so it would still leave the screen
   once you scrolled past the content into the footer. `fixed` pins it to the
   viewport for the whole page; the grid keeps an empty 262px column so the
   content stays exactly where it was. The inline-start offset mirrors the
   centered .container-wide so the sidebar lines up with that column. */
@media (min-width: 1025px) {
  .panel-side {
    position: fixed;
    inset-inline-start: max(var(--space-lg), calc((100vw - var(--container-wide)) / 2));
    width: 286px;
  }
  .panel-main-content { grid-column: 2; }
}
@media (max-width: 1024px) {
  .panel-side { position: static; max-height: none; overflow-y: visible; }
}
.panel-side-head { display: flex; align-items: center; gap: 12px; padding-bottom: var(--space-md); border-bottom: 1px solid var(--glass-hairline); margin-bottom: var(--space-md); }
.panel-side-head strong { display: block; font-size: var(--fs-sm); }
.panel-side-head small { font-size: var(--fs-xs); }
.panel-nav { display: grid; gap: 3px; }
.panel-nav a {
  display: flex; align-items: center; gap: 11px;
  padding: 11px 13px; border-radius: var(--radius-md);
  font-size: var(--fs-sm); font-weight: 600; min-height: 46px;
  color: var(--color-muted-foreground);
  transition: all var(--dur-2) var(--ease-out);
}
.panel-nav a:hover { background: var(--color-muted); color: var(--color-foreground); }
.panel-nav a[aria-current="page"] {
  background: var(--color-primary);
  color: var(--color-on-primary); box-shadow: var(--e2);
}
.panel-nav a svg { width: 19px; height: 19px; flex: none; }
.panel-logout { display: flex; align-items: center; gap: 11px; padding: 11px 13px; border-radius: var(--radius-md); font-size: var(--fs-sm); font-weight: 600; color: var(--color-destructive); min-height: 46px; transition: background-color var(--dur-2) var(--ease-out); }
.panel-logout:hover { background: color-mix(in oklab, var(--color-destructive) 10%, transparent); }
.panel-logout svg { width: 19px; height: 19px; }

.panel-head { margin-bottom: var(--space-lg); }
.panel-head h1 { font-size: var(--fs-2xl); }
.panel-head p { color: var(--color-muted-foreground); margin-top: 5px; font-size: var(--fs-sm); }
.panel-context-bar {
  display: grid; grid-template-columns: minmax(220px, auto) minmax(0, 1fr);
  align-items: center; gap: 12px;
  margin-top: var(--space-md); padding: 10px;
  border-radius: var(--radius-lg); border: 1px solid var(--glass-border);
  background: color-mix(in oklab, var(--color-surface) 78%, transparent);
}
.panel-context-current {
  display: flex; align-items: center; gap: 8px;
  min-height: 40px; padding-inline: 8px; white-space: nowrap;
  color: var(--color-muted-foreground); font-size: var(--fs-xs); font-weight: 800;
}
.panel-context-current svg { width: 18px; height: 18px; color: var(--color-primary); }
.panel-context-current strong { color: var(--color-foreground); font-size: var(--fs-sm); }
.panel-context-links {
  display: flex; align-items: center; gap: 8px;
  overflow-x: auto; scrollbar-width: thin; padding-bottom: 2px;
}
.panel-context-link {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  min-height: 40px; padding: 7px 11px; border-radius: var(--radius-pill);
  border: 1px solid var(--color-border); background: var(--color-background);
  color: var(--color-muted-foreground); font-size: var(--fs-xs); font-weight: 800;
}
.panel-context-link:hover { color: var(--color-foreground); border-color: color-mix(in oklab, var(--color-primary) 28%, var(--color-border)); }
.panel-context-link.is-active {
  background: var(--color-primary); color: var(--color-on-primary); border-color: var(--color-primary);
}
.panel-context-link svg { width: 16px; height: 16px; flex: none; }
@media (max-width: 760px) {
  .panel-context-bar { grid-template-columns: 1fr; gap: 8px; }
  .panel-context-current { white-space: normal; }
}

/* Panel Mobile Quick Bar */
.panel-mob-quick-bar {
  display: flex; gap: 8px; overflow-x: auto; padding-block: 4px 6px;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.panel-mob-quick-bar::-webkit-scrollbar { display: none; }
.panel-mob-quick-bar .chip {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  min-height: 44px; padding: 6px 13px; border-radius: var(--radius-pill);
  font-size: var(--fs-xs); font-weight: 700; text-decoration: none;
  background: var(--color-surface); border: 1px solid var(--color-border);
  color: var(--color-foreground); transition: all var(--dur-2) var(--ease-out);
}
.panel-mob-quick-bar .chip.is-active {
  background: var(--color-primary); color: var(--color-on-primary);
  border-color: var(--color-primary);
}

/* Panel Drawer Modal (Mobile) */
.panel-drawer-backdrop {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(0, 0, 0, 0.65);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  display: flex; justify-content: flex-end;
}
/* `display:flex` above beats the UA rule `[hidden]{display:none}`, which left
   the drawer permanently open (two side menus on screen, and the close button
   seemingly doing nothing). This restores the `hidden` attribute. */
.panel-drawer-backdrop[hidden] { display: none !important; }
.panel-drawer-box {
  width: min(85vw, 340px); height: 100%;
  background: var(--color-background); border-inline-start: 1px solid var(--glass-border);
  box-shadow: var(--e4); display: flex; flex-direction: column;
  overflow: hidden; animation: slideDrawer .25s var(--ease-out);
}
@keyframes slideDrawer {
  from { transform: translateX(-100%); }
  to { transform: translateX(0); }
}
.panel-drawer-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 18px; border-bottom: 1px solid var(--glass-border);
  flex: none;
}
.panel-drawer-body {
  flex: 1; overflow-y: auto; padding: 14px 16px; -webkit-overflow-scrolling: touch;
}
.panel-drawer-open { overflow: hidden; }

/* The admin panel has exactly ONE menu per breakpoint:
   - Desktop (≥1025px): the sticky sidebar (above).
   - Mobile/tablet (≤1024px): the header hamburger AND the «بخش‌های پنل»
     button both open the SAME `#panel-drawer` — one drawer, two ways to
     reach it. The hamburger must NOT open the site's own `.mobile-nav` on
     admin pages (that second drawer was the original «two menus» bug), which
     is why app.js skips it under `body.page-admin` and PANEL_UX_JS takes
     over instead. */
@media (min-width: 1025px) {
  body.page-admin .site-header .nav-toggle { display: none !important; }
}
@media (max-width: 1024px) {
  body.page-admin .site-header .nav-toggle { display: inline-grid !important; }
}

/* While the drawer (or the Cmd+K palette) is open, lift `.main-content` out of
   its stacking context (z-index: 10). A `position:fixed` overlay inside it is
   otherwise capped at 10, so the sticky site header (z-index: 200) paints on
   top of it and covers the drawer's close button. */
body.panel-drawer-open .main-content { z-index: auto; }
body:has(.cmdk:not([hidden])) .main-content { z-index: auto; }

/* The desktop panel keeps its sticky sidebar, so the mobile drawer trigger and
   the quick chip bar are redundant there. (`.show-mobile` has no global
   definition; these two are the only users, and the panel's mobile breakpoint
   is 1024px — the same one that hides the sidebar.) */
@media (min-width: 1025px) {
  .panel-head [data-panel-drawer-open],
  .panel-mob-quick-bar { display: none !important; }
}

/* Panel Business Mobile Card & Quick Actions */
.panel-biz-card {
  padding: 14px 16px; border-radius: var(--radius-lg);
  background: var(--glass-bg); border: 1px solid var(--glass-border);
  margin-bottom: 12px; display: flex; flex-direction: column; gap: 10px;
}
.panel-biz-actions {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 4px;
}

/* Chart (pure CSS/SVG, no library) */
.chart-card { padding: var(--space-lg); border-radius: var(--radius-xl); }
.bar-chart { display: flex; align-items: flex-end; gap: 10px; height: 210px; padding-top: var(--space-md); }
.bar-col { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 8px; height: 100%; justify-content: flex-end; }
.bar {
  width: 100%; max-width: 42px; border-radius: 7px 7px 3px 3px;
  background: linear-gradient(180deg, var(--brand-400), var(--brand-700));
  position: relative; min-height: 4px;
  transition: filter var(--dur-2) var(--ease-out);
  animation: barGrow .8s var(--ease-out) both;
}
.bar:hover { filter: brightness(1.15); }
.bar.alt { background: linear-gradient(180deg, var(--accent-400), var(--accent-700)); }
@keyframes barGrow { from { transform: scaleY(0); transform-origin: bottom } to { transform: scaleY(1) } }
@media (prefers-reduced-motion: reduce) { .bar { animation: none; } }
.bar-label { font-size: var(--fs-xs); color: var(--color-muted-foreground); white-space: nowrap; }
.bar-value { font-size: var(--fs-xs); font-weight: 800; font-variant-numeric: tabular-nums; }

.donut-wrap { display: flex; align-items: center; gap: var(--space-xl); flex-wrap: wrap; justify-content: center; }
.donut { width: 178px; height: 178px; flex: none; transform: rotate(-90deg); }
.donut circle { fill: none; stroke-width: 20; stroke-linecap: round; }
.donut-legend { display: grid; gap: 9px; font-size: var(--fs-sm); }
.donut-legend .row { display: flex; align-items: center; gap: 9px; }
.donut-legend .swatch { width: 13px; height: 13px; border-radius: 4px; flex: none; }

/* Color picker row (admin settings) */
.color-row { display: flex; align-items: center; gap: 12px; padding: 11px 0; border-bottom: 1px solid var(--glass-hairline); }
.color-row:last-child { border-bottom: 0; }
.color-row input[type="color"] { width: 52px; height: 40px; border: 1px solid var(--color-border); border-radius: var(--radius-sm); cursor: pointer; background: none; padding: 3px; }
.color-row .meta { flex: 1; }
.color-row .meta strong { display: block; font-size: var(--fs-sm); }
.color-row .meta small { color: var(--color-muted-foreground); font-size: var(--fs-xs); }
.color-row code { font-size: var(--fs-xs); background: var(--color-muted); padding: 4px 9px; border-radius: var(--radius-xs); font-family: ui-monospace, monospace; }

/* Timeline (backup page) */
.timeline { display: grid; gap: 0; position: relative; padding-inline-start: 26px; }
.timeline::before { content: ''; position: absolute; inset-block: 8px; inset-inline-start: 6px; width: 2px; background: var(--color-border); }
.tl-item { position: relative; padding: 12px 0; }
.tl-item::before {
  content: ''; position: absolute; inset-inline-start: -24px; top: 18px;
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--color-primary); box-shadow: 0 0 0 4px color-mix(in oklab, var(--color-primary) 18%, transparent);
}
.tl-item .t { font-weight: 700; font-size: var(--fs-sm); }
.tl-item .s { font-size: var(--fs-xs); color: var(--color-muted-foreground); }

/* Prose (about / rules) */
.prose { max-width: 74ch; }
.prose h2 { font-size: var(--fs-xl); margin-top: var(--space-2xl); margin-bottom: var(--space-sm); }
.prose h3 { font-size: var(--fs-lg); margin-top: var(--space-xl); margin-bottom: var(--space-xs); }
.prose p { color: var(--color-muted-foreground); margin-bottom: var(--space-md); }
.prose ul { display: grid; gap: 9px; margin-bottom: var(--space-md); }
.prose ul li { display: flex; gap: 10px; align-items: flex-start; color: var(--color-muted-foreground); font-size: var(--fs-sm); }
.prose ul li svg { width: 18px; height: 18px; flex: none; margin-top: 3px; color: var(--color-primary); }
.prose ol { counter-reset: n; display: grid; gap: 11px; }
.prose ol li { counter-increment: n; display: flex; gap: 12px; align-items: flex-start; color: var(--color-muted-foreground); font-size: var(--fs-sm); }
.prose ol li::before {
  content: counter(n); flex: none;
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  background: color-mix(in oklab, var(--color-primary) 14%, transparent);
  color: var(--color-primary); font-weight: 800; font-size: var(--fs-xs);
}

/* Contact split */
.contact-grid { display: grid; gap: var(--space-xl); grid-template-columns: minmax(0, 1fr) 360px; align-items: start; }
@media (max-width: 900px) { .contact-grid { grid-template-columns: 1fr; } }

/* ==========================================================================
   v2 — favourites, offers, panel extras, map providers
   ========================================================================== */

/* Favourite heart on cards */
.fav-btn {
  position: absolute; top: 12px; inset-inline-end: 12px; z-index: 3;
  width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border: 1px solid var(--glass-border);
  color: var(--color-muted-foreground);
  box-shadow: var(--e1);
  transition: all var(--dur-2) var(--ease-out);
}
.fav-btn:hover { transform: scale(1.1); color: var(--color-destructive); }
.fav-btn svg { width: 20px; height: 20px; }
/* One visual contract for every favourite heart: the GLYPH itself becomes
   filled red (not a white heart on a red disk), exactly matching its state. */
[data-fav][aria-pressed="true"],
.fav-btn.is-on {
  color: var(--color-destructive) !important;
  background: color-mix(in oklab, var(--color-destructive) 13%, var(--color-card)) !important;
  border-color: color-mix(in oklab, var(--color-destructive) 45%, transparent) !important;
}
[data-fav][aria-pressed="true"] svg,
.fav-btn.is-on svg { fill: currentColor; stroke: currentColor; }
[data-fav][aria-busy="true"] { opacity: .68; cursor: wait; }
.favorite-link.has-favorites { color: var(--color-destructive) !important; }
.favorite-link.has-favorites svg { fill: currentColor; stroke: currentColor; }

.fav-dot {
  position: absolute; top: 4px; inset-inline-end: 4px;
  min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: var(--radius-pill);
  background: var(--color-accent); color: var(--color-on-primary);
  font-size: 12px; font-weight: 800; line-height: 17px; text-align: center;
}
.header-actions .btn-icon { position: relative; }

/* Offer cards */
.offer-card {
  position: relative; display: flex; align-items: center; gap: var(--space-md);
  padding: var(--space-lg); border-radius: var(--radius-xl);
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur)); backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--glass-border);
  box-shadow: var(--e2), var(--e-inset-top);
  transition: box-shadow var(--dur-3) var(--ease-out);
}
.offer-card:hover { box-shadow: var(--e4); }
.offer-pct {
  width: 68px; height: 68px; flex: none;
  display: grid; place-items: center; border-radius: var(--radius-lg);
  background: linear-gradient(155deg, var(--accent-500), var(--accent-700));
  color: #fff; font-size: 1.5rem; font-weight: 800; line-height: 1;
  font-variant-numeric: tabular-nums;
  box-shadow: var(--e3);
}
.offer-pct small { font-size: .8rem; font-weight: 700; }
.offer-code {
  display: inline-block; margin-top: 8px;
  padding: 6px 14px; border-radius: var(--radius-sm);
  background: var(--color-muted); border: 1px dashed var(--color-border-strong);
  font-family: ui-monospace, monospace; font-size: var(--fs-sm); font-weight: 700;
  cursor: pointer; letter-spacing: .06em;
  transition: all var(--dur-2) var(--ease-out);
}
.offer-code:hover { background: var(--color-primary); color: var(--color-on-primary); border-style: solid; }

/* Owner panel: to-do list */
.todo-list { display: grid; gap: 8px; }
.todo-item {
  display: flex; align-items: center; gap: 11px;
  padding: 13px 15px; border-radius: var(--radius-md);
  background: color-mix(in oklab, var(--color-warning) 10%, transparent);
  border: 1px solid color-mix(in oklab, var(--color-warning) 26%, transparent);
  font-size: var(--fs-sm); font-weight: 600; min-height: 48px;
  transition: transform var(--dur-2) var(--ease-out);
}
.todo-item:hover { transform: translateX(-4px); }
.todo-item svg { width: 18px; height: 18px; flex: none; color: var(--color-warning); }
.todo-item svg:last-child { margin-inline-start: auto; color: var(--color-muted-foreground); }

/* v153: اعلان‌ها (زنگوله) — بازسازی کامل ردیف‌ها برای موبایل: عنوان/متن/زمان
   هرکدام در سطر خودشان با display صریح (بدون تکیه بر رفتار مرورگر)، شکستن
   واژه‌های بلند، کف لمسی ۴۸px و کف متن ۱۲px (قبلاً ۱۱٫۵px بود). جایگزین v152. */
.notif-list .todo-item {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 14px; border-radius: var(--radius-md);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  font-weight: 400; min-height: 48px;
}
.notif-list .todo-item > svg:first-child { flex: none; width: 20px; height: 20px; margin-top: 2px; }
.notif-list .todo-item > span { display: block; flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.notif-list .todo-item strong { display: block; margin-bottom: 3px; overflow-wrap: anywhere; }
.notif-list .todo-item small:not(.time) {
  display: block; font-weight: 400; line-height: 1.7; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.notif-list .todo-item small.time {
  display: inline-block; margin-top: 6px; padding: 2px 10px; border-radius: 999px;
  font-size: 12px; line-height: 1.7; white-space: nowrap;
  background: color-mix(in oklab, var(--color-muted-foreground) 9%, transparent);
  color: var(--color-muted-foreground);
}
.notif-list .todo-item > svg:last-child { flex: none; margin-top: 2px; align-self: center; }
.notif-list .todo-item:hover { transform: none; }
/* خوانده‌نشده: هایلایت روشن‌تر از ردیف عادی — در همین فایل تکرار می‌شود تا
   ترتیب لود main→pages قاعدهٔ is-unread را خنثی نکند (تلهٔ شناخته‌شده) */
.notif-list .todo-item.is-unread {
  background: color-mix(in oklab, var(--color-primary) 9%, var(--color-surface));
  border-color: color-mix(in oklab, var(--color-primary) 30%, var(--color-border));
}
.notif-list .todo-item.is-unread strong { color: var(--color-primary); }

/* v158: ردیف استاندارد اندرویدی سوییچ تنظیم اعلان‌ها — عنوان و توضیح دو سطر
   جدا (قبلاً آیکون/عنوان/توضیح در یک جریان درهم می‌ریخت)، سوییچ انتهای ردیف،
   لمسِ تمام‌ردیف، جداکنندهٔ نازک بین ردیف‌ها. */
.switch-row {
  display: flex; align-items: center; gap: 12px;
  width: 100%; padding: 11px 2px; min-height: 56px;
  cursor: pointer; position: relative;
}
.switch-row + .switch-row { border-top: 1px solid var(--color-border); }
.switch-row .sw-copy { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.switch-row .sw-copy strong {
  display: flex; align-items: center; gap: 7px;
  font-size: 14px; line-height: 1.45;
}
.switch-row .sw-copy strong svg { flex: none; width: 18px; height: 18px; }
.switch-row .sw-copy small {
  display: block; font-size: 12px; line-height: 1.7;
  color: var(--color-muted-foreground); overflow-wrap: anywhere;
}

/* Owner panel: hours editor */
.hours-grid { display: grid; gap: 10px; }
.hours-row {
  display: grid; gap: 10px; align-items: center;
  grid-template-columns: 110px 1fr 1fr auto;
}
@media (max-width: 700px) {
  .hours-row { grid-template-columns: 1fr 1fr; }
  .hours-row > span:first-child { grid-column: 1 / -1; }
}
.hours-row .input { min-height: 44px; }

/* Icon preview in the category form */
.icon-preview {
  display: grid; place-items: center; padding: var(--space-md);
  border-radius: var(--radius-md);
  background: linear-gradient(160deg,
      color-mix(in oklab, var(--color-primary) 16%, var(--color-muted)),
      color-mix(in oklab, var(--color-accent) 10%, var(--color-muted)));
  border: 1px solid var(--glass-border);
}
.icon-preview img { filter: drop-shadow(0 8px 14px rgba(4,30,24,.26)); }
[data-icon-picker] .icon-search { margin-bottom: 6px; }
[data-icon-picker] [data-icon-search-status] { min-height: 20px; margin-bottom: 8px; }
[data-icon-select].is-searching {
  min-height: 112px;
  padding-block: 4px;
  overflow-y: auto;
}
[data-icon-select].is-searching option {
  padding: 10px 12px;
  border-radius: 8px;
}
@media (max-width: 600px) {
  [data-icon-select].is-searching { min-height: 176px; }
  [data-icon-select].is-searching option { padding-block: 12px; }
}

/* Map wrapper states */
[data-map-wrap] { position: relative; }
[data-map-wrap] [data-map-canvas] { border-radius: inherit; overflow: hidden; }
[data-map-wrap][data-map="pending"] [data-map-canvas]::after {
  content: 'در حال بارگذاری نقشه…';
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: var(--fs-sm); color: var(--color-muted-foreground);
}
/* Leaflet + Google inherit the page font */
.leaflet-container { font-family: var(--font-sans) !important; }
.leaflet-popup-content { font-family: var(--font-sans); direction: rtl; text-align: right; }
.gm-style, .gm-style * { font-family: var(--font-sans) !important; }
.map-stage .leaflet-container { background: transparent; }

/* Chips as links */
a.chip { text-decoration: none; }
a.chip.is-active {
  background: var(--color-primary);
  color: var(--color-on-primary); border-color: transparent; box-shadow: var(--e-glow);
}

/* Panel side extra link hover */
.panel-nav-extra:hover { background: var(--color-muted); }

/* ==========================================================================
   v3 — catalog, uploads, owner area
   ========================================================================== */

/* ---------- catalog item cards ---------- */
.item-grid {
  display: grid; gap: var(--space-md);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr));
}
.item-grid.lg { grid-template-columns: repeat(auto-fill, minmax(min(100%, 270px), 1fr)); }

.item-card { overflow: hidden; }
.item-media {
  position: relative; aspect-ratio: 4 / 3; overflow: hidden;
  display: grid; place-items: center;
  background:
    radial-gradient(70% 90% at 50% 12%, color-mix(in oklab, var(--brand-300) 34%, transparent), transparent 72%),
    linear-gradient(160deg, color-mix(in oklab, var(--brand-500) 18%, var(--color-muted)),
                            color-mix(in oklab, var(--accent-400) 12%, var(--color-muted)));
}
/* v111: luxury night-only media removed; base token rule serves both themes. */
.item-media img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--dur-5) var(--ease-out); }
.item-card:hover .item-media img { transform: scale(1.06); }
.item-ph { display: grid; place-items: center; color: color-mix(in oklab, var(--color-primary) 55%, transparent); }
.item-ph svg { width: 54px; height: 54px; }

.item-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-sm); flex-wrap: wrap;
  margin-top: var(--space-md); padding-top: var(--space-md);
  border-top: 1px solid var(--glass-hairline);
}
.item-price { font-size: var(--fs-base); color: var(--color-primary-text); font-weight: 800; }
.item-card .card-desc { -webkit-line-clamp: 2; line-clamp: 2; }
.item-media-link { position:absolute; inset:0; display:grid; place-items:center; color:inherit; }
.item-detail-grid { display:grid; grid-template-columns:minmax(0,1fr) minmax(320px,.9fr); gap:var(--space-lg); align-items:start; }
.item-detail-media { min-height:420px; display:grid; place-items:center; overflow:hidden; border-radius:26px; background:linear-gradient(145deg,var(--color-card),var(--color-background)); border:1px solid var(--glass-border); }
.item-detail-media img { width:100%; height:100%; max-height:620px; object-fit:contain; }
.item-detail-copy { position:sticky; top:calc(var(--header-h) + 16px); }
.item-detail-copy h1 { font-size:var(--fs-3xl); margin:12px 0; }
.item-detail-copy p { color:var(--color-muted-foreground); line-height:1.8; }
.item-detail-price { font-size:var(--fs-2xl); color:var(--color-primary); font-weight:900; margin:16px 0; }
.item-store-link { display:flex; align-items:center; gap:9px; min-height:48px; padding:10px 12px; margin:14px 0; border-radius:14px; background:color-mix(in oklab,var(--color-primary) 9%,transparent); border:1px solid color-mix(in oklab,var(--color-primary) 22%,transparent); }
.item-store-link span { flex:1; }
.item-store-link svg { width:19px; height:19px; }
.item-specs { display:grid; gap:6px; margin:14px 0; }
.item-buy { display:grid; grid-template-columns:auto 86px minmax(0,1fr); align-items:end; gap:9px; margin-top:16px; }
.item-buy label { font-size:12px; color:var(--color-muted-foreground); grid-column:1/3; }
.item-qty { background:var(--color-card) !important; color:var(--color-foreground) !important; border-color:color-mix(in oklab, var(--color-primary) 30%, transparent) !important; text-align:center; font-size:16px !important; }
@media(max-width:768px){.item-detail-grid{grid-template-columns:1fr}.item-detail-media{min-height:280px}.item-detail-copy{position:static}.item-buy{grid-template-columns:82px minmax(0,1fr)}.item-buy label{grid-column:1/-1}}

.item-img-current {
  display: flex; align-items: center; gap: var(--space-md);
  margin-bottom: var(--space-md);
}
.item-img-current img { border-radius: var(--radius-md); object-fit: cover; box-shadow: var(--e2); }

/* ---------- upload drop zone ---------- */
.drop-zone {
  display: grid; place-items: center; gap: 6px; text-align: center;
  padding: var(--space-2xl) var(--space-lg);
  border: 2px dashed var(--color-border-strong);
  border-radius: var(--radius-lg);
  background: var(--glass-bg-weak);
  cursor: pointer; min-height: 150px;
  transition: all var(--dur-2) var(--ease-out);
}
.drop-zone:hover, .drop-zone.is-over {
  border-color: var(--color-primary);
  background: color-mix(in oklab, var(--color-primary) 8%, transparent);
}
.drop-zone.is-busy { opacity: .6; pointer-events: none; }
.dz-icon { display: grid; place-items: center; color: var(--color-primary); }
.dz-icon svg { width: 34px; height: 34px; }

.dz-preview {
  display: grid; gap: 10px; margin-top: var(--space-md);
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
}
.dz-thumb { position: relative; border-radius: var(--radius-md); overflow: hidden; box-shadow: var(--e2); }
.dz-thumb img { width: 100%; aspect-ratio: 1; object-fit: cover; display: block; }
.dz-thumb figcaption {
  font-size: 12px; padding: 5px 7px; text-align: center;
  background: var(--color-muted); color: var(--color-muted-foreground);
}
.dz-thumb .btn-icon {
  position: absolute; top: 5px; inset-inline-end: 5px;
  width: 28px; height: 28px; min-height: 28px; min-width: 28px;
  border-radius: 50%; background: rgba(0,0,0,.6); color: #fff; font-size: 14px;
}

/* ---------- gallery manager ---------- */
.gal-grid {
  display: grid; gap: var(--space-md);
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
.gal-item { position: relative; border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--e2); }
.gal-item img { width: 100%; aspect-ratio: 1; object-fit: cover; display: block; }
.gal-actions {
  position: absolute; top: 8px; inset-inline: 8px;
  display: flex; gap: 6px; justify-content: space-between; align-items: flex-start;
}
.gal-actions .btn-icon {
  width: var(--tap); height: var(--tap); min-height: var(--tap); min-width: var(--tap);
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border: 1px solid var(--glass-border); border-radius: 50%;
}

/* ---------- claim rows ---------- */
.claim-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-md); flex-wrap: wrap;
  padding: 14px 0; border-bottom: 1px solid var(--glass-hairline);
}
.claim-row:last-child { border-bottom: 0; }

/* ---------- OTP input ---------- */
.otp-input {
  text-align: center; font-size: 1.9rem; font-weight: 800;
  letter-spacing: .55em; padding-inline-start: .55em;
  font-variant-numeric: tabular-nums;
}

/* v113: price sparkline colour comes from the theme tokens. */
.spark.down { color: var(--color-success-text); }
.spark.up   { color: var(--color-danger-text); }
/* ---------- sparkline (owner stats) ---------- */
.sparkline {
  display: flex; align-items: flex-end; gap: 3px;
  height: 130px; padding-top: var(--space-md);
}
.spark-col { flex: 1; display: flex; align-items: flex-end; height: 100%; }
.spark-bar {
  width: 100%; border-radius: 3px 3px 1px 1px;
  background: linear-gradient(180deg, var(--brand-400), var(--brand-700));
  transition: filter var(--dur-2) var(--ease-out);
}
.spark-col:hover .spark-bar { filter: brightness(1.25); }

/* real uploaded photos */
.biz-thumb.has-photo { padding: 0; }
.biz-cover { width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform var(--dur-5) var(--ease-out); }
.card-hover:hover .biz-cover { transform: scale(1.06); }
.biz-hero .art.photo { width: 160px; height: 160px; border-radius: var(--radius-xl);
  object-fit: cover; box-shadow: var(--e3); filter: none; }
.gallery-main.photo { background: var(--color-muted); }
.gallery-main.photo img { width: 100%; height: 100%; max-width: none; object-fit: cover; filter: none; }
.gallery-thumbs img { width: 100%; height: 100%; object-fit: cover; }

/* ==========================================================================
   Moderation queue — approving submitted businesses
   ========================================================================== */
.pending-box {
  border-color: color-mix(in oklab, var(--color-warning) 40%, transparent);
  box-shadow: var(--e3), 0 0 0 1px color-mix(in oklab, var(--color-warning) 22%, transparent);
}
.pending-list { display: grid; gap: var(--space-md); }
.pending-card {
  display: grid; gap: var(--space-md);
  grid-template-columns: minmax(0, 1fr) 210px;
  align-items: start;
  padding: var(--space-lg);
  border-radius: var(--radius-lg);
  background: color-mix(in oklab, var(--color-warning) 7%, transparent);
  border: 1px solid color-mix(in oklab, var(--color-warning) 24%, transparent);
}
@media (max-width: 760px) { .pending-card { grid-template-columns: 1fr; } }
.pending-main strong { font-size: var(--fs-lg); }
.pending-actions { display: grid; gap: 8px; }
.pending-actions .btn { width: 100%; }

.btn-approve { color: var(--color-success) !important; }
.btn-approve:hover {
  background: color-mix(in oklab, var(--color-success) 14%, transparent) !important;
}

.review-bar {
  border-color: color-mix(in oklab, var(--color-warning) 40%, transparent);
  background: color-mix(in oklab, var(--color-warning) 8%, var(--glass-bg));
}
.review-bar strong { display: flex; align-items: center; gap: 8px; font-size: var(--fs-base); }
.review-bar strong svg { width: 20px; height: 20px; color: var(--color-warning); }

/* ==========================================================================
   Auth clarity — login == signup
   ========================================================================== */
.auth-note { display: grid; gap: 10px; }
.auth-note-row {
  display: flex; align-items: flex-start; gap: 10px;
  font-size: var(--fs-sm); color: var(--color-muted-foreground);
}
.auth-note-row svg { width: 18px; height: 18px; flex: none; margin-top: 2px; color: var(--color-success); }

/* highlighted call-to-action inside the mobile drawer */
.mobile-nav .panel a.nav-cta {
  background: var(--color-primary);
  color: var(--color-on-primary); box-shadow: var(--e2);
  min-height: 58px; margin-block: 4px;
}
.mobile-nav .panel a.nav-cta svg { color: #fff; }
.mobile-nav .panel a.nav-cta span { display: flex; flex-direction: column; line-height: 1.3; }
.mobile-nav .panel a.nav-cta small { font-size: 12px; opacity: .85; font-weight: 500; }

/* ---------- homepage: shop-owner call to action ---------- */
.owner-cta {
  display: grid; gap: var(--space-2xl);
  grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
  align-items: center;
  padding: var(--space-3xl) var(--space-2xl);
  border-radius: var(--radius-2xl);
  border: none; color: #ffffff;
  background:
    radial-gradient(30rem 18rem at 90% -20%, color-mix(in oklab, var(--brand-400) 42%, transparent), transparent 62%),
    linear-gradient(150deg, var(--brand-600) 0%, var(--brand-700) 58%, var(--brand-800) 100%);
  box-shadow: var(--e4);
}
@media (max-width: 900px) { .owner-cta { grid-template-columns: 1fr; padding: var(--space-2xl) var(--space-lg); } }
.owner-cta .eyebrow { color: var(--color-on-brand); }
.owner-cta h2 { font-size: var(--fs-2xl); margin-top: var(--space-md); color: #ffffff; }
.owner-cta p { margin-top: var(--space-md); color: var(--color-on-brand); max-width: 52ch; }
.owner-cta .btn-primary { background: #ffffff; color: var(--brand-800); border: none; }
.owner-cta .btn-primary:hover { background: var(--color-muted); color: var(--color-foreground); }
.owner-cta .btn-glass { background: rgba(255, 255, 255, 0.13); border: 1px solid rgba(255, 255, 255, 0.3); color: #ffffff; }
.owner-cta-list { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 480px) { .owner-cta-list { grid-template-columns: 1fr; } }
.owner-perk {
  display: flex; align-items: center; gap: 10px;
  padding: 13px 15px; border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.22);
  font-size: var(--fs-sm); font-weight: 600; color: #ffffff;
}
.owner-perk svg { width: 19px; height: 19px; flex: none; color: var(--brand-200); }
/* حالت شب — سطح برندِ تیره با هالهٔ نئونی */
:root[data-theme="dark"] .owner-cta,
:root[data-theme="night"] .owner-cta,
:root[data-theme="luxury"] .owner-cta {
  background:
    radial-gradient(28rem 16rem at 90% -20%, color-mix(in oklab, var(--brand-400) 28%, transparent), transparent 62%),
    linear-gradient(150deg, #0d2e1d 0%, #0a2417 58%, #071c11 100%);
}
:root[data-theme="dark"] .owner-perk { background: rgba(255, 255, 255, 0.07); border-color: rgba(255, 255, 255, 0.14); }
/* These became real links (they used to be dead <div>s advertising features
   with no way to reach them), so they need link affordances and a 44px target. */
a.owner-perk {
  color: inherit; text-decoration: none; min-height: 46px;
  transition: transform var(--dur-2) var(--ease-out),
              background var(--dur-2) var(--ease-out);
}
a.owner-perk:hover {
  transform: translateY(-2px);
  background: color-mix(in oklab, var(--color-primary) 14%, transparent);
}
a.owner-perk:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.owner-perk-all {
  background: color-mix(in oklab, var(--color-accent) 12%, transparent);
  border-color: color-mix(in oklab, var(--color-accent) 30%, transparent);
}
.owner-perk-all svg { color: var(--color-accent); }

/* ==========================================================================
   v5 — reusable image field, two-column forms, live preview
   ========================================================================== */

/* ---------- image field ---------- */
.imgf { display: grid; gap: var(--space-md); }
.imgf-drop {
  display: grid; place-items: center; gap: 6px; text-align: center;
  padding: var(--space-xl) var(--space-lg);
  border: 2px dashed var(--color-border-strong);
  border-radius: var(--radius-lg);
  background: var(--glass-bg-weak);
  cursor: pointer; min-height: 132px;
  transition: all var(--dur-2) var(--ease-out);
}
.imgf-drop:hover, .imgf-drop.is-over {
  border-color: var(--color-primary);
  background: color-mix(in oklab, var(--color-primary) 8%, transparent);
  transform: translateY(-2px);
}
.imgf-drop.is-busy { opacity: .55; pointer-events: none; }
.imgf-drop-icon {
  display: grid; place-items: center;
  width: 48px; height: 48px; border-radius: 50%;
  background: color-mix(in oklab, var(--color-primary) 14%, transparent);
  color: var(--color-primary);
}
.imgf-drop-icon svg { width: 24px; height: 24px; }

.imgf-grid {
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(115px, 1fr));
}
.imgf-item {
  position: relative; border-radius: var(--radius-md); overflow: hidden;
  box-shadow: var(--e2); background: var(--color-muted);
  cursor: grab; transition: transform var(--dur-2) var(--ease-out),
                            box-shadow var(--dur-2) var(--ease-out);
}
.imgf-item:hover { box-shadow: var(--e3); }
.imgf-item.is-dragging { opacity: .45; cursor: grabbing; }
.imgf-item.is-target { outline: 3px dashed var(--color-primary); outline-offset: -3px; }
.imgf-item.is-cover { outline: 2px solid var(--color-primary); outline-offset: -2px; }
.imgf-item img { width: 100%; aspect-ratio: 1; object-fit: cover; display: block; }
.imgf-item figcaption {
  font-size: 12px; padding: 4px 6px; text-align: center;
  background: var(--color-muted); color: var(--color-muted-foreground);
  font-variant-numeric: tabular-nums;
}
.imgf-cover-tag {
  position: absolute; bottom: 6px; inset-inline-start: 6px;
  padding: 3px 9px; border-radius: var(--radius-pill);
  background: var(--color-primary); color: var(--color-on-primary);
  font-size: 12px; font-weight: 800;
}
.imgf-tools {
  position: absolute; top: 6px; inset-inline-end: 6px;
  display: flex; gap: 4px; opacity: 0;
  transition: opacity var(--dur-2) var(--ease-out);
}
.imgf-item:hover .imgf-tools, .imgf-item:focus-within .imgf-tools { opacity: 1; }
@media (hover: none) { .imgf-tools { opacity: 1; } }
.imgf-btn {
  width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border: 1px solid var(--glass-border);
  color: var(--color-foreground);
  transition: all var(--dur-2) var(--ease-out);
}
.imgf-btn:hover { background: var(--color-primary); color: var(--color-on-primary); }
.imgf-btn.imgf-del:hover { background: var(--color-destructive); }
.imgf-btn svg { width: 15px; height: 15px; }
.imgf-hint {
  display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
  font-size: var(--fs-xs); color: var(--color-muted-foreground);
}
.imgf-hint > span:first-child { font-weight: 700; color: var(--color-foreground); }

/* ---------- two-column form with sticky sidebar ---------- */
.form-grid {
  display: grid; gap: var(--space-lg);
  /* both tracks must be able to shrink, otherwise the fixed 320px sidebar
     pushes the panel layout wider than the viewport */
  grid-template-columns: minmax(0, 1fr) minmax(0, 320px);
  align-items: start;
  min-width: 0;
}
.form-main, .form-side { min-width: 0; }
@media (max-width: 1080px) { .form-grid { grid-template-columns: 1fr; } }
.form-side { position: sticky; top: calc(var(--header-h) + 16px); display: grid; gap: 0; }
@media (max-width: 1080px) { .form-side { position: static; } }
.form-actions { display: grid; gap: 8px; }

/* ---------- live preview card ---------- */
.item-preview {
  border-radius: var(--radius-lg); overflow: hidden;
  border: 1px solid var(--glass-border); box-shadow: var(--e2);
  background: var(--color-card);
}
.ip-media {
  aspect-ratio: 4 / 3; display: grid; place-items: center;
  background: linear-gradient(160deg,
    color-mix(in oklab, var(--brand-500) 18%, var(--color-muted)),
    color-mix(in oklab, var(--accent-400) 12%, var(--color-muted)));
  color: color-mix(in oklab, var(--color-primary) 55%, transparent);
}
.ip-media svg { width: 40px; height: 40px; }
.ip-media img { width: 100%; height: 100%; object-fit: cover; }
.ip-body { padding: var(--space-md); }
.ip-body strong { display: block; font-size: var(--fs-sm); }
.ip-price { margin-top: 6px; font-weight: 800; color: var(--color-primary); font-size: var(--fs-sm); }
.ip-old { color: var(--color-muted-foreground); font-weight: 500; margin-inline-end: 6px; }

/* ---------- discount badge on public cards ---------- */
.item-price s { color: var(--color-muted-foreground); font-weight: 500; margin-inline-end: 6px; font-size: max(.9em, 12px); } /* v176: کف ۱۲px */
.badge-off { background: var(--color-destructive); color: var(--color-on-destructive); }

/* item card extras */
.item-more {
  position: absolute; bottom: 8px; inset-inline-end: 8px;
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 9px; border-radius: var(--radius-pill);
  background: rgba(0,0,0,.55); color: #fff; font-size: 12px; font-weight: 700;
}
.item-more svg { width: 13px; height: 13px; }
.item-opts { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 9px; }
.item-opt {
  padding: 3px 10px; border-radius: var(--radius-pill);
  border: 1px solid var(--color-border-strong);
  font-size: 12px; font-weight: 600; color: var(--color-muted-foreground);
}
.item-note {
  display: flex; gap: 7px; align-items: flex-start; margin-top: 10px;
  font-size: var(--fs-xs); color: var(--color-muted-foreground);
}
.item-note svg { width: 14px; height: 14px; flex: none; margin-top: 2px; color: var(--color-warning); }
.brand-logo { width: 40px; height: 40px; border-radius: 12px; object-fit: cover;
  flex: none; box-shadow: var(--e2); }


/* Panel layouts spend 262px on their own sidebar, so the header has less room
   than on a public page and the top nav has to collapse sooner.

   Measured, not guessed. At 1500px the panel header needs:
       brand 174 + nav 786 + actions 432 = 1392px of content
   plus the container's own padding, which pushed it 22px past the edge. The
   overflow is gone by 1560px, so that is the cut-off. Re-measure this if you
   add another link to PUBLIC_NAV — every entry costs roughly 80px. */
@media (max-width: 1559px) {
  .page-panel .main-nav { display: none; }
  .page-panel .nav-toggle { display: inline-grid; }
}

/* ==========================================================================
   Duplicate detection warnings
   ========================================================================== */
.dup-hint {
  margin-top: 8px; padding: 11px 13px;
  border-radius: var(--radius-md);
  font-size: var(--fs-xs);
  animation: dupIn var(--dur-3) var(--ease-out);
}
@keyframes dupIn { from { opacity: 0; transform: translateY(-4px) } to { opacity: 1; transform: none } }
@media (prefers-reduced-motion: reduce) { .dup-hint { animation: none; } }

.dup-hint.is-exact {
  background: color-mix(in oklab, var(--color-destructive) 10%, transparent);
  border: 1px solid color-mix(in oklab, var(--color-destructive) 32%, transparent);
}
.dup-hint.is-maybe {
  background: color-mix(in oklab, var(--color-warning) 11%, transparent);
  border: 1px solid color-mix(in oklab, var(--color-warning) 30%, transparent);
}
.dup-hint-head { display: flex; align-items: center; gap: 7px; margin-bottom: 8px; }
.dup-hint-head svg { width: 16px; height: 16px; flex: none; }
.dup-hint.is-exact .dup-hint-head { color: var(--color-destructive); }
.dup-hint.is-maybe .dup-hint-head { color: var(--color-warning); }

.dup-hint-row {
  display: grid; gap: 2px;
  padding: 8px 0; border-top: 1px solid var(--glass-hairline);
}
.dup-hint-row:first-of-type { border-top: 0; }
.dup-hint-name { font-weight: 800; color: var(--color-foreground); }
.dup-hint-meta { color: var(--color-muted-foreground); }
.dup-hint-why { color: var(--color-muted-foreground); font-style: italic; }
.dup-hint-act { display: flex; gap: 12px; margin-top: 4px; }
.dup-hint-act a { color: var(--color-primary); font-weight: 700; min-height: var(--tap);
.dup-hint-foot {
  margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--color-border);
  font-size: 12.5px; color: var(--color-muted-foreground);
}
.dup-hint-foot a { color: var(--color-primary); font-weight: 700; }
  display: inline-flex; align-items: center; }

.dup-box { border-color: color-mix(in oklab, var(--color-destructive) 34%, transparent); }
.dup-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-md); flex-wrap: wrap;
  padding: 13px 0; border-bottom: 1px solid var(--glass-hairline);
}
.dup-row:last-of-type { border-bottom: 0; }

/* ==========================================================================
   Pagination + bulk action bar
   ========================================================================== */
.pager {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  justify-content: center; margin-top: var(--space-xl);
}
.pager a, .pager .pg-cur {
  display: inline-flex; align-items: center; gap: 5px;
  min-width: var(--tap); min-height: var(--tap); padding: 0 13px;
  border-radius: var(--radius-md);
  font-size: var(--fs-sm); font-weight: 700;
  font-variant-numeric: tabular-nums;
  transition: all var(--dur-2) var(--ease-out);
}
.pager a {
  background: var(--glass-bg); border: 1px solid var(--glass-border);
  color: var(--color-foreground);
}
.pager a:hover { background: var(--color-muted); transform: translateY(-2px); }
.pager a svg { width: 16px; height: 16px; }
.pager .pg-cur {
  background: var(--color-primary);
  color: var(--color-on-primary); box-shadow: var(--e2);
}
.pager .pg-gap { padding: 0 4px; color: var(--color-muted-foreground); }

.bulk-bar {
  position: sticky; top: calc(var(--header-h) + 8px); z-index: var(--z-sticky);
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-md); flex-wrap: wrap;
  padding: 12px 16px; margin-bottom: var(--space-md);
  border-radius: var(--radius-lg);
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: blur(18px) saturate(190%);
  backdrop-filter: blur(18px) saturate(190%);
  border: 1px solid color-mix(in oklab, var(--color-primary) 34%, transparent);
  box-shadow: var(--e3);
  animation: bulkIn var(--dur-3) var(--ease-out);
}
@keyframes bulkIn { from { opacity: 0; transform: translateY(-6px) } to { opacity: 1; transform: none } }
@media (prefers-reduced-motion: reduce) { .bulk-bar { animation: none; } }
.bulk-bar .select { min-height: var(--tap); padding: 6px 12px; font-size: var(--fs-xs); }

/* ======================================================================
   v3 — world-class directory features
   ====================================================================== */

/* --- grouped panel navigation with live counters ------------------- */
.panel-nav { gap: 10px; }
.panel-nav-group {
  display: grid; gap: 3px; margin: 0;
  padding: 7px; border-radius: var(--radius-lg);
  border: 1px solid color-mix(in oklab, var(--color-border) 78%, transparent);
  background: color-mix(in oklab, var(--color-surface) 58%, transparent);
}
.panel-nav-title {
  display: flex; align-items: center; gap: 7px;
  font-size: 11px; font-weight: 900; letter-spacing: 0;
  color: var(--color-muted-foreground); opacity: .88;
  padding: 4px 8px 6px; text-transform: none;
}
.panel-nav-title::before {
  content: ""; width: 6px; height: 6px; border-radius: 999px;
  background: var(--color-primary); opacity: .72; flex: none;
}
.panel-nav a {
  position: relative; min-height: 42px; padding: 9px 10px;
  border: 1px solid transparent; border-radius: var(--radius-sm);
}
.panel-nav a:hover { border-color: var(--glass-hairline); }
.nav-count {
  margin-inline-start: auto; min-width: 22px; height: 20px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0 6px; border-radius: 999px; font-size: 12px; font-weight: 900;
  background: var(--color-accent); color: #fff; line-height: 1;
}
.panel-nav a[aria-current="page"] .nav-count { background: rgba(255,255,255,.28); }

.panel-quick-card .between { gap: var(--space-md); }
.panel-quick-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-md);
}
.panel-quick-section {
  padding: 14px; border-radius: var(--radius-lg);
  border: 1px solid var(--glass-border);
  background: color-mix(in oklab, var(--color-surface) 72%, transparent);
}
.panel-quick-head {
  display: flex; align-items: center; gap: 10px;
  padding-bottom: 12px; margin-bottom: 12px;
  border-bottom: 1px solid var(--glass-hairline);
}
.panel-quick-head strong { display: block; font-size: var(--fs-sm); }
.panel-quick-head small { display: block; color: var(--color-muted-foreground); font-size: var(--fs-xs); margin-top: 2px; }
.panel-quick-links {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px;
}
.panel-quick-links a {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: var(--tap); padding: 9px 10px; border-radius: var(--radius-md);
  background: var(--color-muted); color: var(--color-foreground);
  font-size: var(--fs-sm); font-weight: 800;
  border: 1px solid transparent;
}
.panel-quick-links a:hover {
  background: color-mix(in oklab, var(--color-primary) 10%, var(--color-muted));
  border-color: color-mix(in oklab, var(--color-primary) 24%, transparent);
}
.panel-quick-links svg { width: 18px; height: 18px; flex: none; }
@media (max-width: 760px) {
  .panel-quick-grid { grid-template-columns: 1fr; }
  .panel-quick-links { grid-template-columns: 1fr; }
}

/* --- insights charts ----------------------------------------------- */
.ins-chart {
  display: flex; align-items: flex-end; gap: 3px;
  height: 170px; padding: 12px; border-radius: var(--radius-lg);
  background: var(--color-muted);
}
.ins-bar {
  flex: 1; min-width: 3px; height: var(--h);
  border-radius: 4px 4px 2px 2px;
  background: linear-gradient(180deg, var(--brand-400), var(--brand-700));
  transition: filter var(--dur-2) var(--ease-out);
}
.ins-bar:hover { filter: brightness(1.18); }
.ins-row { display: flex; align-items: center; gap: 10px; margin-bottom: 9px; font-size: var(--fs-sm); }
.ins-label { flex: 0 0 34%; color: var(--color-muted-foreground); font-weight: 600; }
.ins-track { flex: 1; height: 9px; border-radius: 999px; background: var(--color-muted); overflow: hidden; }
.ins-fill { display: block; height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--brand-500), var(--brand-700)); }
.ins-fill.alt { background: linear-gradient(90deg, var(--accent-500), var(--accent-700)); }

/* --- Q&A ------------------------------------------------------------ */
.qa-item { padding: var(--space-md) 0; border-bottom: 1px solid var(--glass-hairline); }
.qa-item:last-child { border-bottom: 0; }
.qa-q { display: flex; gap: 10px; align-items: flex-start; font-weight: 700; }
.qa-q .qmark, .qa-a .amark {
  flex: none; width: 26px; height: 26px; border-radius: 8px;
  display: grid; place-items: center; font-size: 12px; font-weight: 800;
}
/* v117/فاز۷: جفتِ توکنِ روی-رنگ — سفیدِ هاردکد در تم شب فقط ۳٫۲ بود */
.qa-q .qmark { background: var(--color-primary); color: var(--color-on-primary); }
.qa-a .amark { background: var(--color-accent); color: var(--color-on-accent); }
.qa-a { display: flex; gap: 10px; align-items: flex-start; margin-top: 10px;
  padding: 10px 12px; border-radius: var(--radius-md); background: var(--color-muted);
  font-size: var(--fs-sm); color: var(--color-muted-foreground); }
.qa-meta { display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  font-size: var(--fs-xs); color: var(--color-muted-foreground); margin-top: 6px; }
.qa-helpful { display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
  border-radius: 999px; padding: 4px 10px; min-height: 44px; /* v118: tap floor */
  border: 1px solid var(--color-border);
  background: transparent; font-size: var(--fs-xs); font-weight: 600;
  color: var(--color-muted-foreground); transition: all var(--dur-2) var(--ease-out); }
.qa-helpful:hover { border-color: var(--color-primary); color: var(--color-primary); }
.qa-helpful svg { width: 14px; height: 14px; }
.qa-helpful[aria-pressed="true"] { border-color: var(--color-primary); color: var(--color-primary);
  background: color-mix(in oklab, var(--color-primary) 10%, transparent); }

/* --- criteria bars on a business page ------------------------------- */
.crit-grid { display: grid; gap: 10px; margin-top: var(--space-md); }
.crit-row { display: grid; grid-template-columns: minmax(0,1fr) minmax(120px,2fr) 46px;
  align-items: center; gap: 12px; font-size: var(--fs-sm); }
.crit-row > strong { text-align: end; }
.crit-n { display: block; font-size: 12px; font-weight: 400; color: var(--color-muted-foreground); margin-top: 2px; }
.guest-note { background: var(--color-muted); border: 1px dashed var(--color-border-strong); border-radius: var(--radius-md); padding: 10px 14px; font-size: .85rem; margin-bottom: 14px; }
.guest-note b { color: var(--color-foreground); }
.live-score { margin: -2px 0 4px; }
.live-score .nums { color: var(--accent-600, var(--accent-500)); }
.crit-track { height: 8px; border-radius: 999px; background: var(--color-muted); overflow: hidden; }
.crit-fill { display: block; height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent-400), var(--accent-600)); }
@media (max-width: 520px) { .crit-row { grid-template-columns: minmax(0,1fr) minmax(70px,1fr) 40px; gap: 8px; } }

/* --- rating inputs for multi-criteria ------------------------------- */
.crit-input { display: grid; gap: 10px; }
.crit-input .row { display: grid; grid-template-columns: minmax(0,1fr) auto;
  align-items: center; gap: 10px; }
.crit-stars { display: inline-flex; gap: 2px; }
.crit-stars button { background: none; border: 0; cursor: pointer; padding: 2px;
  color: var(--color-border-strong); transition: color var(--dur-1) var(--ease-out);
  /* v118: tap floor — the star glyph stays 20px, the hit area becomes 44px */
  min-width: 44px; min-height: 44px; display: grid; place-items: center; }
.crit-stars button svg { width: 20px; height: 20px; }
.crit-stars button[aria-pressed="true"] { color: var(--accent-500); }
.crit-stars button:hover { color: var(--accent-400); }
/* v158: ستارهٔ انتخابی توپُر می‌شود (fill از CSS بر ویژگی fill="none" svg می‌چربد) */
.rating-input button[aria-pressed="true"] svg,
.crit-stars button[aria-pressed="true"] svg { fill: currentColor; }
/* v158: شش ستاره در صفحهٔ باریک — معیار دو سطر می‌شود تا ستاره‌ها له نشوند */
@media (max-width: 420px) {
  .crit-input .row { grid-template-columns: 1fr; }
  .crit-stars { width: 100%; justify-content: space-between; }
}

/* --- badges on cards ------------------------------------------------ */
.badge-custom { border-style: solid; font-weight: 700; }
.badge-strip { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }

/* --- compare tray --------------------------------------------------- */
.cmp-tray {
  position: fixed; inset-inline: 0; bottom: 0; z-index: 60;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 12px clamp(12px, 4vw, 32px);
  background: var(--glass-bg); backdrop-filter: blur(20px) saturate(180%);
  border-top: 1px solid var(--glass-hairline); box-shadow: var(--e3);
  transform: translateY(110%); transition: transform var(--dur-3) var(--ease-out);
}
.cmp-tray.is-open { transform: none; }
/* `display:flex` above beats the UA `[hidden]{display:none}` rule, which made
   the tray show up empty on every page. Restore the intent explicitly. */
.cmp-tray[hidden] { display: none !important; }
.cmp-tray .chips { display: flex; gap: 8px; flex-wrap: wrap; flex: 1; min-width: 0; }
.cmp-chip { display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px; border-radius: 999px; background: var(--color-muted);
  font-size: var(--fs-xs); font-weight: 600; }
.cmp-chip button { background: none; border: 0; cursor: pointer; color: var(--color-destructive);
  display: grid; place-items: center; }
.cmp-chip button svg { width: 13px; height: 13px; }
.cmp-btn { display: inline-flex; align-items: center; gap: 5px;
  border: 1px solid var(--color-border); background: transparent; cursor: pointer;
  border-radius: 999px; padding: 5px 11px; min-height: 44px;  /* v118: tap floor */
  font-size: var(--fs-xs); font-weight: 600;
  color: var(--color-muted-foreground); transition: all var(--dur-2) var(--ease-out); }
.cmp-btn:hover { border-color: var(--color-primary); color: var(--color-primary); }
.cmp-btn[aria-pressed="true"] { background: var(--color-primary); border-color: var(--color-primary); color: var(--color-on-primary); }
.cmp-btn svg { width: 14px; height: 14px; }
.cmp-table { width: 100%; border-collapse: collapse; }
.cmp-table th, .cmp-table td { padding: 12px 10px; border-bottom: 1px solid var(--glass-hairline);
  text-align: start; vertical-align: top; font-size: var(--fs-sm); }
.cmp-table th:first-child { width: 150px; color: var(--color-muted-foreground); font-weight: 600; }
.cmp-table thead th { font-weight: 800; }

/* --- ad banner ------------------------------------------------------ */
.dgcmp-unit {
  position: relative; display: block; overflow: hidden;
  border-radius: var(--radius-xl); border: 1px solid var(--glass-border);
  background:
    radial-gradient(14rem 10rem at 92% -10%, color-mix(in oklab, var(--color-primary) 15%, transparent), transparent 70%),
    var(--glass-bg);
  box-shadow: var(--e2);
  transition: transform var(--dur-3) var(--ease-out), box-shadow var(--dur-3) var(--ease-out), border-color var(--dur-3) var(--ease-out);
}
.dgcmp-unit:hover {
  transform: translateY(-3px); box-shadow: var(--e4);
  border-color: color-mix(in oklab, var(--color-primary) 40%, transparent);
}
.dgcmp-link {
  display: block; text-decoration: none; color: inherit; padding: 18px 20px;
}
.dgcmp-flag-wrap {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-bottom: 12px;
}
.dgcmp-biz-tag {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: var(--fs-xs); font-weight: 700; color: var(--color-muted-foreground);
}
.dgcmp-biz-tag svg { width: 14px; height: 14px; }
.dgcmp-inner {
  display: flex; align-items: center; gap: 18px;
}
.dgcmp-media {
  flex: none; width: 90px; height: 90px; border-radius: var(--radius-lg);
  overflow: hidden; background: color-mix(in oklab, var(--color-primary) 12%, transparent);
  display: grid; place-items: center;
}
.dgcmp-media img {
  width: 100%; height: 100%; object-fit: cover;
}
.dgcmp-media-icon {
  color: var(--color-primary);
}
.dgcmp-media-icon svg { width: 42px; height: 42px; }
.dgcmp-content {
  flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px;
}
.dgcmp-title {
  font-weight: 800; font-size: var(--fs-lg); line-height: 1.35;
  color: var(--color-foreground);
}
.dgcmp-desc {
  font-size: var(--fs-sm); color: var(--color-muted-foreground); line-height: 1.5;
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.dgcmp-action-row {
  margin-top: 6px; display: flex; align-items: center;
}

@media (max-width: 640px) {
  .dgcmp-link { padding: 14px 16px; }
  .dgcmp-inner { flex-direction: column; align-items: stretch; gap: 12px; }
  .dgcmp-media { width: 100%; height: 140px; }
  .dgcmp-media-icon { height: 80px; }
  .dgcmp-action-row .btn { width: 100%; justify-content: center; min-height: 44px; }
}

/* --- event cards ---------------------------------------------------- */
.event-card { display: flex; gap: 14px; align-items: flex-start; }
.event-date { flex: none; width: 62px; text-align: center; border-radius: var(--radius-lg);
  padding: 8px 4px; background: var(--color-primary); color: var(--color-on-primary); }
.event-date .d { font-size: 20px; font-weight: 800; line-height: 1; }
.event-date .m { font-size: 12px; opacity: .9; margin-top: 3px; display: block; }
.event-card.is-past { opacity: .55; }
.event-card.is-past .event-date { background: var(--color-muted); color: var(--color-muted-foreground); }

/* --- nearby / radius search ----------------------------------------- */
.near-bar {
  display: flex; flex-direction: column; gap: 14px;
  padding: 18px 20px; border-radius: var(--radius-xl);
  background: var(--glass-bg); border: 1px solid var(--glass-border);
  box-shadow: var(--e2);
}
.near-main-row {
  display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
}
.near-range-wrap { flex: 1; min-width: 180px; }
.near-cat-box {
  background: color-mix(in oklab, var(--color-surface) 60%, transparent);
  padding: 12px 14px; border-radius: var(--radius-lg);
  border: 1px solid var(--glass-border);
}
.near-cat-head { display: flex; align-items: center; gap: 6px; }
.near-cat-controls {
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
}
.near-cat-search { flex: 1; min-width: 200px; }
.near-select-wrap { flex: none; min-width: 160px; }
.near-chips-bar {
  display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px;
  scrollbar-width: thin; -webkit-overflow-scrolling: touch;
}
.near-chips-bar .chip {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  min-height: 44px; padding: 6px 12px; border-radius: var(--radius-pill);
  font-size: var(--fs-xs); font-weight: 700; cursor: pointer;
  background: var(--color-surface); border: 1px solid var(--color-border);
  color: var(--color-foreground); transition: all var(--dur-2) var(--ease-out);
}
.near-chips-bar .chip.is-active {
  background: var(--color-primary); color: var(--color-on-primary);
  border-color: var(--color-primary);
}
.dist-badge { display: inline-flex; align-items: center; gap: 4px; font-weight: 700; }

/* --- report dialog -------------------------------------------------- */
.report-link { display: inline-flex; align-items: center; gap: 5px;
  font-size: var(--fs-xs); color: var(--color-muted-foreground); }
.report-link:hover { color: var(--color-destructive); }
.report-link svg { width: 14px; height: 14px; }

/* --- pricing / plan cards ------------------------------------------- */
.plan-live { border-color: var(--color-primary) !important;
  box-shadow: 0 0 0 2px color-mix(in oklab, var(--color-primary) 26%, transparent); }
.plan-expiry { font-size: var(--fs-xs); color: var(--color-muted-foreground); margin-top: 6px; }

/* ======================================================================
   Signed-in header chip + context-aware mobile menu
   ====================================================================== */
.account-chip { gap: 8px !important; padding-inline: 8px !important; }
.account-avatar {
  width: 26px; height: 26px; border-radius: 50%; flex: none;
  display: grid; place-items: center; font-weight: 800; font-size: 12px;
  background: var(--color-primary);
  color: var(--color-on-primary);
}
.account-text { display: flex; flex-direction: column; line-height: 1.15; text-align: start; }
.account-text small { font-size: 12px; opacity: .85; font-weight: 600; }
.account-text strong { font-size: var(--fs-xs); font-weight: 700; }

.mnav-area { display: grid; gap: 2px; }
.mnav-head {
  display: flex; align-items: center; gap: 8px;
  padding: 4px 2px 10px; font-size: var(--fs-sm);
  color: var(--color-primary);
}
.mnav-head svg { width: 18px; height: 18px; }
.mnav-title {
  display: block; padding: 10px 2px 4px;
  /* Was 11px, below the 12px readability floor. It used to appear only inside
     the admin drawer; now signed-out visitors see it above the perk list, so
     it has to meet the same floor as the rest of the site. */
  font-size: 12px; font-weight: 800; letter-spacing: .05em;
  color: var(--color-muted-foreground); opacity: .72;
}
/* v335: public/main-site hamburger becomes a compact task accordion instead
   of one crowded list. The admin panel drawer keeps its own existing map. */
.mnav-groups { display: grid; gap: 8px; }
.mnav-group {
  margin: 0; padding: 6px;
  border: 1px solid color-mix(in oklab, var(--color-border) 76%, transparent);
  border-radius: var(--radius-lg);
  background: color-mix(in oklab, var(--color-surface) 64%, transparent);
  overflow: clip;
}
.mnav-group[open] {
  border-color: color-mix(in oklab, var(--color-primary) 34%, var(--color-border));
  background: color-mix(in oklab, var(--color-surface) 80%, transparent);
}
.mnav-group.is-current:not([open]) {
  border-color: color-mix(in oklab, var(--color-primary) 22%, var(--color-border));
}
.mnav-group.is-current:not([open]) .mnav-summary {
  background: color-mix(in oklab, var(--color-primary) 8%, transparent);
}
.mnav-summary {
  list-style: none; display: flex; align-items: center; gap: 10px;
  min-height: var(--tap); padding: 9px 10px;
  border-radius: var(--radius-md); cursor: pointer; user-select: none;
  color: var(--color-foreground); font-weight: 800;
  transition: background-color var(--dur-2) var(--ease-out), color var(--dur-2) var(--ease-out);
}
.mnav-summary::-webkit-details-marker { display: none; }
.mnav-summary::marker { content: ""; }
.mnav-summary:hover,
.mnav-summary:focus-visible { background: var(--color-muted); outline: none; }
.mnav-summary > svg:not(.mnav-caret) {
  width: 19px; height: 19px; flex: none; color: var(--color-primary);
}
.mnav-summary-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.35; }
.mnav-summary-text small {
  margin-top: 2px; color: var(--color-muted-foreground);
  font-size: var(--fs-xs); font-weight: 600; /* v347: keep mobile menu helper text at the 12px readability floor. */
}
.mnav-current {
  flex: none; padding: 2px 7px; border-radius: var(--radius-pill);
  background: color-mix(in oklab, var(--color-primary) 14%, transparent);
  color: var(--color-primary); font-size: var(--fs-xs); font-weight: 900;
}
.mnav-caret {
  width: 17px; height: 17px; flex: none; margin-inline-start: auto;
  color: var(--color-muted-foreground);
  transition: transform var(--dur-2) var(--ease-out);
}
.mnav-group[open] .mnav-caret { transform: rotate(180deg); }
.mnav-links { display: grid; gap: 2px; padding: 3px 2px 4px; }
.mobile-nav .panel .mnav-links a { min-height: var(--tap); padding: 10px 11px; }
.mobile-nav .panel .mnav-links a.nav-ai { color: var(--color-primary); }
.mobile-nav .panel .mnav-account .mnav-perks { margin-top: 2px; }
.mobile-nav .panel .mnav-account .mnav-title { padding-inline: 10px; }
.mobile-nav .panel .mnav-area a { min-height: var(--tap); font-size: var(--fs-xs); }
.mnav-logout {
  display: flex; align-items: center; gap: 11px; width: 100%;
  padding: 11px 13px; border-radius: var(--radius-md); border: 0;
  background: none; cursor: pointer; text-align: start;
  font-size: var(--fs-sm); font-weight: 600; min-height: 46px;
  color: var(--color-destructive); font-family: inherit;
}
.mnav-logout:hover { background: color-mix(in oklab, var(--color-destructive) 10%, transparent); }
.mnav-logout svg { width: 19px; height: 19px; flex: none; }

/* the panel sidebar is redundant on a phone once the menu carries it */
@media (max-width: 1024px) {
  .panel-layout > .panel-side { display: none; }
}

/* ======================================================================
   Two-level category navigation
   ====================================================================== */
.dir-subchips {
  display: flex; gap: 7px; flex-wrap: wrap;
  margin-top: 10px; padding-top: 10px;
  border-top: 1px dashed var(--color-border);
}
.chip.sub {
  font-size: var(--fs-xs); padding: 5px 11px; min-height: var(--tap);
  background: transparent;
}
.chip.sub.is-active {
  background: var(--color-primary); border-color: var(--color-primary); color: var(--color-on-primary);
}
.chip-n {
  margin-inline-start: 5px; padding: 1px 6px; border-radius: 999px;
  background: var(--color-muted); color: var(--color-muted-foreground);
  font-size: 12px; font-weight: 800; line-height: 1.6;
}
.chip.is-active .chip-n { background: rgba(255,255,255,.26); color: #fff; }

/* the category table in the panel: children read as children */
.cat-child td { background: color-mix(in oklab, var(--color-muted) 45%, transparent); }
.cat-parent td { font-weight: 600; }

/* ----------------------------------------------------------------------
   With 22 top-level categories a single scrolling row hides most of them
   behind a swipe nobody discovers. Wrap instead, and cap the height with a
   "show all" toggle so the filter bar never dominates the page.
   ---------------------------------------------------------------------- */
.dir-chips {
  flex-wrap: wrap;
  overflow-x: visible;
  /* Measured at 412px: the box was 84px tall holding 686px of chips — 21 of
     23 categories unreachable, and the second row sliced through the middle
     of the pills so it read as breakage rather than as "there is more".
     Measured on the live page: padding-top 16 + chip 44 + gap 8 + chip 44 =
     112px for two WHOLE rows. 92px sliced the second row 20px from its
     bottom, which is exactly what looked broken. */
  max-height: 104px;
  overflow-y: hidden;
  transition: max-height var(--dur-3) var(--ease-out);
}
.dir-chips.is-expanded {
  max-height: 70vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* the scroll area needs a floor of its own or it collapses on short lists */
  overscroll-behavior: contain;
}
/* A hard cut with nothing marking it looks like a rendering fault. Fade the
   last few pixels so the row visibly continues under the "همهٔ دسته‌ها" button. */
.dir-chips:not(.is-expanded) {
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 14px), transparent);
  mask-image: linear-gradient(to bottom, #000 calc(100% - 14px), transparent);
}
.chips-more {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  min-height: 44px; margin-top: 8px; padding: 6px 14px; border-radius: 999px;
  border: 1px dashed var(--color-border-strong); background: transparent;
  font-family: inherit; font-size: var(--fs-xs); font-weight: 700;
  color: var(--color-muted-foreground);
  transition: all var(--dur-2) var(--ease-out);
}
.chips-more:hover { border-color: var(--color-primary); color: var(--color-primary); }
.chips-more svg { width: 15px; height: 15px; transition: transform var(--dur-2) var(--ease-out); }
.chips-more[aria-expanded="true"] svg { transform: rotate(180deg); }
@media (max-width: 640px) {
  /* 84px then 92px both sliced the second row. 112px is the measured height
     of two complete rows (16 pad + 44 + 8 gap + 44); the mask below shows
     the list keeps going. */
  .dir-chips { max-height: 104px; }
  .dir-chips.is-expanded { max-height: 58vh; }
  /* the toggle is the way out of a clipped list — it must read as a button,
     sit full width under it, and clear the 44px touch floor */
  .chips-more {
    display: flex; width: 100%; justify-content: center;
    min-height: 44px; margin-top: 10px;
    border-style: solid;
    border-color: color-mix(in oklab, var(--color-primary) 35%, transparent);
    color: var(--color-primary);
    background: color-mix(in oklab, var(--color-primary) 7%, transparent);
  }
}

/* a lone result should not sit in a three-column grid looking abandoned */
.grid-3:has(> :only-child) { grid-template-columns: minmax(0, 420px); }

/* ======================================================================
   FEATURE GATES — visible but locked
   The blur must be strong enough that the data is unreadable, but weak
   enough that the shape of the feature is obvious. 6px hits that balance.
   ====================================================================== */
.gated { position: relative; border-radius: var(--radius-xl); overflow: hidden; }
.gated-inner {
  filter: blur(6px) saturate(.55);
  opacity: .5;
  pointer-events: none;
  user-select: none;
  transform: scale(1.015);   /* hides the soft edge the blur leaves behind */
}
.lock-veil {
  position: absolute; inset: 0; z-index: 2;
  display: grid; place-items: center;
  padding: var(--space-lg);
  background: linear-gradient(180deg,
              color-mix(in oklab, var(--color-background) 55%, transparent),
              color-mix(in oklab, var(--color-background) 85%, transparent));
}
.lock-card {
  text-align: center; max-width: 340px;
  padding: var(--space-lg) var(--space-xl);
  border-radius: var(--radius-xl);
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(14px) saturate(180%);
  backdrop-filter: blur(14px) saturate(180%);
  border: 1px solid var(--glass-hairline);
  box-shadow: var(--e3);
}
.lock-card strong { display: block; font-size: var(--fs-md); margin-top: 10px; }
.lock-card p {
  font-size: var(--fs-sm); color: var(--color-muted-foreground);
  margin: 8px 0 14px; line-height: 1.7;
}
.lock-badge {
  width: 46px; height: 46px; border-radius: 50%;
  display: inline-grid; place-items: center;
  background: var(--color-primary);
  color: var(--color-on-primary); box-shadow: var(--e2);
}
.lock-badge svg { width: 22px; height: 22px; }
.lock-help {
  display: inline-flex; align-items: center; margin-top: 10px; min-height: 44px;
  font-size: var(--fs-xs); color: var(--color-muted-foreground);
  text-decoration: underline; text-underline-offset: 3px;
}
.lock-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: 999px;
  background: color-mix(in oklab, var(--color-accent) 14%, transparent);
  color: var(--color-accent);
  font-size: var(--fs-xs); font-weight: 700;
}
.lock-chip svg { width: 13px; height: 13px; }

/* a locked entry in the sidebar still shows, with a small padlock */
.panel-nav a.is-locked { opacity: .62; }
.panel-nav a.is-locked .nav-lock {
  margin-inline-start: auto; width: 15px; height: 15px;
  color: var(--color-accent); flex: none;
}

/* founding-member ribbon */
.founder-ribbon {
  display: flex; align-items: center; gap: 11px;
  padding: 13px 18px; border-radius: var(--radius-xl);
  background: linear-gradient(100deg,
              color-mix(in oklab, var(--gold-500, var(--color-primary)) 13%, transparent),
              color-mix(in oklab, var(--gold-400, var(--color-primary)) 8%, transparent));
  border: 1px solid color-mix(in oklab, var(--gold-500, var(--color-primary)) 26%, transparent);
  font-size: var(--fs-sm); line-height: 1.7;
}
.founder-ribbon svg { width: 22px; height: 22px; color: var(--gold-500, var(--color-primary)); flex: none; }

/* the unlock matrix in the admin panel */
.unlock-grid { display: grid; gap: 8px; }
.unlock-row {
  display: grid; grid-template-columns: 26px minmax(0,1fr) auto;
  align-items: center; gap: 11px;
  padding: 9px 12px; border-radius: var(--radius-md);
  background: var(--color-muted);
}
.unlock-row.is-on { background: color-mix(in oklab, var(--color-primary) 11%, transparent); }
.unlock-row svg { width: 18px; height: 18px; color: var(--color-muted-foreground); }
.unlock-row.is-on svg { color: var(--color-primary); }
.unlock-row .u-label { font-size: var(--fs-sm); font-weight: 600; }
.unlock-row .u-why {
  display: block; font-size: var(--fs-xs);
  color: var(--color-muted-foreground); font-weight: 400; margin-top: 2px;
}
.unlock-src {
  font-size: 12px; font-weight: 800; padding: 2px 8px; border-radius: 999px;
  background: var(--color-background); color: var(--color-muted-foreground);
}
.unlock-src.src-plan { background: color-mix(in oklab, var(--color-primary) 18%, transparent); color: var(--color-primary); }
.unlock-src.src-founder { background: color-mix(in oklab, var(--gold-500, var(--color-primary)) 20%, transparent); color: var(--gold-500, var(--color-primary)); }
.unlock-src.src-manual { background: color-mix(in oklab, var(--color-accent) 18%, transparent); color: var(--color-accent); }

/* ======================================================================
   CATEGORY ACCORDION — all 22 parents, 143 trades one click away
   ====================================================================== */
.cat-tile.is-group { padding: 0; display: block; cursor: default; }
.cat-tile-head {
  display: block; width: 100%; text-align: inherit; cursor: pointer;
  background: none; border: 0; font: inherit; color: inherit;
  padding: var(--space-lg); position: relative;
  border-radius: inherit;
}
.cat-chevron {
  position: absolute; inset-inline-end: 14px; top: 14px;
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--color-muted); color: var(--color-muted-foreground);
  transition: transform var(--dur-2) var(--ease-out),
              background-color var(--dur-2) var(--ease-out);
}
.cat-chevron svg { width: 15px; height: 15px; }
.cat-tile-head[aria-expanded="true"] .cat-chevron {
  transform: rotate(180deg);
  background: var(--color-primary); color: var(--color-on-primary);
}
.cat-tile.is-group:has([aria-expanded="true"]) {
  border-color: color-mix(in oklab, var(--color-primary) 40%, transparent);
  box-shadow: var(--e2);
}
/* `display:flex` beats the UA rule `[hidden]{display:none}`, so without this
   every accordion stays laid out (and 273px tall) while looking closed. */
.cat-subs[hidden] { display: none !important; }
.cat-subs {
  display: flex; flex-wrap: wrap; gap: 7px;
  padding: 0 var(--space-lg) var(--space-lg);
  animation: subsIn var(--dur-3) var(--ease-out);
}
@keyframes subsIn { from { opacity: 0; transform: translateY(-5px) } to { opacity: 1; transform: none } }
@media (prefers-reduced-motion: reduce) { .cat-subs { animation: none; } }
.sub-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 11px; border-radius: 999px;
  background: var(--color-background);
  border: 1px solid var(--color-border);
  font-size: var(--fs-xs); font-weight: 600;
  transition: all var(--dur-2) var(--ease-out);
}
.sub-pill:hover {
  border-color: var(--color-primary); color: var(--color-primary);
  transform: translateY(-1px);
}
.sub-pill img { width: 20px; height: 20px; object-fit: contain; }
.sub-pill small {
  padding: 1px 6px; border-radius: 999px; font-size: 12px; font-weight: 800;
  background: var(--color-muted); color: var(--color-muted-foreground);
}
.sub-pill.all {
  background: color-mix(in oklab, var(--color-primary) 10%, transparent);
  border-color: color-mix(in oklab, var(--color-primary) 30%, transparent);
  color: var(--color-primary);
}
.sub-pill.all svg { width: 14px; height: 14px; }

/* ======================================================================
   SUPPORT WIDGET — delayed, FAQ-first
   ====================================================================== */
.sup-fab {
  position: fixed; inset-inline-start: 20px; bottom: 20px; z-index: 100;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-width: var(--tap-lg); min-height: var(--tap-lg); /* v77: ≥۴۸px */
  padding: 12px 18px; border: 0; border-radius: 999px; cursor: pointer;
  font-family: inherit; font-size: var(--fs-sm); font-weight: 700;
  background: var(--color-primary);
  color: var(--color-on-primary); box-shadow: var(--e3);
  animation: supIn var(--dur-4) var(--ease-out);
}
.sup-fab:hover { transform: translateY(-2px); box-shadow: var(--e4, var(--e3)); }
.sup-fab svg { width: 21px; height: 21px; }
.sup-fab-dot {
  position: absolute; top: 9px; inset-inline-end: 9px;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--accent-400); border: 2px solid #fff;
}
.sup-fab[aria-expanded="true"] .sup-fab-dot { display: none; }
@keyframes supIn { from { opacity: 0; transform: translateY(16px) scale(.9) } to { opacity: 1; transform: none } }
@media (prefers-reduced-motion: reduce) { .sup-fab { animation: none; } }
@media (max-width: 560px) {
  .sup-fab { inset-inline-start: 14px; bottom: 14px; padding: 12px; }
  .sup-fab-label { display: none; }
}

.sup-panel {
  position: fixed; inset-inline-start: 20px; bottom: 84px; z-index: 101;
  width: min(380px, calc(100vw - 32px));
  max-height: min(560px, calc(100vh - 130px));
  display: flex; flex-direction: column;
  border-radius: var(--radius-xl); overflow: hidden;
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
  border: 1px solid var(--glass-hairline);
  box-shadow: var(--e3);
  animation: supPanelIn var(--dur-3) var(--ease-out);
}
.sup-panel[hidden] { display: none !important; }
@keyframes supPanelIn { from { opacity: 0; transform: translateY(12px) } to { opacity: 1; transform: none } }
@media (prefers-reduced-motion: reduce) { .sup-panel { animation: none; } }
@media (max-width: 560px) { .sup-panel { inset-inline: 14px; bottom: 76px; width: auto; } }

/* The bottom nav (z-index 90) spans the whole bottom edge — the floating
   helper used to sit *behind* it (its z-index was 70, and its 14px bottom
   offset was inside the nav's 60px band). Dock it ABOVE the nav instead. */
@media (max-width: 768px) {
  .sup-fab   { bottom: calc(var(--botnav-h) + env(safe-area-inset-bottom) + 12px); }
  .sup-panel { bottom: calc(var(--botnav-h) + env(safe-area-inset-bottom) + 68px); }
}

.sup-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 10px; padding: 15px 17px;
  border-bottom: 1px solid var(--glass-hairline);
  background: color-mix(in oklab, var(--color-primary) 7%, transparent);
}
.sup-head strong { display: flex; align-items: center; gap: 7px; font-size: var(--fs-sm); }
.sup-head strong svg { width: 18px; height: 18px; color: var(--color-primary); }
.sup-head small { display: block; margin-top: 3px; font-size: var(--fs-xs); color: var(--color-muted-foreground); }
.sup-body { padding: 13px 17px 17px; overflow-y: auto; }

.sup-faq { border-bottom: 1px solid var(--glass-hairline); }
.sup-faq:last-of-type { border-bottom: 0; }
.sup-faq summary {
  cursor: pointer; padding: 11px 0; font-size: var(--fs-sm); font-weight: 600;
  list-style: none; display: flex; align-items: center; gap: 8px;
}
.sup-faq summary::-webkit-details-marker { display: none; }
.sup-faq summary::before {
  content: '+'; flex: none;
  width: 19px; height: 19px; border-radius: 50%;
  display: grid; place-items: center; font-weight: 800; font-size: 13px;
  background: var(--color-muted); color: var(--color-muted-foreground);
}
.sup-faq[open] summary::before { content: '−'; background: var(--color-primary); color: var(--color-on-primary); }
.sup-faq p {
  margin: 0 0 12px 27px; padding-inline-start: 0;
  font-size: var(--fs-xs); line-height: 1.85; color: var(--color-muted-foreground);
}
html[dir="rtl"] .sup-faq p { margin: 0 27px 12px 0; }
.sup-direct-title {
  display: flex; align-items: center; gap: 7px;
  font-size: var(--fs-sm); font-weight: 700; margin-bottom: 11px;
}
.sup-direct-title svg { width: 16px; height: 16px; color: var(--color-primary); }
.sup-actions { display: grid; gap: 8px; }
.ticket-only-cta { display:flex; align-items:center; gap:12px; padding:12px; margin-bottom:12px; border-radius:16px; background:color-mix(in oklab,var(--color-primary) 10%,transparent); border:1px solid color-mix(in oklab,var(--color-primary) 24%,transparent); }
.ticket-only-cta p { font-size:12px; color:var(--color-muted-foreground); margin-top:3px; }
.tk-attachment { display:flex; align-items:center; gap:8px; margin-top:8px; padding:9px 11px; border-radius:12px; background:rgba(255,255,255,.07); border:1px solid var(--glass-hairline); }
.tk-attachment svg { width:18px; height:18px; color:var(--color-primary); }
.tk-attachment small { margin-inline-start:auto; color:var(--color-muted-foreground); }

/* ======================================================================
   MAP SELECTION — name the pin you picked
   ====================================================================== */
.map-selected {
  position: absolute; inset-inline-start: 12px; top: 12px; z-index: 500;
  max-width: min(270px, calc(100% - 24px));
  display: flex; flex-direction: column; gap: 4px;
  /* v118: more compact — the card should name the pin, not hide the map */
  padding: 9px 12px; border-radius: var(--radius-md);
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  backdrop-filter: blur(16px) saturate(180%);
  border: 1px solid var(--glass-hairline);
  box-shadow: var(--e3);
  animation: mapSelIn var(--dur-2) var(--ease-out);
}
.map-selected[hidden] { display: none !important; }
.map-selected strong { font-size: var(--fs-xs); }
.map-selected span { font-size: 12px; color: var(--color-muted-foreground); }  /* v160 */
.map-selected .btn { margin-top: 3px; }
@keyframes mapSelIn { from { opacity: 0; transform: translateY(-6px) } to { opacity: 1; transform: none } }
@media (prefers-reduced-motion: reduce) { .map-selected { animation: none; } }

/* map legend — quiet provider status chip at the stage's lower edge. */
.map-legend {
  position: absolute;
  inset-inline: 12px;
  bottom: 10px;
  z-index: 400;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  width: fit-content;
  max-width: calc(100% - 24px);
  padding: 6px 11px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  color: var(--color-muted-foreground);
  background: color-mix(in oklab, var(--color-card) 82%, transparent);
  border: 1px solid var(--color-border);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  pointer-events: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.map-legend svg { width: 14px; height: 14px; flex: none; }

/* Measured on a 412px phone (and re-measured in v109): the card rendered
   335px tall inside a 510px map — 55%+ of the whole map — and floated 118px
   above the stage edge, so it covered the pin it was describing. On a phone
   it is a bottom sheet: DOCKED to the stage's lower edge, height-capped so
   the map above it always stays visible, scrollable inside itself. While a
   card is open the stage gets .has-card and the legend / «نزدیک من» button
   step aside instead of being buried under the sheet. */
@media (max-width: 1024px) {
  /* v119: a FIXED compact panel — everything fits on screen, no scroll.
     The card is a bottom bar (~150px): icon + name + status, meta row,
     one-line address, action buttons. Long text is clamped, never scrolls. */
  .map-selected {
    inset-inline: 10px;
    top: auto; bottom: 10px;
    max-width: none; width: auto;
    max-height: 150px;
    overflow: hidden;
    padding: 8px 10px;
    gap: 3px;
    animation: mapSheetIn var(--dur-2) var(--ease-out);
    background: color-mix(in oklab, var(--color-background) 96%, transparent);
  }
  @keyframes mapSheetIn { from { opacity: 0; transform: translateY(10px) } to { opacity: 1; transform: none } }
  @media (prefers-reduced-motion: reduce) { .map-selected { animation: none; } }
  .ms-head img { width: 28px; height: 28px; }
  .ms-head { gap: 8px; padding-inline-end: 30px; }
  .ms-title strong { font-size: var(--fs-sm) !important; }
  .ms-sub, .ms-meta { font-size: var(--fs-xs); }
  .ms-stars small { display: none; }        /* فشرده‌تر: فقط ستاره + عدد */
  .ms-descr { display: none; }              /* توضیح بلند = اسکرول؛ در موبایل حذف */
  .ms-row {
    font-size: var(--fs-xs);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .ms-acts { flex-wrap: nowrap; }
  .ms-acts .btn {
    flex: 1; min-width: 0; min-height: 40px;
    padding-inline: 6px; font-size: var(--fs-xs); white-space: nowrap;
  }
  .map-stage.has-card .map-legend { bottom: calc(150px + 14px); }
  .map-legend { transition: bottom var(--dur-2) var(--ease-out); }
}

.map-item.is-selected {
  background: color-mix(in oklab, var(--color-primary) 12%, transparent);
  border-color: var(--color-primary);
}
.map-item.is-selected .t { color: var(--color-primary); font-weight: 800; }

/* The selected marker.
   Unselected pins are 22px flat dots. The selected one becomes a different
   object entirely: a large WHITE teardrop holding the shop's own category
   icon, ringed in the brand colour, pulsing once a second, with the name on
   a solid chip beneath. Size alone was not a strong enough signal across a
   map of ten markers — changing the shape, the fill and the content is. */
.bz-pin-wrap { position: relative; display: block; }
.bz-pin-drop {
  position: absolute; inset-inline-start: -13px; top: -26px;
  width: 26px; height: 26px; border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
  background: #fff;
  border: 2px solid var(--pin, var(--color-primary));
  box-shadow: 0 6px 18px rgba(0,0,0,.38);
  display: grid; place-items: center;
  z-index: 2;
}
.bz-pin-drop img,
.bz-pin-drop svg { transform: rotate(45deg); display: block; }
.bz-pin-drop img { width: 17px; height: 17px; object-fit: contain; }

/* a soft halo so the eye is pulled to the pick even when zoomed out */
.bz-pin-pulse {
  position: absolute; inset-inline-start: -13px; top: -13px;
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--pin, var(--color-primary));
  opacity: .28;
  animation: bzPinPulse 1.6s ease-out infinite;
  pointer-events: none;
}
@keyframes bzPinPulse {
  0%   { transform: scale(.6); opacity: .40; }
  70%  { transform: scale(1.9); opacity: 0; }
  100% { transform: scale(1.9); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .bz-pin-pulse { animation: none; opacity: .22; }
}

.bz-pin-label {
  position: absolute; inset-inline-start: 50%; top: 4px;
  transform: translateX(50%);
  white-space: nowrap; padding: 3px 9px; border-radius: 999px;
  background: var(--pin, var(--color-primary)); color: #fff;
  font-family: Vazirmatn, sans-serif; font-size: 12px; font-weight: 800;  /* v160 */
  box-shadow: 0 3px 10px rgba(0,0,0,.30);
  border: 1.5px solid #fff;
}
html[dir="rtl"] .bz-pin-label { transform: translateX(50%); }
.bz-gm-label { text-shadow: 0 0 4px #fff, 0 0 8px #fff; }

/* v120: پین‌ها با زوم مقیاس می‌خورند — متغیر --pin-scale را map.js روی
   کانتینر نقشه ست می‌کند (zoomend). نقطهٔ دوری مرکز، پینِ فعال از نوک. */
.bz-pin .bz-dot {
  transform: scale(var(--pin-scale, 1));
  transform-origin: 50% 50%;
  transition: transform var(--dur-2) var(--ease-out);
  will-change: transform;
}
.bz-pin-active .bz-pin-wrap {
  transform: scale(var(--pin-scale, 1));
  transform-origin: 50% 100%;
  transition: transform var(--dur-2) var(--ease-out);
  will-change: transform;
}
/* v156: نقطهٔ «موقعیت من» هم با زوم مقیاس می‌گیرد (داخلِ divIcon مقیاس
   می‌خورد نه روی ریشه — وگرنه ترنسفورمِ جابه‌جایی Leaflet خراب می‌شد). */
.bz-me .bz-me-dot {
  transform: scale(var(--pin-scale, 1));
  transform-origin: 50% 50%;
  transition: transform var(--dur-2) var(--ease-out);
  will-change: transform;
}

/* v120: جستجوی زندهٔ دایرکتوری — حالت «در حال به‌روزرسانی» بدون پرش صفحه */
[data-dir-results].is-updating [data-dir-grid] {
  opacity: .45;
  pointer-events: none;
  transition: opacity var(--dur-2) var(--ease-out);
}
[data-dir-results].is-updating::after {
  content: "در حال به‌روزرسانی…";
  position: absolute; inset-inline: 0; top: 68px; text-align: center;
  color: var(--color-primary); font-weight: 800; font-size: var(--fs-sm);
  animation: dirUpdPulse 1s ease-in-out infinite alternate;
}
[data-dir-results] { position: relative; }
@keyframes dirUpdPulse { from { opacity: .55 } to { opacity: 1 } }

/* ======================================================================
   PRODUCT TRUST FLAGS — the small print that closes a sale
   ====================================================================== */
.item-flags { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 9px; }
.item-flag {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 8px; border-radius: 999px;
  background: color-mix(in oklab, var(--color-primary) 9%, transparent);
  color: var(--color-primary);
  font-size: 12px; font-weight: 700; line-height: 1.6;
}
.item-flag svg { width: 12px; height: 12px; }

/* spec table on the product page */
.spec-table { width: 100%; border-collapse: collapse; margin-top: var(--space-md); }
.spec-table tr { border-bottom: 1px solid var(--glass-hairline); }
.spec-table tr:last-child { border-bottom: 0; }
.spec-table td { padding: 9px 4px; font-size: var(--fs-sm); vertical-align: top; }
.spec-table td:first-child {
  width: 40%; color: var(--color-muted-foreground); font-weight: 600;
}
.spec-table td:last-child { font-weight: 600; }

/* ======================================================================
   OPEN NOW — live trading status
   Rendered by the server in Iran time, refreshed client-side each minute.
   'closing' gets its own amber treatment: "open" and "closes in 20
   minutes" are different answers to a customer deciding whether to set off.
   ====================================================================== */
.open-line {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  padding: 11px 14px; margin-bottom: var(--space-md);
  border-radius: var(--radius-lg);
  font-size: var(--fs-sm); line-height: 1.6;
  border: 1px solid transparent;
}
.open-line strong { font-weight: 800; }
.open-detail { color: var(--color-muted-foreground); font-size: var(--fs-xs); }
.open-dot {
  width: 9px; height: 9px; border-radius: 50%; flex: none;
  background: currentColor;
  box-shadow: 0 0 0 0 currentColor;
}
.open-line.is-open {
  color: var(--color-success-text);
  background: color-mix(in oklab, var(--color-success) 11%, transparent);
  border-color: color-mix(in oklab, var(--color-success) 26%, transparent);
}
/* the pulse only runs while genuinely open, and never for reduced-motion */
.open-line.is-open .open-dot { animation: openPulse 2.4s ease-out infinite; }
.open-line.is-closing {
  color: var(--gold-500, var(--color-primary));
  background: color-mix(in oklab, var(--gold-400, var(--color-primary)) 13%, transparent);
  border-color: color-mix(in oklab, var(--gold-400, var(--color-primary)) 30%, transparent);
}
.open-line.is-closing .open-dot { animation: openPulse 1.1s ease-out infinite; }
.open-line.is-closed {
  color: var(--color-muted-foreground);
  background: color-mix(in oklab, var(--color-foreground) 5%, transparent);
  border-color: color-mix(in oklab, var(--color-foreground) 12%, transparent);
}
@keyframes openPulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in oklab, currentColor 55%, transparent); }
  70%  { box-shadow: 0 0 0 7px color-mix(in oklab, currentColor 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in oklab, currentColor 0%, transparent); }
}
@media (prefers-reduced-motion: reduce) {
  .open-line .open-dot { animation: none !important; }
}

/* today's row in the hours table */
.hours-table tr.is-today { background: color-mix(in oklab, var(--color-primary) 7%, transparent); }
.hours-table tr.is-today .d { font-weight: 800; }
.today-tag {
  display: inline-block; margin-inline-start: 7px;
  padding: 1px 7px; border-radius: 999px;
  background: var(--color-primary); color: var(--color-on-primary);
  font-size: 12px; font-weight: 800; vertical-align: middle;
}

/* ======================================================================
   LOCAL PRICE COMPARISON
   The bar is proportional to the most expensive offer, so the cheapest
   shop is visibly shorter — the comparison should be readable without
   reading a single number.
   ====================================================================== */
.price-grid { align-items: start; }
.price-card .card-title { font-size: var(--fs-md); line-height: 1.5; }

.pbars { display: grid; gap: 9px; }
.pbar-row {
  display: grid; grid-template-columns: minmax(58px, 88px) 1fr auto;
  align-items: center; gap: 9px; font-size: var(--fs-xs);
}
.pbar-name {
  color: var(--color-muted-foreground);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pbar-track {
  height: 9px; border-radius: 999px; overflow: hidden;
  background: color-mix(in oklab, var(--color-foreground) 8%, transparent);
}
.pbar-fill {
  display: block; height: 100%; border-radius: 999px;
  background: linear-gradient(90deg,
              color-mix(in oklab, var(--color-accent) 70%, transparent),
              var(--color-accent));
  transition: width .5s var(--ease-out);
}
.pbar-fill.is-best {
  background: linear-gradient(90deg,
              color-mix(in oklab, var(--color-success) 65%, transparent), var(--color-success));
}
.pbar-val { font-weight: 700; white-space: nowrap; }

.price-summary {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
}
.price-summary > div {
  padding: 12px 14px; border-radius: var(--radius-lg);
  background: color-mix(in oklab, var(--color-foreground) 4%, transparent);
  border: 1px solid var(--glass-hairline);
}
.price-summary .k {
  display: block; font-size: var(--fs-xs);
  color: var(--color-muted-foreground); margin-bottom: 4px;
}
.price-summary .v { font-size: var(--fs-lg); font-weight: 800; }
.price-summary .save {
  background: color-mix(in oklab, var(--color-success) 10%, transparent);
  border-color: color-mix(in oklab, var(--color-success) 28%, transparent);
}
.price-summary .save .v { color: var(--color-success-text); }
.price-summary .save small { display: block; color: var(--color-success-text); font-weight: 700; }

.price-table tr.is-best { background: color-mix(in oklab, var(--color-success) 8%, transparent); }
.price-table .rank { color: var(--color-muted-foreground); font-weight: 700; }
.over-pct { color: var(--gold-500, var(--color-primary)); font-weight: 700; }

@media (max-width: 640px) {
  .pbar-row { grid-template-columns: minmax(52px, 74px) 1fr auto; }
}

/* ======================================================================
   چانه‌زنی — haggling
   The thread reads like a conversation because that is what it is: two
   people naming numbers until one of them agrees.
   ====================================================================== */
.badge-accent {
  background: color-mix(in oklab, var(--color-accent) 15%, transparent);
  color: var(--color-accent);
  border-color: color-mix(in oklab, var(--color-accent) 34%, transparent);
}
.hag-item { display: flex; gap: 14px; align-items: center; }
.hag-thumb { border-radius: var(--radius-md); object-fit: cover; flex: none; }
.hag-listed { margin-top: 6px; font-size: var(--fs-sm); }

.hag-thread { display: grid; gap: 12px; }
.hag-bubble {
  max-width: min(100%, 460px);
  padding: 13px 16px; border-radius: var(--radius-xl);
  border: 1px solid var(--glass-hairline);
  background: var(--glass-bg);
}
.hag-bubble.is-buyer {
  margin-inline-start: auto;
  background: color-mix(in oklab, var(--color-primary) 9%, transparent);
  border-color: color-mix(in oklab, var(--color-primary) 24%, transparent);
}
.hag-bubble.is-seller {
  margin-inline-end: auto;
  background: color-mix(in oklab, var(--color-accent) 8%, transparent);
  border-color: color-mix(in oklab, var(--color-accent) 22%, transparent);
}
.hag-who {
  display: flex; align-items: center; gap: 6px;
  font-size: var(--fs-xs); color: var(--color-muted-foreground);
}
.hag-who svg { width: 14px; height: 14px; }
.hag-who time { margin-inline-start: auto; }
.hag-price { font-size: var(--fs-lg); font-weight: 800; margin-top: 5px; }
.hag-note { font-size: var(--fs-sm); margin-top: 6px; line-height: 1.7; }

.hag-result {
  text-align: center; max-width: 520px; margin: 0 auto;
  padding: var(--space-2xl) var(--space-xl);
  border-radius: var(--radius-xl);
  background: var(--glass-bg); border: 1px solid var(--glass-hairline);
}
.hag-result h2 { margin: 14px 0 8px; }
.hag-result p { color: var(--color-muted-foreground); line-height: 1.8; margin-bottom: 18px; }
.hag-emoji svg { width: 52px; height: 52px; color: var(--color-primary); }
.hag-result.is-yes { border-color: color-mix(in oklab, var(--color-success) 34%, transparent); }
.hag-result.is-yes .hag-emoji svg { color: var(--color-success); }
.hag-result.is-mid { border-color: color-mix(in oklab, var(--gold-400, var(--color-primary)) 34%, transparent); }
.hag-result.is-mid .hag-emoji svg { color: var(--gold-500, var(--color-primary)); }

/* seller panel */
.hag-offer-row {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px; margin-top: 10px;
}
.hag-offer-row > div {
  padding: 10px 12px; border-radius: var(--radius-lg);
  background: color-mix(in oklab, var(--color-foreground) 4%, transparent);
}
.hag-offer-row .k {
  display: block; font-size: var(--fs-xs);
  color: var(--color-muted-foreground); margin-bottom: 3px;
}
.hag-offer-row .v { display: block; font-size: var(--fs-md); font-weight: 800; }
.hag-minis { display: flex; flex-wrap: wrap; gap: 6px; }
.hag-mini {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: 999px; font-size: var(--fs-xs);
  background: color-mix(in oklab, var(--color-foreground) 6%, transparent);
}
.hag-mini.is-buyer { background: color-mix(in oklab, var(--color-primary) 12%, transparent); }
.hag-mini.is-seller { background: color-mix(in oklab, var(--color-accent) 12%, transparent); }

/* ======================================================================
   BOTTOM NAVIGATION  ·  the thumb zone

   Measured, not guessed: the horizontal .main-nav hides below 1440px (eleven
   links need 995px and the header can only spare 942px), but this bar only
   appeared below 1024px. Between 861px and 1440px the page therefore had NO
   visible navigation at all — just a hamburger. That band is exactly what
   Chrome for Android's "Desktop site" lands on: it forces a 980px viewport.
   So the one mode a shopkeeper switches to was the one with no nav.
   The bar now covers the whole gap, up to where the horizontal nav returns.
   ====================================================================== */
.bottom-nav { display: none; }

@media (max-width: 768px) {
  .bottom-nav {
    position: fixed; z-index: 90;
    inset-inline: 0; bottom: 0;
    display: grid; grid-template-columns: repeat(5, minmax(0,1fr));
    height: calc(60px + env(safe-area-inset-bottom));
    padding: 4px 4px env(safe-area-inset-bottom);
    border-radius: 0;
    /* v97 — standard full-width bottom tab bar, flush to the screen edge and
       opaque. The floating rounded pill read as non-standard on phones. */
    background: var(--color-card);
    border-top: 1px solid var(--color-border);
    box-shadow: 0 -6px 20px rgba(0,0,0,.10);
  }
  /* v89 redesign — Material-3 style. The old active state was a tall box that
     wrapped icon+label and clipped at the bar's edge; now a soft pill sits
     behind the ICON only, and every tab shares one quiet rhythm. */
  .bottom-nav a {
    position: relative; min-width: 0; min-height: 52px;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px; text-decoration: none;
    color: var(--color-muted-foreground); font-weight: 600;
    -webkit-tap-highlight-color: transparent;
    transition: color var(--dur-2), transform var(--dur-2);
  }
  .bottom-nav a span { position: relative; max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:12px; line-height:1.2; }
  .bottom-nav svg { position: relative; width:23px; height:23px; stroke-width:2; }
  /* soft indicator pill behind the icon only */
  .bottom-nav a::before {
    content:''; position:absolute; top:5px; width:54px; height:30px; border-radius:999px;
    background:transparent; transition:background var(--dur-2);
  }
  .bottom-nav a[aria-current="page"] { color: var(--color-primary-text); }
  .bottom-nav a[aria-current="page"] span { color: var(--color-primary-text); }
  .bottom-nav a[aria-current="page"]::before { background: color-mix(in oklab, var(--color-primary-text) 16%, transparent); }
  .bottom-nav a:active { transform:scale(.94); }
  /* v97: the flush bottom bar overlays the footer; reserve its height. */
  .site-footer { padding-bottom: calc(76px + env(safe-area-inset-bottom)); }
}

/* ======================================================================
   CALL BAR  ·  a shop page's own sticky actions
   Sits above the bottom nav. Contact is the whole point of a directory,
   so it must never require a scroll.
   ====================================================================== */
.call-bar { display: none; }

/* Phone-only, aligned with the thumb navigation boundary. */
@media (max-width: 768px) {
.call-bar {
  position: fixed;
  inset-inline: 12px;
  bottom: calc(var(--botnav-h, 64px) + env(safe-area-inset-bottom) + 8px);
  z-index: 85;
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; border-radius: var(--radius-lg, 16px);
  background: var(--color-card, var(--color-surface));
  border: 1px solid var(--color-border);
  box-shadow: 0 12px 32px rgba(0,0,0,.16);
}
.call-bar .cb-main { flex: 1 1 auto; min-width: 0; }
.call-bar .cb-side { flex: none; display: flex; gap: 8px; }
}

@media (prefers-reduced-motion: reduce) {
  .bottom-nav a:active, .cb-main:active, .cb-side:active { transform: none; }
}

/* ======================================================================
   UPLOAD PROGRESS + PREVIEW (v89)
   One floating bar reports a real percentage for every file upload; a
   thumbnail previews the chosen photo/video before it is sent.
   ====================================================================== */
.up-progress {
  position: fixed; z-index: 200;
  inset-inline: 12px;
  bottom: calc(var(--botnav-h, 64px) + env(safe-area-inset-bottom) + 12px);
  display: none; align-items: center; gap: 11px;
  padding: 11px 13px; border-radius: var(--radius-lg, 16px);
  background: color-mix(in srgb, var(--color-card, var(--color-card)) 97%, transparent);
  border: 1px solid color-mix(in oklab, var(--gold-400, var(--color-primary)) 30%, transparent);
  box-shadow: 0 16px 42px rgba(0,0,0,.42);
  color: var(--color-foreground);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  backdrop-filter: blur(18px) saturate(150%);
}
.up-progress.is-on { display: flex; }
.up-progress .up-ico { flex: none; width: 22px; height: 22px; color: var(--gold-400, var(--color-primary)); }
.up-progress .up-body { flex: 1; min-width: 0; }
.up-progress .up-label { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; font-size: 13px; font-weight: 700; }
.up-progress .up-pct { color: var(--gold-300, var(--color-primary)); font-variant-numeric: tabular-nums; }
.up-progress .up-track { margin-top: 7px; height: 6px; border-radius: 999px; background: color-mix(in oklab, var(--color-foreground) 13%, transparent); overflow: hidden; }
.up-progress .up-fill { height: 100%; width: 0; border-radius: 999px; background: linear-gradient(90deg, var(--gold-300, var(--color-primary)), var(--gold-500, var(--color-primary))); transition: width .15s ease; }
.up-progress.is-err { border-color: rgba(248,113,113,.5); }
.up-progress.is-err .up-ico { color: var(--color-danger-text); }
.up-progress.is-err .up-fill { background: var(--color-danger-text); }

.up-preview { display: flex; align-items: center; gap: 11px; margin-top: 10px;
  padding: 8px; border-radius: var(--radius-md, 12px);
  background: var(--glass-bg-weak, rgba(255,255,255,.04));
  border: 1px solid var(--glass-hairline, rgba(255,255,255,.08)); }
.up-preview[hidden] { display: none; }
.up-preview img, .up-preview video { width: 60px; height: 60px; flex: none; object-fit: cover;
  border-radius: 10px; background: #000; border: 1px solid var(--glass-hairline, rgba(255,255,255,.1)); }
.up-preview .up-meta { font-size: 12px; line-height: 1.5; color: var(--color-muted-foreground); min-width: 0; }
.up-preview .up-meta strong { display: inline-block; max-width: 100%; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; color: var(--color-foreground); font-size: 13px; }

/* ======================================================================
   MOBILE HERO  ·  measured at 1496px tall — two full screens of nothing
   The fix is ordering, not deletion: on a phone the search box and the
   categories are what people came for, so they move above the artwork
   and the "open now" card.
   ====================================================================== */
@media (max-width: 1024px) {
  .hero {
    min-height: auto;
    padding-block: var(--space-xl) var(--space-lg);
  }
  .hero-inner { gap: var(--space-lg); }

  /* order: badge+headline -> search -> CTAs -> art -> open-now card */
  /* copy first, then the whole side column (art + open-now card) */
  .hero-copy { order: 1; }
  .hero-side { order: 2; }
  /* inside the side column on a phone the art leads, because the card is
     tall and pushing it above the picture buried the illustration */
  .hero-side { flex-direction: column-reverse; }

  .hero-copy h1 {
    /* 40px on a 360px screen ate four lines; 28px still leads the page */
    font-size: clamp(1.55rem, 6.2vw, 2rem);
    line-height: 1.35;
    margin-bottom: 10px;
  }
  .hero-lead {
    font-size: var(--fs-base);
    line-height: 1.75;
    margin-bottom: var(--space-md);
  }
  /* the trust row is three nice-to-haves; it can wait below the fold */
  .hero-trust { display: none; }
  .scroll-cue { display: none; }

  .hero-search { margin-bottom: var(--space-md); }
  .hero-search .input { min-height: var(--tap-lg); }
  .hero-cta .btn { flex: 1; min-height: var(--tap-lg); }

  /* the open-now card is genuinely useful, but it is not the first thing */
  .hero-panel { padding: var(--space-md); }
  .hero-panel .hero-mini:nth-child(n+4) { display: none; }  /* 3 is plenty */
}

/* ----------------------------------------------------------------------
   HERO OVERFLOW FIX
   `.hero-copy { max-width: 58ch }` is ~383px in Vazirmatn — wider than a
   360px phone. The grid could not shrink it because a grid item's default
   `min-width: auto` refuses to go below its content's intrinsic size, so
   the column blew out and the search box and CTAs were clipped at BOTH
   edges (measured left: -35px inside a 336px container).

   `min-width: 0` lets the track shrink; `max-width: 100%` caps the copy.
   ---------------------------------------------------------------------- */
@media (max-width: 1024px) {
  .hero-inner > * { min-width: 0; }
  .hero-copy { max-width: 100%; }
}

/* ======================================================================
   OPTIONAL-FIELD DISCLOSURE
   The submit form went from 6 required fields to 3. The other four are
   not gone — they sit here, one tap away. Benchmarks put 3-field forms at
   23.1% completion against 14.1% at six, and a shopkeeper filling this in
   while a customer waits is exactly the case that data describes.
   ====================================================================== */
.more-fields {
  border: 1px solid var(--glass-hairline);
  border-radius: var(--radius-lg);
  margin-bottom: var(--space-lg);
  background: color-mix(in oklab, var(--color-foreground) 3%, transparent);
}
.more-fields > summary {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 14px 16px; cursor: pointer; min-height: 52px;
  font-weight: 700; list-style: none;
  border-radius: var(--radius-lg);
  -webkit-tap-highlight-color: transparent;
}
.more-fields > summary::-webkit-details-marker { display: none; }
.more-fields > summary svg {
  width: 18px; height: 18px; color: var(--color-primary); flex: none;
  transition: transform var(--dur-2) var(--ease-out);
}
.more-fields[open] > summary svg { transform: rotate(45deg); }
.more-fields > summary small {
  flex-basis: 100%; font-weight: 500; font-size: var(--fs-xs);
  color: var(--color-muted-foreground); line-height: 1.6;
}
.more-fields > summary:hover { background: color-mix(in oklab, var(--color-primary) 5%, transparent); }
.more-fields-body { padding: 4px 16px 16px; }

/* The optional block now carries the whole profile — hours, socials, map pin.
   Grouping keeps it from reading as one endless column of inputs. */
.sub-fields {
  border: 0; padding: 0; margin: 0 0 var(--space-lg);
  border-top: 1px solid var(--glass-hairline); padding-top: var(--space-md);
}
.sub-fields > legend {
  display: flex; align-items: center; gap: 8px;
  padding: 0; margin-bottom: 6px;
  font-weight: 800; font-size: var(--fs-sm);
}
.sub-fields > legend svg { width: 17px; height: 17px; color: var(--color-primary); flex: none; }
.sub-fields .field-hint { margin-bottom: 10px; }
[data-geo-msg] { margin-top: 8px; line-height: 1.7; }
[data-geo-fill] { margin-top: 4px; }

/* ======================================================================
   QUICK ACTIONS on a business page
   Copy the number, share the shop, save it to contacts. Measured: none of
   these existed, and all three are things a person on a phone actually
   does with a shop's details.
   ====================================================================== */
.biz-action-panel {
  display:flex; flex-direction:column; align-items:stretch;
  gap:8px; min-width:min(100%,210px);
  padding:10px; border-radius:var(--radius-xl);
  background: color-mix(in oklab, var(--color-card) 70%, transparent);
  border:1px solid var(--glass-hairline);
}
.biz-action-title,
.biz-action-subtitle {
  display:flex; align-items:center; gap:7px;
  font-size:var(--fs-xs); font-weight:900;
  color:var(--color-muted-foreground);
}
.biz-action-title svg { width:17px; height:17px; color:var(--color-primary); }
.biz-action-subtitle { margin-top:4px; }
.quick-acts {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 8px; margin-top: var(--space-md);
}
.qa-btn {
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 6px;
  min-height: 62px; padding: 10px 6px;
  border-radius: var(--radius-lg);
  background: var(--glass-bg);
  border: 1px solid var(--glass-hairline);
  color: var(--color-foreground);
  font-size: var(--fs-xs); font-weight: 700;
  cursor: pointer; text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  transition: background var(--dur-1) var(--ease-out);
}
.qa-btn svg { width: 20px; height: 20px; color: var(--color-primary); }
.qa-btn:hover { background: color-mix(in oklab, var(--color-primary) 8%, transparent); }
.qa-btn:active { transform: scale(.96); }
.qa-btn.is-done { background: color-mix(in oklab, var(--color-success) 14%, transparent); }
.qa-btn.is-done svg { color: var(--color-success); }
@media (prefers-reduced-motion: reduce) { .qa-btn:active { transform: none; } }

/* Panel Navigation Grid */
.panel-nav-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}
@media (min-width: 640px) {
  .panel-nav-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
  }
}
@media (min-width: 960px) {
  .panel-nav-grid {
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
  }
}
.panel-nav-tile {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-radius: var(--radius-lg);
  background: var(--color-card);
  border: 1px solid var(--color-border);
  color: var(--color-foreground);
  text-decoration: none;
  font-size: 13px;
  font-weight: 700;
  min-height: 50px;
  transition: all var(--dur-2) var(--ease-out);
}
.panel-nav-tile:hover {
  background: color-mix(in oklab, var(--color-primary) 8%, var(--color-card));
  border-color: var(--color-primary);
  transform: translateY(-1px);
}
.panel-nav-tile svg {
  width: 18px;
  height: 18px;
  flex: none;
  color: var(--color-primary);
}
.panel-nav-tile svg:last-child {
  width: 14px;
  height: 14px;
  color: var(--color-muted-foreground);
}
.panel-nav-tile span {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  border-radius: var(--radius-xl);
  background: var(--color-card);
  border: 1px solid var(--color-border);
  margin-bottom: 18px;
}
.panel-head h1 { font-size: var(--fs-lg); font-weight: 800; margin: 0; }
.panel-head p { font-size: var(--fs-xs); color: var(--color-muted-foreground); margin: 2px 0 0; }

/* ======================================================================
   OWNER QUICK ACTIONS
   Measured: adding one product was 8 steps deep. The full 45-field form is
   untouched and still linked; these are the shorter route to the same place.
   ====================================================================== */
.quick-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px;
}
.quick-tile {
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 5px; text-align: center;
  min-height: 92px; padding: 14px 10px;
  border-radius: var(--radius-lg);
  background: var(--glass-bg);
  border: 1px solid var(--glass-hairline);
  color: var(--color-foreground); text-decoration: none;
  font-weight: 700; font-size: var(--fs-sm);
  transition: background var(--dur-1) var(--ease-out), transform var(--dur-1) var(--ease-out);
}
.quick-tile svg { width: 24px; height: 24px; color: var(--color-primary); }
.quick-tile small {
  font-weight: 500; font-size: var(--fs-xs);
  color: var(--color-muted-foreground); line-height: 1.5;
}
.quick-tile:hover {
  background: color-mix(in oklab, var(--color-primary) 8%, transparent);
  transform: translateY(-2px);
}
.quick-tile:active { transform: scale(.97); }

.quick-add-row {
  display: grid; grid-template-columns: minmax(0,2fr) minmax(0,1fr) auto;
  gap: 10px; align-items: start;
}
.quick-add-row .btn { min-height: 48px; }

@media (max-width: 1024px) {
  .quick-grid { grid-template-columns: 1fr 1fr; }
  .quick-tile { min-height: 84px; }
  /* stacked on a phone: three controls side by side at 360px would leave
     the price field about 70px wide */
  .quick-add-row { grid-template-columns: 1fr; }
  .quick-add-row .btn { width: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .quick-tile:hover, .quick-tile:active { transform: none; }
}

/* ======================================================================
   COLLAPSIBLE DIRECTORY FILTERS
   The search box stays; sort, "open now" and the category chips fold away.
   Measured before: 858px above the first result on a 360px screen.
   ====================================================================== */
.dir-filters { margin-top: 10px; }
.dir-filters > summary {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 16px; min-height: 44px;
  border-radius: 999px; cursor: pointer; list-style: none;
  background: var(--glass-bg);
  border: 1px solid var(--glass-hairline);
  font-weight: 700; font-size: var(--fs-sm);
  -webkit-tap-highlight-color: transparent;
}
.dir-filters > summary::-webkit-details-marker { display: none; }
.dir-filters > summary svg { width: 17px; height: 17px; color: var(--color-primary); }
.dir-filters[open] > summary { background: color-mix(in oklab, var(--color-primary) 9%, transparent); }
.filter-count {
  display: inline-grid; place-items: center;
  min-width: 20px; height: 20px; padding: 0 6px;
  border-radius: 999px; background: var(--color-primary); color: var(--color-on-primary);
  font-size: 12px; font-weight: 800;
}
.dir-filters-body { padding-top: var(--space-md); }

/* On a wide screen there is room for everything, so the fold is pointless:
   force it open and hide the toggle rather than making desktop users click. */
@media (min-width: 861px) {
  .dir-filters > summary { display: none; }
  .dir-filters .dir-filters-body { display: block !important; padding-top: 10px; }
  .dir-filters:not([open]) .dir-filters-body { display: block; }
}

/* the results header shrinks on a phone — you already know what you searched */
@media (max-width: 1024px) {
  .dir-hero { padding-block: var(--space-md) var(--space-sm); }
  .dir-hero h1 { font-size: clamp(1.4rem, 5.6vw, 1.75rem); margin-bottom: 4px; }
  .dir-hero p { font-size: var(--fs-sm); }
  .dir-meta { font-size: var(--fs-xs); }
}

/* ======================================================================
   SEARCHABLE CATEGORY PICKER
   165 trades in a native <select> is a scroll marathon: the shopkeeper
   knows the word for their own trade but must guess which of 22 parent
   groups it was filed under. Type-to-filter removes the guess entirely.
   The native <select> stays in the DOM so the form posts unchanged and
   everything still works with JavaScript off.
   ====================================================================== */
/* Leaflet panes use z-index values up to 700. The desktop picker lives in the
   left map column, so its positioned root must form a higher stack than the
   sibling map canvas; otherwise a visible result is not clickable where the
   popup overlaps the map. */
.catpick { position: relative; z-index: 700; }
.catpick-native { display: none; }

.catpick-btn {
  display: flex; align-items: center; gap: 10px; width: 100%;
  min-height: 48px; padding: 12px 16px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  background: var(--color-surface, #fff);
  color: var(--color-muted-foreground);
  font: inherit; font-size: var(--fs-base); text-align: start;
  cursor: pointer;
}
.catpick.has-value .catpick-btn { color: var(--color-foreground); font-weight: 600; }
.catpick-btn > svg { width: 19px; height: 19px; flex: none; color: var(--color-primary); }
.catpick-val { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.catpick-caret { transition: transform var(--dur-2) var(--ease-out); }
.catpick-btn[aria-expanded="true"] .catpick-caret { transform: rotate(180deg); }
.catpick-btn:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }

.catpick-pop {
  position: absolute; z-index: 60; inset-inline: 0; top: calc(100% + 6px);
  border-radius: var(--radius-lg);
  background: var(--color-background);
  border: 1px solid var(--glass-hairline);
  box-shadow: var(--e3);
  overflow: hidden;
}
.catpick-search {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px; border-bottom: 1px solid var(--glass-hairline);
}
.catpick-search svg { width: 17px; height: 17px; color: var(--color-muted-foreground); flex: none; }
.catpick-search input {
  flex: 1; border: 0; background: none; outline: none;
  font: inherit; font-size: 16px;   /* 16px or iOS zooms the page */
  color: var(--color-foreground); min-height: var(--tap);
}
.catpick-list { max-height: 320px; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.catpick-item {
  display: flex; align-items: baseline; gap: 10px; width: 100%;
  padding: 11px 14px; min-height: 46px;
  border: 0; background: none; cursor: pointer;
  font: inherit; text-align: start;
  color: var(--color-foreground);
  border-bottom: 1px solid color-mix(in oklab, var(--color-foreground) 5%, transparent);
}
.catpick-item:last-child { border-bottom: 0; }
.catpick-item:hover,
.catpick-item.is-cursor { background: color-mix(in oklab, var(--color-primary) 9%, transparent); }
.catpick-item.is-on { background: color-mix(in oklab, var(--color-primary) 14%, transparent); font-weight: 700; }
.ci-name { flex: 1; }
.ci-grp { font-size: var(--fs-xs); color: var(--color-muted-foreground); flex: none; }
.catpick-empty { padding: 16px; font-size: var(--fs-sm); color: var(--color-muted-foreground); line-height: 1.7; }

@media (max-width: 1024px) {
  .catpick-item { min-height: 48px; }

  /* Measured on a 412×915 phone: the popup opened below the button, and the
     first result landed UNDER the fixed bottom bar — you typed "نانوا" and
     could not see "نانوایی". Anchoring it to the viewport instead of the
     button removes the whole class of problem: 165 trades now get the full
     screen, the search box sits at the top under the thumb, and the list
     scrolls above the bar instead of behind it. */
  .catpick-pop {
    position: fixed; z-index: 200;
    inset: 0; top: 0; left: 0; right: 0; bottom: 0;
    border-radius: 0; border: 0;
    display: flex; flex-direction: column;
    background: var(--color-background);
    animation: catpickIn var(--dur-2) var(--ease-out);
  }
  /* `display:flex` above beats the UA `[hidden]{display:none}` rule. Without
     this the closed sheet still covers the whole viewport and swallows every
     tap on the page — including the button that opens it. Third time this
     exact trap has bitten in this codebase (cmp-tray, cat-subs, sup-panel). */
  .catpick-pop[hidden] { display: none !important; }
  @keyframes catpickIn { from { opacity: 0; transform: translateY(8px); } }
  @media (prefers-reduced-motion: reduce) { .catpick-pop { animation: none; } }

  .catpick-sheet-head {
    display: flex; align-items: center; gap: 10px;
    padding: 12px 14px calc(12px + env(safe-area-inset-top));
    padding-top: max(12px, env(safe-area-inset-top));
    border-bottom: 1px solid var(--glass-hairline);
    font-weight: 700;
  }
  .catpick-sheet-head .catpick-close {
    margin-inline-start: auto; width: 44px; height: 44px;
    display: grid; place-items: center;
    border: 0; background: none; cursor: pointer;
    color: var(--color-foreground); border-radius: var(--radius-md);
  }
  .catpick-sheet-head .catpick-close svg { width: 22px; height: 22px; }
  .catpick-search { padding: 12px 14px; }
  .catpick-search input { min-height: 46px; }
  /* Fill what is left, and keep the last row clear of the bottom bar. */
  .catpick-list {
    flex: 1; max-height: none;
    padding-bottom: calc(84px + env(safe-area-inset-bottom));
  }
  .catpick-item { padding: 13px 16px; }
  /* The page must not scroll behind a full-screen sheet. */
  body.catpick-open { overflow: hidden; }
}
@media (min-width: 861px) {
  .catpick-sheet-head { display: none; }
}

/* ----------------------------------------------------------------- features */
.feat-grid {
  display: grid; gap: 12px;
  /* min() so a 300px minimum never exceeds a 360px phone's usable width and
     force a horizontal scrollbar; 250px lets two sit side by side on a wide
     phone in landscape or in Chrome's desktop mode. */
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 250px), 1fr));
}
.feat-card {
  display: flex; align-items: center; gap: 14px;
  padding: 16px; min-height: 76px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--glass-hairline);
  background: var(--glass-bg);
  color: inherit; text-decoration: none;
  min-width: 0;                     /* grid items overflow without this */
  transition: transform var(--dur-2) var(--ease-out),
              border-color var(--dur-2) var(--ease-out);
}
.feat-card:hover {
  transform: translateY(-2px);
  border-color: color-mix(in oklab, var(--color-primary) 40%, transparent);
}
.feat-card > svg:last-child {
  width: 18px; height: 18px; flex: none;
  color: var(--color-muted-foreground);
}
.feat-ico {
  width: 46px; height: 46px; flex: none;
  display: grid; place-items: center; border-radius: var(--radius-md);
  background: color-mix(in oklab, var(--color-primary) 12%, transparent);
  color: var(--color-primary);
}
.feat-ico svg { width: 23px; height: 23px; }
.feat-txt { flex: 1; min-width: 0; display: block; }
.feat-txt strong { display: block; font-size: var(--fs-base); line-height: 1.5; }
.feat-txt small {
  display: block; color: var(--color-muted-foreground);
  font-size: var(--fs-sm); line-height: 1.7; margin-top: 2px;
}
.feat-lock {
  display: inline-flex; align-items: center; gap: 4px; margin-top: 6px;
  padding: 2px 8px; border-radius: 999px;
  font-size: var(--fs-xs); font-weight: 600;
  background: color-mix(in oklab, var(--color-accent) 15%, transparent);
  color: var(--color-accent);
}
.feat-lock svg { width: 12px; height: 12px; }

/* Perk list inside the mobile menu, shown to signed-out visitors. */
.mnav-perks { margin-top: 4px; }
.mnav-perks a { align-items: flex-start; }
.mnav-perks a small {
  display: block; font-size: var(--fs-xs); font-weight: 400;
  color: var(--color-muted-foreground); line-height: 1.6; margin-top: 1px;
}
.mnav-perk-all { font-weight: 700; color: var(--color-primary); }

/* ======================================================================
   MAP SELECTION CARD
   Picking a pin is a question — "what is this place?" — and answering it
   with a bare name made people open the full page just to find a phone
   number. Now the card answers the whole question where it was asked.
   ====================================================================== */
/* No `position` here: this rule sits AFTER .map-selected in the file, so
   declaring one silently overrode the absolute/fixed placement that puts the
   card on the map. .map-selected is already positioned, which is all the
   close button needs to anchor against. */
[data-map-selected] { display: grid; gap: 10px; }
/* 44px target, out of the way of the title, present at every width */
.ms-close {
  position: absolute; inset-inline-end: -4px; top: -4px;
  width: 40px; height: 40px; display: grid; place-items: center;
  border: 0; background: none; cursor: pointer; border-radius: 50%;
  color: var(--color-muted-foreground);
}
.ms-close svg { width: 19px; height: 19px; }
.ms-close:hover { background: color-mix(in oklab, var(--color-foreground) 8%, transparent); }
.ms-close:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
/* keep the title clear of it */
.ms-head { padding-inline-end: 34px; }
.ms-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.ms-head img { flex: none; }
.ms-title { flex: 1; min-width: 0; }
.ms-title strong { display: block; font-size: var(--fs-md); line-height: 1.4; }
.ms-sub { font-size: var(--fs-xs); color: var(--color-muted-foreground); }
.ms-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ms-stars { display: inline-flex; align-items: center; gap: 5px; font-size: var(--fs-sm); }
.ms-stars { color: var(--color-accent); }
.ms-stars b { color: var(--color-foreground); }
.ms-stars small { color: var(--color-muted-foreground); font-weight: 500; }
.ms-descr { font-size: var(--fs-sm); line-height: 1.75; margin: 0; }
.ms-row { font-size: var(--fs-xs); color: var(--color-muted-foreground); line-height: 1.7; }
.ms-acts { display: flex; gap: 8px; flex-wrap: wrap; }
.ms-acts .btn { flex: 1; min-width: 96px; justify-content: center; }
@media (max-width: 1024px) { .ms-acts .btn { min-height: 44px; } }

/* ======================================================================
   SUPPORT TICKETS
   The contact form used to post into a void. A ticket is the same message
   plus a status the sender can watch and a thread both sides can continue.
   ====================================================================== */
.tk-list { display: grid; gap: 8px; }
.tk-row {
  display: flex; align-items: center; gap: 10px;
  padding: 13px 14px; border-radius: var(--radius-lg);
  background: var(--glass-bg); border: 1px solid var(--glass-hairline);
  color: inherit; text-decoration: none;
  transition: background var(--dur-1) var(--ease-out);
}
.tk-row:hover { background: color-mix(in oklab, var(--color-primary) 7%, transparent); }
.tk-row > svg { width: 17px; height: 17px; color: var(--color-muted-foreground); flex: none; }
.tk-main { flex: 1; min-width: 0; }
.tk-main strong { display: block; line-height: 1.5; }
.tk-meta {
  font-size: var(--fs-xs); color: var(--color-muted-foreground);
  margin-top: 3px; line-height: 1.7;
}
.tk-meta a { color: inherit; }
.tk-dot {
  width: 9px; height: 9px; border-radius: 50%; flex: none;
  background: var(--color-accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-accent) 22%, transparent);
}

.tk-thread { display: grid; gap: 12px; }
.tk-bubble {
  max-width: min(100%, 560px);
  padding: 13px 16px; border-radius: var(--radius-xl);
  border: 1px solid var(--glass-hairline); background: var(--glass-bg);
}
.tk-bubble.is-me {
  margin-inline-start: auto;
  background: color-mix(in oklab, var(--color-primary) 9%, transparent);
  border-color: color-mix(in oklab, var(--color-primary) 24%, transparent);
}
.tk-bubble.is-admin {
  margin-inline-end: auto;
  background: color-mix(in oklab, var(--color-accent) 8%, transparent);
  border-color: color-mix(in oklab, var(--color-accent) 22%, transparent);
}
.tk-who {
  display: flex; align-items: center; gap: 6px;
  font-size: var(--fs-xs); color: var(--color-muted-foreground);
  margin-bottom: 6px;
}
.tk-who svg { width: 14px; height: 14px; }
.tk-who time { margin-inline-start: auto; }
.tk-bubble p { margin: 0; font-size: var(--fs-sm); line-height: 1.85; white-space: pre-wrap; }

/* ======================================================================
   PER-SHOP BACKGROUND
   A shopkeeper with a good photo of their storefront can put it behind
   their own page header. A scrim keeps the name and rating readable over
   any photo — a bright shopfront would otherwise swallow white text.
   ====================================================================== */
.biz-hero.has-cover {
  position: relative;
  background-image:
    linear-gradient(
      to bottom,
      color-mix(in oklab, var(--color-background) 78%, transparent),
      color-mix(in oklab, var(--color-background) 92%, transparent)),
    var(--cover);
  background-size: cover;
  background-position: center;
  border: 1px solid var(--glass-hairline);
}
/* v111: cover overlay now comes from the token wash (base rule). */

/* choosing that background, from photos already uploaded */
.cover-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 10px;
}
.cover-tile {
  position: relative; padding: 0; cursor: pointer;
  border: 2px solid transparent; border-radius: var(--radius-lg);
  overflow: hidden; background: none; aspect-ratio: 16/10;
}
.cover-tile img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cover-tile:hover { border-color: color-mix(in oklab, var(--color-primary) 45%, transparent); }
.cover-mark {
  position: absolute; inset-block-start: 6px; inset-inline-end: 6px;
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--color-primary); color: var(--color-on-primary);
  opacity: 0; transform: scale(.7);
  transition: all var(--dur-2) var(--ease-out);
}
.cover-mark svg { width: 15px; height: 15px; }
.cover-tile.is-on { border-color: var(--color-primary); }
.cover-tile.is-on .cover-mark { opacity: 1; transform: scale(1); }
@media (max-width: 1024px) { .cover-tile { min-height: 76px; } }

/* ======================================================================
   QR CODE
   Printed and stuck on the shop window. Research puts shop-window scan
   rates at 5-10%, against 1-3% for print advertising — but only when the
   destination is worth arriving at, which is why it points at the full
   page (hours, phone, catalogue) and not a bare card.
   ====================================================================== */
.qr-box { display: flex; gap: var(--space-lg); align-items: flex-start; flex-wrap: wrap; }
.qr-img {
  flex: none; width: 200px; height: 200px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--glass-hairline);
  background: #fff; padding: 8px;
}
.qr-txt { flex: 1; min-width: min(100%, 240px); }
.qr-txt p { font-size: var(--fs-sm); line-height: 1.85; margin: 0 0 8px; }
@media (max-width: 640px) {
  .qr-box { justify-content: center; }
  .qr-img { width: 180px; height: 180px; }
}

/* ======================================================================
   ADMIN INBOX  ·  everything waiting, in one list
   ====================================================================== */
.ib-list { display: grid; gap: 7px; }
.ib-row {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 13px; border-radius: var(--radius-lg);
  background: var(--glass-bg); border: 1px solid var(--glass-hairline);
  color: inherit; text-decoration: none;
}
.ib-row:hover { background: color-mix(in oklab, var(--color-primary) 7%, transparent); }
.ib-row > svg { width: 16px; height: 16px; color: var(--color-muted-foreground); flex: none; }
.ib-main { flex: 1; min-width: 0; }
.ib-main strong { display: block; line-height: 1.5; }
.ib-sub { font-size: var(--fs-xs); color: var(--color-muted-foreground); margin-top: 2px; }
.ib-when { font-size: var(--fs-xs); color: var(--color-muted-foreground); flex: none; }
.ib-more {
  display: inline-block; margin-top: 10px;
  font-size: var(--fs-sm); font-weight: 700; color: var(--color-primary);
}
@media (max-width: 640px) { .ib-when { display: none; } }

/* ======================================================================
   FEATURE SWITCHES
   ====================================================================== */
.feat-list { display: grid; gap: 8px; }
.feat-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; border-radius: var(--radius-lg);
  background: var(--glass-bg); border: 1px solid var(--glass-hairline);
  cursor: pointer;
}
.feat-row:hover { background: color-mix(in oklab, var(--color-primary) 6%, transparent); }
.feat-row input { width: 24px; height: 24px; flex: none; accent-color: var(--color-primary); }
.feat-ic { flex: none; display: grid; place-items: center; }
.feat-ic svg { width: 20px; height: 20px; color: var(--color-primary); }
.feat-txt { flex: 1; min-width: 0; }
.feat-txt strong { display: block; }
.feat-txt small {
  display: block; margin-top: 3px; font-size: var(--fs-xs);
  color: var(--color-muted-foreground); line-height: 1.7;
}
.feat-state {
  flex: none; font-size: var(--fs-xs); font-weight: 800;
  color: var(--color-muted-foreground);
}
.feat-row:has(input:checked) .feat-state { color: var(--color-primary); }
.feat-row:has(input:checked) {
  border-color: color-mix(in oklab, var(--color-primary) 30%, transparent);
}
@media (max-width: 640px) { .feat-state { display: none; } }

/* unread counter in the owner sidebar — the notification channel while
   SMS is not configured */
.nav-count {
  margin-inline-start: auto;
  min-width: 22px; height: 22px; padding: 0 6px;
  display: inline-grid; place-items: center;
  border-radius: 999px;
  background: var(--color-accent); color: var(--color-on-primary);
  font-size: 12px; font-weight: 800; flex: none;
}

/* ======================================================================
   HERO VISUAL  ·  static CSS composition (v75)
   No video, poster, JavaScript parallax, continuous animation or GPU hint.
   Layered turquoise geometry keeps the premium Iranian-night atmosphere at
   effectively zero transfer cost and respects reduced-motion by design.
   ====================================================================== */
.hero-visual {
  /* v111: flat stage — the page background token shows through, so the
     headline ink always sits on its own theme. */
  position: absolute; inset: 0; z-index: 0;
  overflow: hidden; pointer-events: none; isolation: isolate;
  background: none;
}
/* v111: the rings/girih ornament is retired with the luxury identity. */
.hero-visual::before, .hero-visual > span, .hero-visual > i { display: none !important; }
.hero-shade { position: absolute; inset: 0; z-index: 1; pointer-events: none; background: none; }
/* ======================================================================
   FEATURES BAND  ·  «امکانات سایت» — the first thing a visitor meets (v42)
   A dark emerald band with glass cards, glow orbs and staggered reveal.
   ====================================================================== */
.feat-band {
  position: relative; overflow: hidden;
  padding-block: var(--space-2xl) var(--space-2xl);
  background: var(--color-background-2);
  border-block: 1px solid var(--color-border);
  color: var(--color-foreground);
}
.feat-band .eyebrow { color: var(--color-primary-text); border-color: color-mix(in oklab, var(--color-primary-text) 40%, transparent); }
.feat-band h2 { color: var(--color-foreground); font-size: var(--fs-2xl); }
.feat-band p { color: var(--color-muted-foreground); }
.feat-head { max-width: 62ch; margin-bottom: var(--space-xl); }
.feat-head p { margin-top: 8px; font-size: var(--fs-sm); }
.feat-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.feat-card {
  position: relative; overflow: hidden;
  display: flex; align-items: flex-start; gap: 12px;
  padding: 16px; min-height: 92px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  background: var(--color-card);
  color: var(--color-card-foreground); text-decoration: none;
  transition: transform var(--dur-2) var(--ease-out), border-color var(--dur-2), background var(--dur-2);
}
.feat-card:hover { transform: translateY(-2px); border-color: var(--color-border-strong); }
.feat-ic {
  flex: none; display: grid; place-items: center;
  width: 44px; height: 44px; border-radius: 12px;
  color: var(--gold-300, var(--color-primary));
  background: color-mix(in oklab, var(--gold-400, var(--color-primary)) 14%, transparent);
  border: 1px solid color-mix(in oklab, var(--gold-400, var(--color-primary)) 26%, transparent);
}
.feat-ic svg { width: 22px; height: 22px; }
.feat-body { display: grid; gap: 3px; min-width: 0; }
.feat-body strong { font-size: var(--fs-sm); font-weight: 700; }
.feat-body small { font-size: 12px; line-height: 1.55; color: var(--color-muted-foreground); }
.feat-arrow { margin-inline-start: auto; align-self: center; color: var(--gold-300, var(--color-primary)); opacity: 0; transform: translateX(-6px); transition: all var(--dur-2); }
.feat-arrow svg { width: 16px; height: 16px; }
.feat-card:hover .feat-arrow { opacity: 1; transform: none; }
.feat-cta { margin-top: var(--space-lg); display: flex; justify-content: center; }
.feat-band .btn-glass { border-color: var(--color-border-strong); color: var(--color-foreground); background: var(--color-card); }
.feat-orb {
  position: absolute; border-radius: 50%; filter: blur(60px); opacity: .5; pointer-events: none;
}
.feat-orb-a { width: 340px; height: 340px; top: -140px; inset-inline-start: -120px; background: color-mix(in oklab, var(--brand-400) 55%, transparent); animation: orbFloat 11s ease-in-out infinite; }
.feat-orb-b { width: 300px; height: 300px; bottom: -120px; inset-inline-end: -90px; background: color-mix(in oklab, var(--accent-400) 45%, transparent); animation: orbFloat 14s ease-in-out infinite reverse; }
@keyframes orbFloat { 0%, 100% { transform: translateY(0) } 50% { transform: translateY(-26px) } }
@media (prefers-reduced-motion: reduce) { .feat-orb { animation: none; } }

@media (max-width: 1024px) {
  .feat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 420px) {
  .feat-card { padding: 14px; min-height: 84px; }
  .feat-ic { width: 40px; height: 40px; }
}

/* Username/password login toggle on the auth pages (v57) */
.auth-alt summary { list-style: none; display: flex; justify-content: center; }
.auth-alt summary::-webkit-details-marker { display: none; }
.auth-alt .field { margin-bottom: var(--space-md); }

/* ==========================================================================
   PASSWORD REMINDER (v58) — the security nudge after phone-OTP sign-in
   Prominent but non-blocking: sits at the top of the dashboard, states the
   benefit, one CTA + a dismiss. Dismissed via sessionStorage (returns on the
   next sign-in until a password is actually set).
   ========================================================================== */
.pw-reminder {
  display: flex; align-items: center; gap: 14px;
  margin-bottom: var(--space-lg);
  padding: 14px 16px;
  border-radius: var(--radius-lg);
  background: color-mix(in oklab, var(--color-warning) 10%, var(--color-card));
  border: 1px solid color-mix(in oklab, var(--color-warning) 35%, transparent);
  box-shadow: var(--e1);
}
.pw-reminder-ic {
  flex: none; width: 44px; height: 44px; border-radius: 12px;
  display: grid; place-items: center;
  background: color-mix(in oklab, var(--color-warning) 18%, transparent);
  color: var(--color-warning);
}
.pw-reminder-ic svg { width: 22px; height: 22px; }
.pw-reminder-body { flex: 1; min-width: 0; }
.pw-reminder-body strong { font-size: var(--fs-base); font-weight: 800; }
.pw-reminder-body p { margin-top: 2px; font-size: var(--fs-sm); color: var(--color-muted-foreground); line-height: 1.6; }
.pw-reminder .btn { flex: none; }
.pw-reminder-x {
  flex: none; width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  color: var(--color-muted-foreground);
}
.pw-reminder-x:hover { background: var(--color-muted); color: var(--color-foreground); }
.pw-reminder-x svg { width: 16px; height: 16px; }
@media (max-width: 560px) {
  .pw-reminder { flex-wrap: wrap; }
  .pw-reminder .btn { width: 100%; justify-content: center; }
}

/* ---- v93: admin command palette (Ctrl+K) ---- */
.cmdk { position: fixed; inset: 0; z-index: var(--z-modal); background: rgba(2,6,18,.55);
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  display: flex; align-items: flex-start; justify-content: center; padding: 12vh 16px 16px; }
.cmdk[hidden] { display: none; }
.cmdk-box { width: min(560px,100%); background: var(--color-card); border: 1px solid var(--color-border);
  border-radius: 16px; box-shadow: var(--e4); overflow: hidden; }
.cmdk-box input { width: 100%; border: 0; background: transparent; padding: 14px 16px; font-size: 16px;
  color: var(--color-foreground); outline: none; border-bottom: 1px solid var(--color-border); }
.cmdk-list { max-height: 52vh; overflow: auto; padding: 6px; }
.cmdk-item { display: flex; align-items: center; gap: 10px; padding: 11px 12px; border-radius: 10px;
  color: var(--color-foreground); font-size: 14px; font-weight: 600; }
.cmdk-item:hover { background: var(--color-muted); }
.cmdk-item svg { width: 18px; height: 18px; color: var(--color-muted-foreground); flex: none; }
.cmdk-item.cmdk-action { color: var(--color-primary); }
.cmdk-empty { padding: 18px; text-align: center; color: var(--color-muted-foreground); font-size: 13px; }
.cmdk-kbd { font-size: 12px; color: var(--color-muted-foreground); border: 1px solid var(--color-border);
  border-radius: 6px; padding: 2px 5px; margin-inline-start: 4px; font-family: inherit; }

/* ---- v99: in-browser media compressor UI (story composer) ---- */
.cz { margin-top: .5rem; }
.cz-status { font-size: 12px; color: var(--color-muted-foreground); display: flex; align-items: center; gap: 6px; margin: 0; }
.cz.is-busy .cz-status::before { content: ""; width: 14px; height: 14px; border: 2px solid var(--color-border); border-top-color: var(--color-primary); border-radius: 50%; animation: cz-spin .7s linear infinite; flex: 0 0 auto; }
@keyframes cz-spin { to { transform: rotate(360deg); } }
.cz-preview { display: flex; align-items: center; gap: 10px; margin-top: .5rem; padding: 8px; border: 1px solid var(--color-border); border-radius: 12px; background: var(--color-card); }
.cz-media img, .cz-media video { max-height: 150px; max-width: 150px; border-radius: 10px; display: block; object-fit: cover; }
.cz-meta { display: flex; flex-direction: column; gap: 8px; }
.cz-size { font-size: 12px; color: var(--color-muted-foreground); }

/* ---- v100: video trim UI + story row + anonymised view stats ---- */
.story-row-main { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.story-stats { margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--color-border); }
.story-stats-head { font-size: 13px; }
.story-stats-days { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 4px; }
.story-stats-days li { display: flex; justify-content: space-between; font-size: 12px; color: var(--color-muted-foreground); }

/* ---- v101: owner story preview thumbnail ---- */
.story-thumb-btn { position: relative; padding: 0; border: 0; background: none; cursor: pointer; line-height: 0; border-radius: 12px; }
.story-thumb-btn .story-vid-tag { position: absolute; inset: 0; display: grid; place-items: center; color: #fff; font-size: 18px; background: rgba(0,0,0,.35); border-radius: 12px; }

/* ======================================================================
   v109 — LIVE ANIMATION LAYER
   همهٔ بخش‌هایی که «زنده» هستند یک نبض بصری دارند. همه چیز ذیل
   prefers-reduced-motion را رعایت می‌کند (WCAG 2.3.3).
   ====================================================================== */

/* ---- 1) story presence: the ring slowly breathes so «استوری زنده» reads
   at a glance; the gradient itself stays the identity marker ---- */
.biz-card .card-media.story-ring::after {
  content: ""; position: absolute; inset: -3px; border-radius: inherit;
  box-shadow: 0 0 0 0 var(--story-ring-glow, color-mix(in oklab, var(--color-primary) 40%, transparent));
  animation: storyBreath 2.6s var(--ease-inout) infinite;
  pointer-events: none; z-index: 2;
}
@keyframes storyBreath {
  0%   { box-shadow: 0 0 0 0 var(--story-ring-glow, color-mix(in oklab, var(--color-primary) 40%, transparent)); }
  55%  { box-shadow: 0 0 14px 3px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}
.story-chip svg { animation: storyChipNudge 2.6s var(--ease-inout) infinite; }
@keyframes storyChipNudge { 0%, 100% { transform: scale(1) } 50% { transform: scale(1.18) } }

/* ---- 2) open-now badge: the clock badge gets a live dot, matching the
   .open-line pulse that already exists ---- */
.badge-open { position: relative; }
.badge-open::before {
  content: ""; width: 7px; height: 7px; flex: none; border-radius: 50%;
  background: currentColor; order: -1;
  animation: liveDot 2.4s ease-out infinite;
}
.badge-warn::before {
  content: ""; width: 7px; height: 7px; flex: none; border-radius: 50%;
  background: currentColor; order: -1;
  animation: liveDot 1.1s ease-out infinite;
}
@keyframes liveDot {
  0%   { opacity: 1; box-shadow: 0 0 0 0 color-mix(in oklab, currentColor 45%, transparent); }
  70%  { opacity: .75; box-shadow: 0 0 0 5px transparent; }
  100% { opacity: 1; box-shadow: 0 0 0 0 transparent; }
}

/* ---- 3) chat: messages pop in — a conversation should feel alive ---- */
.msg { animation: msgIn var(--dur-3) var(--ease-out) both; }
@keyframes msgIn { from { opacity: 0; transform: translateY(8px) scale(.98) } to { opacity: 1; transform: none } }

/* ---- 4) deal countdown urgency: under one hour it ticks hot ---- */
.deal-countdown.is-urgent { color: var(--color-danger-text); animation: urgentTick 1s steps(1) infinite; }
@keyframes urgentTick { 50% { opacity: .55 } }

/* ---- 5) UpBar v2 — real upload: ring spinner spins while bytes move,
   keeps spinning in the «در حال پردازش» phase (server working), error
   shakes once. The old static arrow icon is replaced by the ring in markup. */
.up-progress .up-ring { position: relative; flex: none; width: 26px; height: 26px; }
.up-progress .up-ring::before {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  border: 3px solid color-mix(in oklab, currentColor 22%, transparent);
  border-top-color: currentColor;
  animation: spin .8s linear infinite;
}
.up-progress .up-ring::after {
  content: ""; position: absolute; inset: 7px; border-radius: 50%;
  background: color-mix(in oklab, currentColor 30%, transparent);
  transition: transform .2s var(--ease-spring);
}
.up-progress.is-done .up-ring::after { transform: scale(1.35); }
.up-progress { transition: opacity .3s ease, transform .3s var(--ease-out); }
.up-progress:not(.is-on) { opacity: 0; transform: translateY(10px); pointer-events: none; }
.up-progress.is-err { animation: upShake .4s var(--ease-out); }
@keyframes upShake {
  0%, 100% { transform: translateX(0) }
  25% { transform: translateX(-5px) } 55% { transform: translateX(5px) } 80% { transform: translateX(-3px) }
}
.up-progress .up-fill { position: relative; overflow: hidden; }
.up-progress .up-fill::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.45), transparent);
  transform: translateX(-100%);
  animation: upSheen 1.2s linear infinite;
}
@keyframes upSheen { to { transform: translateX(100%) } }

/* ---- 6) trash rows: restore target feedback ---- */
.trash-row-restored { animation: restoredFlash 1.2s var(--ease-out); }
@keyframes restoredFlash {
  0% { background: color-mix(in oklab, var(--color-success) 26%, transparent) }
  100% { background: transparent }
}

/* ---- 7) global safety: no live animation without consent ---- */
@media (prefers-reduced-motion: reduce) {
  .biz-card .card-media.story-ring::after, .story-chip svg, .badge-open::before,
  .badge-warn::before, .msg, .deal-countdown.is-urgent,
  .up-progress .up-ring::before, .up-progress .up-fill::after, .up-progress.is-err {
    animation: none !important;
  }
}

/* ═══ v117/M4 — panel bulk ops, stretched ticket link, mobile filter fold ═══ */
.tk-row { position: relative; }
.tk-link { position: absolute; inset: 0; border-radius: inherit; z-index: 1; }
/* v330-stage8: ticket row controls are used in bulk moderation; keep each
   direct target at the 44px tap floor without changing the stretched row link. */
.tk-row .tk-tel { position: relative; z-index: 2; min-width: var(--tap); min-height: var(--tap); display: inline-flex; align-items: center; }
input.tk-check { position: relative; z-index: 2; width: var(--tap); height: var(--tap);
  min-width: var(--tap); min-height: var(--tap); accent-color: var(--color-primary); flex: none; }
.tk-row:hover { background: color-mix(in oklab, var(--color-primary) 7%, transparent); }

.bulk-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px; margin-bottom: var(--space-lg); border-radius: var(--radius-lg);
  background: var(--glass-bg); border: 1px dashed var(--glass-hairline); }
.bulk-bar .select { min-width: 150px; }
.bulk-bar .chip { cursor: pointer; user-select: none; }

.rev-check { float: right; margin: 4px 0 0 8px; width: 20px; height: 20px;
  accent-color: var(--color-primary); }
/* v118: bare checkboxes in the reviews table (row select + «انتخاب همه») had
   no expanded hit area like .check inputs do — a 20px target. Grow the hit
   area with a pseudo-element, keeping the visible box small. */
.rev-check, .bulk-select-all input[type="checkbox"],
input.rev-check { position: relative; }
.rev-check::after, .bulk-select-all input[type="checkbox"]::after {
  content: ''; position: absolute; inset: -12px; }
article.review:has(.rev-check:checked) { outline: 2px solid var(--color-primary);
  outline-offset: 2px; border-radius: var(--radius-md); }

@media (max-width: 768px) {
  .dir-toolbar[data-foldable="1"] .dir-row { display: none; }
  .dir-toolbar[data-foldable="1"].is-open .dir-row { display: flex; flex-wrap: wrap; }
  .dir-toolbar .filters-toggle { display: inline-flex; }
  .bulk-bar { position: sticky; bottom: 8px; z-index: 5; backdrop-filter: blur(8px); }
}
.filters-toggle { display: none; }

/* ═══ v117/M5 — moderation queue & audit filters ═══ */
.mod-item { flex: 1 1 auto; min-width: 0; display: grid; }
.mod-item small { font-weight: 500; }
.todo-item form { margin-inline-start: auto; display: flex; gap: 2px; }
.todo-item form:first-of-type { margin-inline-start: auto; }
.todo-item .btn-icon { min-width: 44px; min-height: 44px; }
.btn-icon.btn-approve { color: var(--color-success, #1a9e4b); }
.btn-icon.btn-approve:hover { background: color-mix(in oklab, var(--color-success, #1a9e4b) 14%, transparent); }
.card-title a { margin-inline-start: auto; font-weight: 500; text-decoration: none; }
.card-title a:hover { text-decoration: underline; }
@media (max-width: 700px) {
  .todo-item form:first-of-type { margin-inline-start: 0; }
  .todo-item { flex-wrap: wrap; }
}

/* ==========================================================================
   v119 — صفحهٔ اصلی بازطراحی‌شده (هیرو + اجزای h-*)
   نسخهٔ قبلی هیرو حذف شد؛ این بلوک طراحی نو است: سبز روشن، کوتاه، یکدست.
   ========================================================================== */

/* ==========================================================================
   صفحهٔ اصلی (v120) — هیروی «سبز زنده»
   قانون: متن سفید فقط روی سطح برند؛ کارت‌های روشن = متن تیره.
   ========================================================================== */
/* ==========================================================================
   صفحهٔ اصلی — هیروی مدرن، دلنشین و یکپارچهٔ بازارچه (Persian Modern Hero)
   ========================================================================== */
.h-hero {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(40rem 22rem at 92% -8%, color-mix(in oklab, var(--brand-300) 26%, transparent), transparent 60%),
    radial-gradient(34rem 22rem at -6% 108%, color-mix(in oklab, var(--amber-300) 32%, transparent), transparent 58%),
    radial-gradient(28rem 18rem at 58% -14%, color-mix(in oklab, var(--amber-400) 16%, transparent), transparent 55%),
    linear-gradient(180deg, #fdf6ec 0%, var(--color-background) 100%);
  padding: clamp(24px, 4vw, 48px) 0 0;
  border-bottom: 1px solid var(--color-border);
}
.h-hero::after {
  content: ""; position: absolute; z-index: 0;
  inset: auto -6rem -8rem auto; width: 22rem; height: 22rem; border-radius: 50%;
  background: radial-gradient(circle, color-mix(in oklab, var(--amber-300) 22%, transparent) 0%, transparent 68%);
  pointer-events: none;
}
.h-hero-in {
  position: relative; z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(260px, 0.65fr);
  gap: clamp(20px, 4vw, 56px);
  align-items: center;
  padding-bottom: clamp(24px, 4vw, 44px);
}

.h-hero-badge {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  padding: 6px 14px; border-radius: 999px;
  font-size: 13px; font-weight: 700; color: var(--color-primary);
  box-shadow: var(--e1);
}
.h-hero-badge .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--color-primary); box-shadow: 0 0 8px var(--color-primary); }
.h-hero-badge svg { width: 15px; height: 15px; color: var(--color-primary); }

.h-hero-copy h1 {
  font-size: clamp(1.6rem, 2.8vw, 2.5rem);
  line-height: 1.32; margin: 16px 0 10px; color: var(--color-foreground);
  font-weight: 800; text-wrap: balance;
}

.h-hero-lead { color: var(--color-muted-foreground); font-size: 1rem; max-width: 52ch; margin: 0; line-height: 1.6; }

.h-hero-search { display: flex; gap: 10px; margin: 22px 0 18px; }
.h-hero-search .search-wrap { flex: 1; position: relative; display: block; }
.h-hero-search .input {
  height: 48px; border-radius: 12px;
  background: var(--color-card);
  border: 1.5px solid var(--color-border-strong);
  box-shadow: var(--e2);
  color: var(--color-foreground);
}
.h-hero-search .input:focus {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-primary) 18%, transparent);
}
.h-hero-search .btn {
  height: 48px; border-radius: 12px;
  background: var(--color-primary); color: var(--color-on-primary);
  border: 1px solid transparent;
  font-weight: 700;
}
.h-hero-search .btn:hover { background: var(--color-primary-hover); }

.h-hero-cta { display: flex; gap: 10px; flex-wrap: wrap; }
.h-hero-cta .btn { min-height: 46px; border-radius: 12px; }
/* دکمهٔ کنشی هیرو: زعفرانی گرم و پرانرژی */
.h-hero-cta .btn-accent {
  background: var(--amber-500); color: #ffffff;
  border: none; font-weight: 800;
  box-shadow: 0 4px 14px color-mix(in oklab, var(--amber-500) 35%, transparent);
}
.h-hero-cta .btn-accent:hover { background: var(--accent-600); transform: translateY(-1px); }
.h-hero-cta .btn-glass {
  background: var(--color-card);
  border: 1.5px solid var(--color-border);
  color: var(--color-foreground);
  box-shadow: var(--e1);
}
.h-hero-cta .btn-glass:hover { background: var(--color-muted); border-color: var(--color-border-strong); }

.h-hero-trust {
  display: flex; flex-wrap: wrap; gap: 6px 20px;
  color: var(--color-muted-foreground); font-size: 13px; margin-top: 18px;
}
.h-hero-trust svg { width: 16px; height: 16px; vertical-align: -3px; color: var(--color-primary); }

/* پنل «باز هستند» — کارت شیک روی زمینهٔ اصلی */
.h-open {
  background: var(--color-card); border: 1px solid var(--color-border);
  border-radius: 20px; padding: 18px; box-shadow: var(--e3);
}
.h-open-head {
  display: flex; gap: 8px; align-items: center;
  font-weight: 800; margin-bottom: 12px; color: var(--color-foreground);
}
.h-open-head svg { width: 18px; height: 18px; color: var(--color-primary); }
.h-open-list { display: grid; gap: 8px; }

/* ردیف آمار — فشرده و یکدست */
.h-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; }

/* تخفیف‌های لحظه‌ای */
.h-deals { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px; }
.h-deal {
  border: 1px solid var(--color-border); border-radius: 18px;
  background: var(--color-card);
  box-shadow: var(--e2);
}
.h-deal .card-title { color: var(--color-foreground); }
.h-deal .deal-countdown { color: var(--color-muted-foreground); }
.h-deal .deal-countdown.is-urgent { color: var(--color-warning-text); }
.h-deal .badge-accent {
  background: var(--color-accent); color: var(--color-on-accent);
  border-color: transparent; font-weight: 800;
}
.h-deal .btn { background: var(--color-primary); color: var(--color-on-primary); border: none; }
.h-deal .btn:hover { background: var(--color-primary-hover); }

@media (max-width: 860px) {
  .h-hero-in { grid-template-columns: 1fr; }
  .h-hero-search { flex-direction: row; }
  .h-hero-search .btn { width: auto; }
}

/* حالت شب: هیروی آبسیدین لاجوردی */
:root[data-theme="dark"] .h-hero,
:root[data-theme="night"] .h-hero,
:root[data-theme="luxury"] .h-hero {
  background:
    radial-gradient(40rem 22rem at 92% -8%, rgba(45, 212, 191, 0.12), transparent 60%),
    radial-gradient(32rem 20rem at -5% 105%, rgba(245, 158, 11, 0.08), transparent 58%),
    linear-gradient(180deg, #0d1520 0%, var(--color-background) 100%);
  border-bottom-color: var(--color-border);
}
    radial-gradient(42rem 24rem at 88% -12%, color-mix(in oklab, var(--brand-400) 30%, transparent), transparent 62%),
    radial-gradient(30rem 20rem at -8% 110%, color-mix(in oklab, var(--brand-300) 20%, transparent), transparent 55%),
    linear-gradient(160deg, #0d2e1d 0%, #0a2417 52%, #071c11 100%);
}
:root[data-theme="dark"] .h-deal { background: linear-gradient(160deg, #123724 0%, #0b2418 100%); }
:root[data-theme="dark"] .h-deal .badge-accent { background: var(--brand-500); color: #05240f; }

/* ==========================================================================
   دسته‌ها — کارت‌های تصویری بزرگ (v120) به سبک دیوار: هنرِ نئونی + شمار زنده
   ========================================================================== */
.h-cat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.h-catcard {
  position: relative; display: flex; flex-direction: column; justify-content: flex-end; gap: 5px;
  min-height: 136px; padding: 16px; border-radius: 18px; overflow: hidden;
  text-decoration: none;
  background:
    radial-gradient(10rem 8rem at 12% -12%, color-mix(in oklab, var(--brand-300) 60%, transparent), transparent 70%),
    radial-gradient(8rem 8rem at 108% 118%, color-mix(in oklab, var(--brand-500) 26%, transparent), transparent 72%),
    linear-gradient(165deg, var(--brand-100) 0%, var(--brand-200) 100%);
  border: 1px solid color-mix(in oklab, var(--brand-500) 30%, transparent);
  transition: transform var(--dur-3) var(--ease-out), box-shadow var(--dur-3) var(--ease-out);
}
.h-catcard:hover {
  transform: translateY(-4px);
  box-shadow: var(--e4), 0 12px 30px color-mix(in oklab, var(--brand-500) 26%, transparent);
}
.h-catcard:focus-visible { outline: 2px solid var(--color-ring); outline-offset: 2px; }
.h-catcard-ic { position: absolute; top: 12px; inset-inline-start: 12px; opacity: .96; transition: transform var(--dur-3) var(--ease-out); filter: drop-shadow(0 6px 14px color-mix(in oklab, var(--brand-700) 35%, transparent)); }
.h-catcard-ic img { width: 46px; height: 46px; }
.h-catcard:hover .h-catcard-ic { transform: scale(1.1) rotate(-3deg); }
.h-catcard-name { font-weight: 800; font-size: var(--fs-md); color: var(--brand-900); }
.h-catcard-nums { font-size: var(--fs-xs); font-weight: 700; color: var(--brand-700); }

@media (max-width: 900px) { .h-cat-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 640px) {
  .h-cat-grid { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .h-catcard { min-height: 120px; padding: 12px; }
  .h-catcard-ic img { width: 38px; height: 38px; }
}

/* حالت شب — کارت دسته: سبزِ تیره با شبنم نئونی */
:root[data-theme="dark"] .h-catcard,
:root[data-theme="night"] .h-catcard,
:root[data-theme="luxury"] .h-catcard {
  background:
    radial-gradient(10rem 8rem at 12% -12%, color-mix(in oklab, var(--brand-400) 26%, transparent), transparent 70%),
    linear-gradient(165deg, #14291d 0%, #0d1f16 100%);
  border-color: color-mix(in oklab, var(--brand-500) 34%, transparent);
}
:root[data-theme="dark"] .h-catcard-name { color: var(--color-on-brand); }
:root[data-theme="dark"] .h-catcard-nums { color: var(--brand-300); }

/* ---------- v352: compact, non-overlay recently viewed cards ---------- */
#recent-wrap[hidden] { display: none !important; }
.recent-row {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: clamp(168px, 22vw, 220px);
  gap: 12px;
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  scroll-snap-type: inline proximity;
  scrollbar-width: thin;
  padding: 2px 2px 12px;
}
.recent-card.card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 0;
  overflow: hidden;
  position: relative;
  scroll-snap-align: start;
  text-decoration: none;
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  background: var(--color-card);
  box-shadow: var(--e1);
  transition: transform var(--dur-2) var(--ease-out),
              border-color var(--dur-2) var(--ease-out),
              box-shadow var(--dur-2) var(--ease-out);
}
.recent-card.card:hover {
  transform: translateY(-2px);
  border-color: var(--color-primary);
  box-shadow: var(--e2);
}
.recent-card.card:focus-visible { outline: 2px solid var(--color-ring); outline-offset: 2px; }
.recent-card img,
.recent-ph {
  width: 100%;
  aspect-ratio: 16 / 10;
  flex: none;
  object-fit: cover;
  border-radius: 0;
  background: linear-gradient(145deg, var(--brand-700), var(--brand-500));
  color: var(--color-on-brand);
  font-size: var(--fs-2xl);
  font-weight: 900;
}
.recent-card img { display: block; }
.recent-ph { display: grid; place-items: center; }
.recent-name {
  display: -webkit-box;
  position: static;
  width: auto;
  min-height: 50px;
  padding: 10px 12px 12px;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  color: var(--color-foreground);
  background: transparent;
  border: 0;
  font-size: var(--fs-sm);
  font-weight: 800;
  line-height: 1.65;
  text-align: start;
}
@media (max-width: 640px) {
  .recent-row { grid-auto-columns: minmax(156px, 72vw); gap: 10px; }
  .recent-name { min-height: 46px; padding: 9px 10px 11px; }
}

/* ========================================================================== 
   v137 — story trim scrubber (dual-handle, mobile-first).
   Replaces the confusing millisecond number-steppers of v131 with:
     · two draggable handles (44px touch targets) over the clip timeline,
     · a filled window that can be slid as a whole,
     · tap the track to preview any moment,
     · − / + fine-tune to 0.1s, and «پخش نمونه» verifies the chosen slice.
   ========================================================================== */
.cz-trim { margin-top: .5rem; padding: 10px; border: 1px solid var(--color-border); border-radius: 12px; background: var(--color-card); }
.cz-trim-msg { font-size: 13px; font-weight: 600; margin: 0 0 8px; color: var(--color-foreground); }
.cz-trim-video { width: 100%; max-height: 200px; border-radius: 10px; background: #000; display: block; margin-bottom: 6px; }
.cz-video-wrap { position: relative; display: block; margin-bottom: 6px; }.cz-video-wrap .cz-trim-video { margin-bottom: 0; cursor: pointer; width: 100%; max-height: 200px; border-radius: 10px; background: #000; display: block; }.cz-video-play { position: absolute; inset: 0; margin: auto; width: 64px; height: 64px; border-radius: 50%;  background: color-mix(in oklab, #000 55%, transparent); color: #fff; font-size: 22px; border: 0;  display: grid; place-items: center; cursor: pointer; transition: transform .15s ease, background .15s ease;  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); }.cz-video-play.is-on { background: color-mix(in oklab, var(--color-primary, #0b6059) 78%, transparent); }.cz-video-play:active { transform: scale(.92); }.cz-video-wrap video::-webkit-media-controls { display: none !important; }

.cz-scrub { margin: 4px 2px 2px; }
.cz-track { position: relative; height: 44px; touch-action: none; }
.cz-line { position: absolute; left: 0; right: 0; top: 50%; height: 6px; transform: translateY(-50%); border-radius: 999px; background: var(--color-border); }
.cz-range { position: absolute; top: 50%; height: 6px; transform: translateY(-50%); border-radius: 999px; background: var(--color-primary); opacity: .9; touch-action: none; cursor: grab; }
.cz-h {
  position: absolute; top: 50%; width: 44px; height: 44px; margin: -22px 0 0 -22px;
  border: 0; padding: 0; background: transparent; cursor: grab;
  touch-action: none; -webkit-tap-highlight-color: transparent;
}
.cz-h::before {
  content: ""; position: absolute; left: 50%; top: 50%; width: 20px; height: 20px;
  border-radius: 50%; transform: translate(-50%, -50%);
  background: var(--color-card); border: 3px solid var(--color-primary);
  box-shadow: 0 1px 4px rgba(0, 0, 0, .28);
  transition: transform .15s ease;
}
.cz-h:active::before, .cz-h.is-drag::before { transform: translate(-50%, -50%) scale(1.14); }
.cz-times { display: flex; justify-content: space-between; align-items: center; gap: 6px; font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--color-muted-foreground); }
.cz-times .nums { color: var(--color-foreground); }
.cz-dur { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: 999px; padding: 2px 8px; font-size: 12px; color: var(--color-muted-foreground); }
.cz-edit { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 8px; }
.cz-edit .btn { min-height: 44px; }
.cz-edit-hint { margin: 0; flex-basis: 100%; font-size: 12px; color: var(--color-muted-foreground); line-height: 1.6; }

.cz-sidebar { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }
.cz-side { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.cz-side-box { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; }
.cz-side-label { font-size: 12px; color: var(--color-muted-foreground); }
.cz-val {
  min-width: 84px; height: 44px; display: grid; place-items: center;
  font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums;
  border: 1px solid var(--color-border); border-radius: 12px;
  background: var(--color-background); color: var(--color-foreground); padding: 0 6px;
}
.cz-step {
  flex: none; width: 44px; height: 44px; border-radius: 12px;
  display: grid; place-items: center; cursor: pointer;
  font-size: 22px; font-weight: 700; line-height: 1; color: var(--color-foreground);
  background: var(--color-surface); border: 1px solid var(--color-border);
  transition: background var(--dur-2), transform var(--dur-2);
  -webkit-tap-highlight-color: transparent; user-select: none; touch-action: manipulation;
}
.cz-step:active { transform: scale(.92); background: var(--color-muted); }
.cz-trim-hint { font-size: 12px; color: var(--color-muted-foreground); margin: 8px 0 0; line-height: 1.7; }
.cz-sample { margin-top: 8px; }
.cz-play { min-height: 44px; }
.cz-play.is-on { border-color: var(--color-primary); color: var(--color-primary); }
.cz-trim-actions { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.cz-trim-actions .btn { min-height: 44px; }

/* ============================================================ v139: card-to-card */
.pay-box .pay-steps{list-style:none;margin:0 0 14px;padding:0;display:grid;gap:8px}
.pay-steps li{display:flex;gap:10px;align-items:flex-start;font-size:13px;line-height:1.9;color:var(--color-body)}
.pay-steps li>span{flex:0 0 26px;height:26px;border-radius:50%;display:grid;place-items:center;
  background:color-mix(in oklab,var(--color-primary) 14%,transparent);
  color:var(--color-primary);font-weight:700;font-size:13px;margin-top:2px}
.pay-card-row{flex-wrap:wrap;gap:8px}
.pay-card-no{font-weight:700;letter-spacing:.5px;font-size:15px}
.copy-card{transition:border-color .2s,color .2s}
.copy-card.is-copied{border-color:var(--color-success,#16a34a);color:var(--color-success,#16a34a)}
.field-hint{font-size:12px;color:var(--color-muted-foreground,#6b7280);margin:5px 0 0}
/* admin payment table extras */
.pay-cell{min-width:180px;font-size:12px}
.pay-cell .badge{margin-bottom:4px}
.pay-ref{direction:ltr;text-align:right;font-size:12px;color:var(--color-body);word-break:break-all}
.pay-note{font-size:12px;color:var(--color-muted-foreground,#6b7280);margin-top:2px;max-width:220px;white-space:normal}
.pay-receipt{display:inline-flex;align-items:center;gap:6px;margin-top:6px;font-size:12px;
  color:var(--color-primary);text-decoration:none;position:relative}
.pay-receipt img{width:52px;height:52px;object-fit:cover;border-radius:var(--radius-md,10px);
  border:1px solid var(--color-border);cursor:zoom-in}

/* ============================================================ v140: modern card-to-card pay box */
.pay-head{display:flex;gap:12px;align-items:flex-start;margin-bottom:6px}
.pay-head>svg{flex:0 0 auto;width:30px;height:30px;color:var(--color-primary);
  background:color-mix(in oklab,var(--color-primary) 12%,transparent);
  border-radius:10px;padding:6px;box-sizing:content-box}
.pay-head .card-title{font-size:var(--fs-lg,18px)}
.pay-sub{margin:4px 0 0;font-size:13px;color:var(--color-muted-foreground,#6b7280)}
.pay-sub strong{color:var(--color-foreground)}
.pay-card-box{margin-top:4px;border:1px dashed color-mix(in oklab,var(--color-primary) 45%,transparent);
  background:color-mix(in oklab,var(--color-primary) 6%,transparent);
  border-radius:16px;padding:16px 16px 12px}
.pay-card-label{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--color-muted-foreground,#6b7280);margin-bottom:8px}
.pay-card-label svg{width:16px;height:16px;color:var(--color-primary)}
.pay-card-line{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}
.pay-card-line .pay-card-no{font-size:21px;letter-spacing:1px;font-weight:800;direction:ltr;color:var(--color-foreground)}
.pay-card-line .copy-card{min-height:44px}
.pay-card-line .copy-card.is-copied{border-color:var(--color-success,#16a34a);color:var(--color-success,#16a34a)}
.pay-card-meta{display:flex;flex-wrap:wrap;gap:6px 16px;margin-top:10px;padding-top:10px;
  border-top:1px solid color-mix(in oklab,var(--color-primary) 18%,transparent)}
.pay-card-meta span{display:inline-flex;align-items:center;gap:6px;font-size:13px;color:var(--color-body)}
.pay-card-meta svg{width:16px;height:16px;color:var(--color-muted-foreground,#6b7280)}
.pay-cta{margin-top:4px}
.pay-meta{margin-top:8px;display:grid;gap:2px}
.pay-meta .info-row{font-size:12px}
/* receipt lightbox (manager panel) */
.lb{position:fixed;inset:0;background:rgba(10,14,20,.86);display:grid;place-items:center;
  z-index:220;padding:26px;backdrop-filter:blur(4px)}
.lb img{max-width:min(92vw,780px);max-height:88vh;object-fit:contain;border-radius:14px;
  box-shadow:0 26px 70px rgba(0,0,0,.55)}
.lb-x{position:absolute;top:16px;inset-inline-start:16px;width:46px;height:46px;border-radius:50%;
  background:rgba(255,255,255,.14);color:#fff;border:0;font-size:26px;line-height:1;cursor:pointer;
  display:grid;place-items:center;z-index:1}
.lb-x:hover{background:rgba(255,255,255,.28)}
.lb[hidden]{display:none !important}

/* v141: dedicated public page link next to the owner's QR/barcode */
.qr-link{margin-top:2px}
.qr-link-row{display:flex;gap:8px;flex-wrap:wrap}
.qr-link-row .input{flex:1;min-width:170px;direction:ltr;text-align:left}
.qr-link-row .copy-link{min-height:44px}
.qr-link-row .copy-link.is-copied{border-color:var(--color-success,#16a34a);color:var(--color-success,#16a34a)}

/* ---------- v208: staged business registration wizard (/register-business) ---------- */
/* ---- v209: wizard visual refresh ---- */
.rw{--rw-accent:var(--color-primary);--rw-soft:color-mix(in srgb,var(--color-primary) 10%,transparent)}
.rw-hero{display:flex;align-items:center;gap:16px;margin-bottom:var(--space-md)}
.rw-hero .eyebrow{color:var(--rw-accent);font-weight:700;font-size:var(--text-sm);margin:0 0 2px}
.rw-hero .page-title{margin:0}
.rw-sub{margin:4px 0 0;color:var(--color-text-muted);font-size:var(--text-sm);max-width:52ch}
.rw-ring{--p:0;flex:none;width:64px;height:64px;border-radius:50%;display:grid;place-items:center;
  background:conic-gradient(var(--rw-accent) calc(var(--p)*1%),color-mix(in srgb,var(--rw-accent) 15%,transparent) 0);
  transition:background .4s ease}
.rw-ring span{width:50px;height:50px;border-radius:50%;background:var(--color-surface,#fff);display:grid;place-items:center;color:var(--rw-accent)}
.rw-ring svg{width:22px;height:22px}
.rw-stepper{margin:0 0 var(--space-lg);--rw-pct:0%}
.rw-track{height:4px;border-radius:999px;background:color-mix(in srgb,var(--rw-accent) 14%,transparent);overflow:hidden}
.rw-fill{display:block;height:100%;width:var(--rw-pct);background:linear-gradient(90deg,var(--rw-accent),color-mix(in srgb,var(--rw-accent) 60%,#7dd3c0));transition:width .4s ease}
.rw-steps{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-top:10px}
.rw-step{display:flex;flex-direction:column;align-items:center;gap:6px;padding:6px 2px;border-radius:var(--radius-md);font-size:var(--text-xs);color:var(--color-text-muted);text-decoration:none;min-height:44px}
.rw-dot{display:grid;place-items:center;width:28px;height:28px;border-radius:50%;border:2px solid color-mix(in srgb,var(--rw-accent) 25%,transparent);font-weight:800;font-size:12px;transition:all .2s}
.rw-dot svg{width:14px;height:14px}
.rw-step.is-done .rw-dot{background:var(--rw-accent);border-color:var(--rw-accent);color:#fff}
.rw-step.is-current .rw-dot{border-color:var(--rw-accent);color:var(--rw-accent);box-shadow:0 0 0 4px var(--rw-soft)}
.rw-step.is-current{color:var(--rw-accent);font-weight:800}
.rw-step.is-locked{opacity:.45;cursor:not-allowed}
@media (max-width:560px){.rw-lbl{display:none}.rw-step.is-current .rw-lbl{display:block}}
.rw-layout{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--space-lg);align-items:start}
@media (min-width:1024px){.rw-layout{grid-template-columns:minmax(0,1fr) 280px}}
.rw-side{position:sticky;top:calc(var(--header-h,64px) + 16px);display:none;padding:var(--space-md);border-radius:var(--radius-lg);
  background:linear-gradient(160deg,var(--rw-soft),transparent 70%);border:1px solid color-mix(in srgb,var(--rw-accent) 18%,transparent)}
@media (min-width:1024px){.rw-side{display:block}}
.rw-side-title{display:flex;align-items:center;gap:6px;font-weight:800;margin:0 0 10px;color:var(--rw-accent)}
.rw-side-title svg{width:18px;height:18px}
.rw-summary{list-style:none;margin:0;padding:0;display:grid;gap:6px}
.rw-summary li{display:grid;grid-template-columns:18px auto 1fr;gap:8px;align-items:center;font-size:var(--text-sm);color:var(--color-text-muted)}
.rw-summary li svg{width:16px;height:16px}
.rw-summary li b{justify-self:end;font-weight:600;color:var(--color-text-muted);max-width:14ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rw-summary li.is-set{color:inherit}.rw-summary li.is-set b{color:var(--rw-accent)}
.rw-foot{margin-top:var(--space-md);display:flex;gap:6px;align-items:center}
/* category picker */
.rw-search{display:flex;align-items:center;gap:10px;padding:0 14px;border-radius:999px;border:1.5px solid var(--color-border,rgba(0,0,0,.12));background:var(--color-surface,#fff);margin-bottom:12px}
.rw-search:focus-within{border-color:var(--rw-accent);box-shadow:0 0 0 4px var(--rw-soft)}
.rw-search svg{width:20px;height:20px;color:var(--rw-accent);flex:none}
.rw-search input{border:0;background:transparent;flex:1;min-height:48px;font:inherit;outline:0}
.rw-picked{display:none;align-items:center;gap:8px;padding:10px 12px;border-radius:var(--radius-md);background:var(--rw-soft);color:var(--rw-accent);margin-bottom:12px;font-size:var(--text-sm)}
.rw-picked.is-on{display:flex}.rw-picked svg{width:18px;height:18px}
.rw-groups{display:grid;gap:8px}
.rw-group{border:1px solid var(--color-border,rgba(0,0,0,.1));border-radius:var(--radius-md);background:var(--color-surface,#fff);overflow:hidden;transition:border-color .2s}
.rw-group.is-on{border-color:var(--rw-accent)}
.rw-group summary{display:grid;grid-template-columns:44px 1fr 20px;grid-template-areas:"ic name car" "ic sub car";align-items:center;gap:0 12px;padding:10px 12px;cursor:pointer;list-style:none;min-height:56px}
.rw-group summary::-webkit-details-marker{display:none}
.rw-group summary img{grid-area:ic;width:44px;height:44px;object-fit:contain}
.rw-group-name{grid-area:name;font-weight:800}
.rw-group summary small{grid-area:sub;color:var(--color-text-muted);font-size:var(--text-xs);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rw-group summary>svg{grid-area:car;width:18px;height:18px;color:var(--color-text-muted);transition:transform .2s}
.rw-group[open] summary>svg{transform:rotate(180deg)}
.rw-chips{display:flex;flex-wrap:wrap;gap:8px;padding:4px 12px 12px}
.rw-chip{border:1.5px solid var(--color-border,rgba(0,0,0,.12));background:transparent;border-radius:999px;padding:8px 14px;font:inherit;font-size:var(--text-sm);font-weight:600;min-height:40px;cursor:pointer;color:inherit;transition:all .15s}
.rw-chip:hover{border-color:var(--rw-accent)}
.rw-chip.is-on{background:var(--rw-accent);border-color:var(--rw-accent);color:#fff}
.rw-chip.is-hidden,.rw-group.is-hidden{display:none}
.rw-native-wrap{display:none;margin-top:12px}
.rw-empty{text-align:center;padding:16px}
.rw-card{padding:var(--space-lg);border-radius:var(--radius-lg)}
.rw-nav{display:flex;justify-content:space-between;align-items:center;gap:var(--space-sm);margin-top:var(--space-lg);padding-top:var(--space-md);border-top:1px solid var(--color-border,rgba(0,0,0,.08));flex-wrap:wrap}
.rw-nav .btn-lg{min-width:180px}
.rw-next svg{width:18px;height:18px}
@media (max-width:720px){.rw-nav .btn-lg{flex:1;min-width:0}.rw-nav .cluster{flex:1}
  .rw{padding-bottom:calc(var(--botnav-h,64px) + 24px)}}
.rw-cancel{margin-top:var(--space-md);text-align:center}
.rw-errs{margin:0;padding-inline-start:18px}
.rw-intro{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:8px;counter-reset:rw}
.rw-intro li{display:flex;align-items:center;gap:8px;padding:10px 12px;border:1px solid var(--color-border,rgba(0,0,0,.1));border-radius:var(--radius-md);font-weight:700;counter-increment:rw}
.rw-intro li::before{content:counter(rw);display:inline-grid;place-items:center;width:24px;height:24px;border-radius:50%;background:var(--color-primary);color:var(--color-on-primary);font-size:12px}
.rw-intro li svg{width:18px;height:18px;color:var(--color-primary)}
.rw-presets{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:8px;margin-bottom:var(--space-md)}
.rw-preset{position:relative;display:block}
.rw-preset input{position:absolute;opacity:0;inset:0;width:100%;height:100%;margin:0;cursor:pointer}
.rw-preset span{display:block;padding:12px;border:2px solid var(--color-border,rgba(0,0,0,.12));border-radius:var(--radius-md);text-align:center;font-weight:700;min-height:44px}
.rw-preset input:checked+span{border-color:var(--color-primary);background:color-mix(in srgb,var(--color-primary) 10%,transparent);color:var(--color-primary)}
.rw-preset input:focus-visible+span{outline:2px solid var(--color-primary);outline-offset:2px}
.rw-thumbs{display:grid;grid-template-columns:repeat(auto-fill,minmax(110px,1fr));gap:8px}
.rw-thumb{position:relative;margin:0;aspect-ratio:1;border-radius:var(--radius-md);overflow:hidden;background:var(--color-surface-2,rgba(0,0,0,.05))}
.rw-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.rw-thumb form{position:absolute;top:4px;inset-inline-start:4px}
.rw-thumb .btn{background:rgba(255,255,255,.9);color:var(--color-destructive,#b91c1c);padding:6px;min-height:34px}
.rw-preview{gap:var(--space-lg)}
.rw-table{margin:0}
.rw-row{display:grid;grid-template-columns:130px 1fr;gap:8px;padding:8px 0;border-bottom:1px solid var(--color-border,rgba(0,0,0,.08))}
.rw-row dt{color:var(--color-text-muted);font-size:var(--text-sm)}
.rw-row dd{margin:0;word-break:break-word}
.rw-edit{display:inline-flex;vertical-align:middle;margin-inline-start:6px;color:var(--color-primary)}
.rw-edit svg{width:14px;height:14px}
.rw-hours{list-style:none;margin:0;padding:0;font-size:var(--text-sm)}
.rw-hours li{display:flex;justify-content:space-between;padding:4px 0;border-bottom:1px dashed var(--color-border,rgba(0,0,0,.08))}
@media (max-width:640px){.rw-preview{grid-template-columns:1fr}.rw-row{grid-template-columns:100px 1fr}}

/* ---- v209: owner lifecycle controls on «کسب‌وکارهای من» ---- */
.lc{margin-top:var(--space-md);padding-top:var(--space-md);border-top:1px dashed var(--color-border,rgba(0,0,0,.1))}
.lc-note{display:flex;gap:10px;align-items:flex-start;padding:10px 12px;border-radius:var(--radius-md);background:color-mix(in srgb,var(--color-primary) 8%,transparent);margin-bottom:10px}
.lc-note svg{width:20px;height:20px;flex:none;color:var(--color-primary);margin-top:2px}
.lc-note strong{display:block;font-size:var(--text-sm)}
.lc-note small{display:block;color:var(--color-text-muted);font-size:var(--text-xs);margin-top:2px}
.lc-note.lc-warn{background:color-mix(in srgb,#d97706 12%,transparent)}.lc-note.lc-warn svg{color:#b45309}
.lc-note.lc-err{background:color-mix(in srgb,var(--color-destructive,#b91c1c) 10%,transparent)}.lc-note.lc-err svg{color:var(--color-destructive,#b91c1c)}
.lc-actions{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.lc-actions .inl{display:inline}
.lc-danger{color:var(--color-destructive,#b91c1c);margin-inline-start:auto}
.lc-dialog{position:fixed;inset:0;margin:auto;border:0;border-radius:var(--radius-lg);padding:0;max-width:min(92vw,460px);width:100%;height:fit-content;max-height:90vh;overflow:auto;background:var(--color-surface,#fff);color:inherit;box-shadow:var(--e4,0 20px 60px rgba(0,0,0,.35))}
.lc-dialog::backdrop{background:rgba(0,0,0,.45);backdrop-filter:blur(3px)}
.lc-dialog-body{padding:var(--space-lg);display:grid;gap:10px}
.lc-dialog .card-title{color:var(--color-destructive,#b91c1c)}
.biz-own-section{margin-bottom:calc(var(--space-xl,40px) + 8px);padding-bottom:var(--space-lg);border-bottom:1px solid var(--color-border,rgba(0,0,0,.08))}
.biz-own-list{gap:20px}

/* v211 — messenger fields: icon sits inline with the label text */
.field-label:has(> svg){display:inline-flex;align-items:center;gap:6px}
.field-label > svg{width:16px;height:16px;flex:none;color:var(--accent,inherit)}
.rw-msgrs .field-label > svg{width:18px;height:18px}

/* ======================================================================
   v213 — دستیار هوشمند دست گیر: نوار معلق زنده + صفحهٔ چت /assistant
   ====================================================================== */
.ai-bar {
  position: fixed; z-index: 99; inset-inline-end: 20px; bottom: 20px;
  display: flex; align-items: center; gap: 12px; max-width: min(420px, calc(100vw - 32px));
  padding: 10px 14px 10px 10px; border-radius: 999px; text-decoration: none; color: inherit;
  background: var(--glass-bg); -webkit-backdrop-filter: blur(18px) saturate(180%); backdrop-filter: blur(18px) saturate(180%);
  border: 1px solid var(--glass-hairline); box-shadow: var(--e3);
  animation: supIn var(--dur-4) var(--ease-out);
}
.ai-bar[hidden] { display: none !important; }
.ai-bar:hover { transform: translateY(-2px); box-shadow: var(--e4, var(--e3)); border-color: var(--color-primary); }
.ai-bar-orb {
  flex: 0 0 auto; width: 42px; height: 42px; border-radius: 50%; display: grid; place-items: center;
  color: #fff; background: linear-gradient(135deg, var(--color-primary), var(--accent-400, var(--color-primary)));
  box-shadow: 0 0 0 0 rgba(0,0,0,0); animation: aiPulse 2.4s ease-out infinite;
}
.ai-bar-orb svg { width: 22px; height: 22px; }
@keyframes aiPulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--color-primary) 45%, transparent) } 70% { box-shadow: 0 0 0 12px transparent } 100% { box-shadow: 0 0 0 0 transparent } }
.ai-bar-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.5; }
.ai-bar-text strong { font-size: var(--fs-sm); }
.ai-bar-live { font-size: var(--fs-xs); color: var(--color-text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ai-bar-live::before { content: ""; display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: #22c55e; margin-inline-end: 6px; vertical-align: middle; animation: aiBlink 1.6s infinite; }
@keyframes aiBlink { 50% { opacity: .35 } }
.ai-bar-cta { flex: 0 0 auto; color: var(--color-primary); }
.ai-bar-cta svg { width: 18px; height: 18px; }
@media (max-width: 768px) { .ai-bar { bottom: calc(var(--botnav-h) + env(safe-area-inset-bottom) + 12px); } }
@media (max-width: 560px) { .ai-bar { inset-inline-end: 14px; inset-inline-start: 82px; max-width: none; padding: 8px 12px 8px 8px; } .ai-bar-orb { width: 38px; height: 38px; } }
@media (prefers-reduced-motion: reduce) { .ai-bar, .ai-bar-orb, .ai-bar-live::before { animation: none; } }
body:has(.messenger) .ai-bar, .page-assistant .ai-bar, .page-assistant .sup-fab { display: none !important; }

.ai-invite {
  position: fixed; z-index: 102; inset-inline-end: 20px; bottom: 96px; width: min(340px, calc(100vw - 32px));
  padding: 16px 16px 14px; border-radius: var(--radius-xl); background: var(--glass-bg);
  -webkit-backdrop-filter: blur(20px) saturate(180%); backdrop-filter: blur(20px) saturate(180%);
  border: 1px solid var(--glass-hairline); box-shadow: var(--e3); animation: supPanelIn var(--dur-3) var(--ease-out);
}
.ai-invite[hidden] { display: none !important; }
.ai-invite-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; padding-inline-end: 28px; }
.ai-invite-head svg { width: 20px; height: 20px; color: var(--color-primary); }
.ai-invite p { margin: 0 0 12px; font-size: var(--fs-sm); color: var(--color-text-muted); }
.ai-invite-x { position: absolute; top: 8px; inset-inline-start: 8px; }
@media (max-width: 768px) { .ai-invite { bottom: calc(var(--botnav-h) + env(safe-area-inset-bottom) + 84px); } }

/* chat page (v215) */
.page-assistant .main-content { padding-bottom: 0; }
.ai-page { max-width: 880px; margin: 0 auto; padding: 16px 16px 120px; display: flex; flex-direction: column; gap: 14px; min-height: calc(100vh - 140px); }
.ai-hero { display: flex; gap: 14px; align-items: flex-start; padding: 22px 20px; border-radius: var(--radius-xl);
  background: linear-gradient(135deg, color-mix(in srgb, var(--color-primary) 16%, transparent), color-mix(in srgb, var(--accent-400, var(--color-primary)) 10%, transparent));
  border: 1px solid var(--glass-hairline); }
.ai-hero h1 { font-size: clamp(1.1rem, 2.6vw, 1.5rem); margin: 0 0 6px; }
.ai-hero p { margin: 0; color: var(--color-text-muted); font-size: var(--fs-sm); line-height: 1.7; }
/* v343: visible homepage route chooser — existing destinations only */
.h-route-section { padding-top: 0; }
.h-route-board {
  position: relative;
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(220px, .85fr) 1.7fr;
  gap: var(--space-lg);
  align-items: stretch;
  padding: var(--space-lg);
  border-radius: var(--radius-2xl);
  border: 1px solid color-mix(in oklab, var(--color-primary) 24%, var(--color-border));
  background:
    radial-gradient(circle at 8% 18%, color-mix(in oklab, var(--color-primary) 18%, transparent), transparent 28%),
    linear-gradient(135deg, color-mix(in oklab, var(--color-primary) 10%, var(--color-card)), var(--color-card));
  box-shadow: var(--e3);
}
.h-route-board::before {
  content: "";
  position: absolute;
  inset-block: 18px;
  inset-inline-start: 0;
  width: 6px;
  border-radius: 999px;
  background: linear-gradient(180deg, var(--color-primary), var(--accent-500));
}
.h-route-head {
  position: relative;
  z-index: 1;
  padding: var(--space-md);
  border-radius: var(--radius-xl);
  background: color-mix(in oklab, var(--color-card) 72%, transparent);
  border: 1px solid color-mix(in oklab, var(--color-primary) 14%, var(--color-border));
}
.h-route-head .eyebrow { justify-content: flex-start; }
.h-route-head h2 { margin: 10px 0 6px; font-size: var(--fs-2xl); }
.h-route-head p { margin: 0; color: var(--color-muted-foreground); line-height: 1.9; }
.h-route-grid { position: relative; z-index: 1; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; }
.h-route-card {
  min-height: 142px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 10px;
  padding: var(--space-md);
  border-radius: var(--radius-xl);
  border: 1px solid var(--color-border-strong);
  background: var(--color-card);
  color: var(--color-foreground);
  text-decoration: none;
  box-shadow: var(--e2);
  transition: transform var(--dur-2) var(--ease-out), border-color var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out);
}
.h-route-card:hover { transform: translateY(-3px); border-color: var(--color-primary); box-shadow: var(--e3); }
.h-route-card:focus-visible { outline: 2px solid var(--color-ring); outline-offset: 2px; }
.h-route-ic {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-lg);
  color: var(--color-primary);
  background: color-mix(in oklab, var(--color-primary) 12%, var(--color-muted));
}
.h-route-ic svg { width: 23px; height: 23px; }
.h-route-card strong { font-size: var(--fs-md); }
.h-route-card small { color: var(--color-muted-foreground); line-height: 1.7; }
.h-route-card.is-catalog .h-route-ic { color: var(--accent-600); background: color-mix(in oklab, var(--accent-500) 13%, var(--color-muted)); }
.h-route-card.is-map .h-route-ic { color: var(--brand-600); background: color-mix(in oklab, var(--brand-500) 12%, var(--color-muted)); }
.h-route-card.is-owner .h-route-ic { color: var(--gold-600); background: color-mix(in oklab, var(--gold-400) 18%, var(--color-muted)); }
@media (max-width: 980px) {
  .h-route-board { grid-template-columns: 1fr; }
  .h-route-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 540px) {
  .h-route-board { padding: var(--space-md); border-radius: var(--radius-xl); }
  .h-route-grid { grid-template-columns: 1fr; }
  .h-route-card { min-height: 104px; flex-direction: row; align-items: center; justify-content: flex-start; }
  .h-route-card small { display: block; }
}

.ai-hero-orb { width: 52px; height: 52px; flex: 0 0 auto; }
.ai-hero-orb svg { width: 26px; height: 26px; }
.ai-hero-meta { display: inline-flex; align-items: center; gap: 6px; margin-top: 8px; color: var(--color-text-muted); font-size: var(--fs-xs); }
.ai-dot { width: 8px; height: 8px; border-radius: 50%; background: #22c55e; animation: aiBlink 1.6s infinite; }
.ai-starts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.ai-starts[hidden] { display: none; }
.ai-start { display: flex; flex-direction: column; gap: 4px; align-items: flex-start; text-align: start; padding: 14px; border-radius: var(--radius-lg);
  border: 1px solid var(--glass-hairline); background: var(--glass-bg); color: inherit; font: inherit; cursor: pointer; transition: transform .15s, border-color .15s; }
.ai-start:hover { transform: translateY(-2px); border-color: var(--color-primary); }
.ai-start svg { width: 20px; height: 20px; color: var(--color-primary); }
.ai-start strong { font-size: var(--fs-sm); }
.ai-start small { color: var(--color-text-muted); font-size: var(--fs-xs); line-height: 1.5; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.ai-log { display: flex; flex-direction: column; gap: 12px; }
.ai-log:empty { display: none; }
.ai-msg { max-width: 88%; padding: 12px 16px; border-radius: 18px; font-size: var(--fs-sm); line-height: 1.85; animation: supPanelIn var(--dur-3) var(--ease-out); }
.ai-msg p { margin: 0; white-space: pre-line; }
.ai-bot { align-self: flex-start; background: var(--glass-bg); border: 1px solid var(--glass-hairline); border-start-start-radius: 6px; box-shadow: var(--e1, none); }
.ai-user { align-self: flex-end; background: var(--color-primary); color: var(--color-on-primary); border-start-end-radius: 6px; }
.ai-links { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.ai-links a { display: inline-flex; align-items: center; min-height: 34px; padding: 4px 14px; border-radius: 999px; font-size: var(--fs-xs); font-weight: 700; text-decoration: none;
  background: color-mix(in srgb, var(--color-primary) 12%, transparent); color: var(--color-primary); border: 1px solid color-mix(in srgb, var(--color-primary) 35%, transparent); }
.ai-links a:hover { background: var(--color-primary); color: var(--color-on-primary); }
.ai-typing p::after { content: "…"; animation: aiBlink 1s infinite; }
.ai-composer { position: fixed; z-index: 95; inset-inline: 0; bottom: 0; margin: 0 auto; max-width: 880px; padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
  display: flex; gap: 8px; align-items: flex-end; background: var(--glass-bg); -webkit-backdrop-filter: blur(18px) saturate(180%); backdrop-filter: blur(18px) saturate(180%);
  border-top: 1px solid var(--glass-hairline); }
@media (max-width: 768px) { .ai-composer { bottom: calc(var(--botnav-h) + env(safe-area-inset-bottom)); } .ai-page { padding-bottom: 150px; } }
.ai-composer .input { flex: 1 1 auto; min-height: 48px; max-height: 140px; resize: none; border-radius: 24px; padding-inline: 18px; }
.ai-send { min-width: 48px; min-height: 48px; border-radius: 50%; padding: 0; }
.ai-send svg { transform: scaleX(-1); }
.ai-foot { margin: 0; text-align: center; }
.ai-quota-warn { color: var(--color-destructive) !important; }
.nav-ai { color: var(--color-primary) !important; font-weight: 700; }
/* v286 audit: 12px = کف اندازهٔ متن سایت (test_appearance) — پیش‌تر 11px بود */
.nav-ai .nav-count { margin-inline-start: auto; background: var(--color-primary); color: var(--color-on-primary); border-radius: 999px; padding: 1px 8px; font-size: 12px; }
@media (max-width: 640px) { .ai-starts { grid-template-columns: repeat(2, 1fr); } .ai-hero { padding: 16px 14px; } .ai-hero-orb { width: 44px; height: 44px; } }
.page-assistant .site-footer, .page-assistant footer { display: none !important; }

/* v330-stage8: bulk-select checkboxes in panel tables are direct controls;
   the old inline table header shrank the native box to 13×13 on desktop. */
input[data-bulk-all], input[data-bulk-item], .bulk-bar input[type="checkbox"] {
  width: var(--tap); height: var(--tap);
  min-width: var(--tap); min-height: var(--tap);
  accent-color: var(--color-primary);
}

/* ==========================================================================
   v344 — Live/Luxury motion layer
   هدف: سایت «زنده» به‌نظر برسد، اما سبک، آرام و قابل‌دسترس بماند.
   حرکت‌های خودکار فقط روی opacity/transform هستند و reduced motion را رعایت می‌کنند.
   ========================================================================== */
.h-hero { isolation: isolate; }
.h-hero::before {
  content: "";
  position: absolute;
  z-index: 0;
  inset: -24% -12% auto -12%;
  height: min(58vh, 460px);
  pointer-events: none;
  opacity: .58;
  background:
    radial-gradient(16rem 12rem at 18% 38%, color-mix(in oklab, var(--amber-300) 32%, transparent), transparent 72%),
    radial-gradient(18rem 11rem at 84% 32%, color-mix(in oklab, var(--brand-400) 24%, transparent), transparent 70%),
    conic-gradient(from 210deg at 50% 50%, transparent, color-mix(in oklab, var(--color-primary) 14%, transparent), transparent 34%, color-mix(in oklab, var(--amber-400) 12%, transparent), transparent 68%);
  filter: blur(10px) saturate(118%);
  transform: translate3d(0, 0, 0) rotate(.001deg);
  animation: hAuroraDrift 13s var(--ease-inout) infinite alternate;
}
@keyframes hAuroraDrift {
  from { transform: translate3d(-1.4rem, -.4rem, 0) scale(1); opacity: .48; }
  to   { transform: translate3d(1.1rem, .8rem, 0) scale(1.035); opacity: .68; }
}

.kinetic-type {
  position: relative;
  display: inline-block;
  max-width: 100%;
}
.kinetic-type.is-typing::after {
  content: "";
  display: inline-block;
  width: .11em;
  height: .86em;
  margin-inline-start: .14em;
  border-radius: 999px;
  vertical-align: -.08em;
  background: linear-gradient(180deg, var(--amber-400), var(--color-primary));
  box-shadow: 0 0 18px color-mix(in oklab, var(--amber-400) 50%, transparent);
  animation: hCaretBlink .92s steps(2, start) infinite;
}
@keyframes hCaretBlink { 50% { opacity: .25; transform: translateY(1px); } }

.h-hero-badge {
  position: relative;
  overflow: hidden;
}
.h-hero-badge::after {
  content: "";
  position: absolute;
  inset: -35% -60%;
  pointer-events: none;
  background: linear-gradient(110deg, transparent 36%, rgba(255,255,255,.42) 50%, transparent 64%);
  transform: translate3d(44%, 0, 0) skewX(-16deg);
  animation: hSpecularSweep 5.8s var(--ease-inout) infinite;
}
@keyframes hSpecularSweep {
  0%, 52% { transform: translate3d(44%, 0, 0) skewX(-16deg); opacity: 0; }
  62% { opacity: .85; }
  78%, 100% { transform: translate3d(-44%, 0, 0) skewX(-16deg); opacity: 0; }
}

.live-luxe-card {
  position: relative;
  isolation: isolate;
}
.live-luxe-card::after {
  content: "";
  position: absolute;
  z-index: 0;
  inset: 1px;
  border-radius: inherit;
  pointer-events: none;
  opacity: .78;
  background:
    linear-gradient(115deg, transparent 0 38%, rgba(255,255,255,.32) 48%, transparent 58% 100%),
    radial-gradient(16rem 10rem at 86% 10%, color-mix(in oklab, var(--amber-300) 18%, transparent), transparent 68%);
  transform: translate3d(14%, 0, 0);
  animation: hRouteGlow 7.2s var(--ease-inout) infinite;
}
@keyframes hRouteGlow {
  0%, 42% { opacity: .22; transform: translate3d(18%, 0, 0); }
  58% { opacity: .78; }
  80%, 100% { opacity: .18; transform: translate3d(-18%, 0, 0); }
}

.js .h-route-board .h-route-card {
  transition:
    opacity 560ms var(--ease-out),
    transform 560ms var(--ease-out),
    border-color var(--dur-3) var(--ease-out),
    box-shadow var(--dur-3) var(--ease-out);
}
.js .h-route-board:not(.is-in) .h-route-card {
  opacity: 0;
  transform: translate3d(0, 14px, 0) scale(.985);
}
.js .h-route-board.is-in .h-route-card { opacity: 1; transform: translate3d(0, 0, 0) scale(1); }
.js .h-route-board.is-in .h-route-card:nth-child(2) { transition-delay: 80ms; }
.js .h-route-board.is-in .h-route-card:nth-child(3) { transition-delay: 160ms; }
.js .h-route-board.is-in .h-route-card:nth-child(4) { transition-delay: 240ms; }
.h-route-card { overflow: hidden; }
.h-route-card::after {
  content: "";
  position: absolute;
  inset: -40% -70%;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(110deg, transparent 42%, rgba(255,255,255,.55) 50%, transparent 58%);
  transform: translate3d(42%, 0, 0) rotate(0.001deg);
  transition: opacity var(--dur-2) var(--ease-out), transform 680ms var(--ease-out);
}
.h-route-card:hover::after,
.h-route-card:focus-visible::after {
  opacity: .75;
  transform: translate3d(-42%, 0, 0) rotate(0.001deg);
}

.stat.is-counting {
  border-color: color-mix(in oklab, var(--color-primary) 32%, var(--glass-border));
  box-shadow: var(--e3), 0 0 0 1px color-mix(in oklab, var(--color-primary) 16%, transparent);
}
.stat.is-counting .stat-icon {
  animation: statBreath 820ms var(--ease-out) infinite alternate;
}
.stat.is-counting .stat-value {
  color: var(--color-primary-text);
  text-shadow: 0 0 18px color-mix(in oklab, var(--color-primary) 18%, transparent);
}
@keyframes statBreath {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(0, -2px, 0) scale(1.045); }
}

@media (max-width: 760px) {
  .h-hero::before { height: 310px; filter: blur(18px) saturate(112%); opacity: .36; }
  .js .h-route-board.is-in .h-route-card { transition-delay: 0ms !important; }
}
@media (prefers-reduced-motion: reduce) {
  .h-hero::before,
  .kinetic-type.is-typing::after,
  .h-hero-badge::after,
  .live-luxe-card::after,
  .stat.is-counting .stat-icon {
    animation: none !important;
  }
  .js .h-route-board .h-route-card {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* ==========================================================================
   v345 — Obvious live motion stage + real scroll reveals
   هدف این نسخه عمداً «قابل دیدن» است: یک صحنهٔ زنده بعد از هیرو، شمارنده‌های
   بزرگ، اسکن‌لاین، هاله‌های متحرک و reveal قوی‌تر روی اسکرول؛ بدون route/schema.
   ========================================================================== */
.h-motion-section {
  padding-top: clamp(22px, 4vw, 44px);
  padding-bottom: clamp(22px, 4vw, 44px);
  perspective: 1200px;
}
.h-motion-shell {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-height: clamp(360px, 48vw, 520px);
  display: grid;
  grid-template-columns: minmax(0, .9fr) minmax(320px, 1.1fr);
  gap: clamp(18px, 4vw, 42px);
  align-items: center;
  padding: clamp(22px, 5vw, 54px);
  border-radius: clamp(24px, 4vw, 44px);
  color: #fff;
  background:
    radial-gradient(50rem 28rem at 82% 8%, rgba(20, 184, 166, .46), transparent 62%),
    radial-gradient(38rem 30rem at 10% 94%, rgba(245, 158, 11, .34), transparent 60%),
    linear-gradient(135deg, #06251d 0%, #091c25 42%, #1b1024 100%);
  border: 1px solid rgba(255, 255, 255, .18);
  box-shadow:
    0 28px 80px rgba(5, 19, 24, .34),
    inset 0 1px 0 rgba(255,255,255,.28),
    inset 0 -1px 0 rgba(255,255,255,.08);
}
.h-motion-shell::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .82;
  background:
    linear-gradient(115deg, transparent 0 34%, rgba(255,255,255,.18) 43%, transparent 52% 100%),
    repeating-linear-gradient(90deg, rgba(255,255,255,.075) 0 1px, transparent 1px 76px);
  transform: translate3d(18%, 0, 0);
  animation: v345StageSweep 5.8s cubic-bezier(.2,.7,.2,1) infinite;
}
.h-motion-shell::after {
  content: "";
  position: absolute;
  inset: 14px;
  z-index: -1;
  border-radius: inherit;
  pointer-events: none;
  border: 1px solid rgba(255,255,255,.13);
  box-shadow: inset 0 0 70px rgba(20,184,166,.18);
}
@keyframes v345StageSweep {
  0%, 35% { transform: translate3d(24%, 0, 0); opacity: .22; }
  52% { opacity: .88; }
  78%, 100% { transform: translate3d(-24%, 0, 0); opacity: .18; }
}
.h-motion-aurora {
  position: absolute;
  z-index: -2;
  width: 34vmax;
  height: 34vmax;
  border-radius: 999px;
  filter: blur(34px);
  opacity: .58;
  mix-blend-mode: screen;
  pointer-events: none;
  transform: translate3d(0,0,0);
}
.h-motion-aurora.a1 { inset: -24% auto auto -10%; background: rgba(16, 185, 129, .56); animation: v345FloatA 9s ease-in-out infinite alternate; }
.h-motion-aurora.a2 { inset: auto -12% -24% auto; background: rgba(245, 158, 11, .48); animation: v345FloatB 11s ease-in-out infinite alternate; }
.h-motion-aurora.a3 { inset: -18% 30% auto auto; background: rgba(56, 189, 248, .36); animation: v345FloatC 10s ease-in-out infinite alternate; }
@keyframes v345FloatA { to { transform: translate3d(8%, 10%, 0) scale(1.14); } }
@keyframes v345FloatB { to { transform: translate3d(-10%, -8%, 0) scale(1.08); } }
@keyframes v345FloatC { to { transform: translate3d(-4%, 16%, 0) scale(1.12); } }
.h-motion-copy { position: relative; z-index: 2; max-width: 54ch; }
.h-motion-kicker {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 14px;
  padding: 7px 13px;
  border-radius: 999px;
  background: rgba(255,255,255,.13);
  border: 1px solid rgba(255,255,255,.22);
  color: #d9fff7;
  font-size: var(--fs-sm);
  font-weight: 900;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.18);
}
.h-motion-kicker::before {
  content: "";
  width: 9px;
  height: 9px;
  border-radius: 999px;
  background: #34d399;
  box-shadow: 0 0 0 0 rgba(52,211,153,.52), 0 0 18px rgba(52,211,153,.9);
  animation: v345Ping 1.45s ease-out infinite;
}
@keyframes v345Ping { 70%, 100% { box-shadow: 0 0 0 12px rgba(52,211,153,0), 0 0 18px rgba(52,211,153,.9); } }
.h-motion-title {
  display: block;
  margin: 0;
  color: #fff;
  font-size: clamp(1.8rem, 4.2vw, 4.1rem);
  line-height: 1.16;
  font-weight: 950;
  letter-spacing: -.025em;
  text-shadow: 0 16px 48px rgba(0,0,0,.35);
}
.h-motion-copy p {
  margin: 18px 0 0;
  color: rgba(255,255,255,.78);
  font-size: clamp(.98rem, 1.4vw, 1.14rem);
  line-height: 2;
}
.h-motion-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 24px; }
.h-motion-actions .btn { min-height: 48px; border-radius: 16px; }
.h-motion-actions .btn-glass { color: #fff; border-color: rgba(255,255,255,.26); background: rgba(255,255,255,.11); }
.h-motion-metrics {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(12px, 2vw, 18px);
}
.h-motion-stat {
  position: relative;
  min-height: 154px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: clamp(16px, 2.6vw, 24px);
  border-radius: 28px;
  background: linear-gradient(155deg, rgba(255,255,255,.18), rgba(255,255,255,.075));
  border: 1px solid rgba(255,255,255,.2);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.22), 0 18px 42px rgba(0,0,0,.2);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  backdrop-filter: blur(16px) saturate(160%);
}
.h-motion-stat::after {
  content: "";
  position: absolute;
  inset: -40% -65%;
  background: linear-gradient(110deg, transparent 42%, rgba(255,255,255,.42) 50%, transparent 58%);
  transform: translate3d(44%, 0, 0) skewX(-16deg);
  animation: v345MiniSweep 4.8s ease-in-out infinite;
  animation-delay: var(--sweep-delay, 0s);
  pointer-events: none;
}
.h-motion-stat:nth-child(2)::after { --sweep-delay: .35s; }
.h-motion-stat:nth-child(3)::after { --sweep-delay: .7s; }
.h-motion-stat:nth-child(4)::after { --sweep-delay: 1.05s; }
@keyframes v345MiniSweep {
  0%, 48% { transform: translate3d(44%, 0, 0) skewX(-16deg); opacity: 0; }
  58% { opacity: .85; }
  78%, 100% { transform: translate3d(-44%, 0, 0) skewX(-16deg); opacity: 0; }
}
.h-motion-stat strong {
  display: block;
  color: #fff7d6;
  font-size: clamp(2.4rem, 6vw, 5.4rem);
  line-height: .9;
  font-weight: 1000;
  letter-spacing: -.04em;
  text-shadow: 0 0 32px rgba(251, 191, 36, .32), 0 14px 36px rgba(0,0,0,.35);
}
.h-motion-stat span {
  color: rgba(255,255,255,.78);
  font-size: var(--fs-sm);
  font-weight: 800;
  line-height: 1.8;
}
.h-motion-stat.is-hot {
  background: linear-gradient(155deg, rgba(251,191,36,.25), rgba(20,184,166,.13));
  border-color: rgba(251,191,36,.42);
}
.h-motion-scan {
  position: absolute;
  inset-inline: 0;
  inset-block-end: 28px;
  z-index: 1;
  display: grid;
  gap: 7px;
  opacity: .55;
  pointer-events: none;
}
.h-motion-scan span {
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.58), transparent);
  transform: translateX(40%);
  animation: v345Scan 3.6s linear infinite;
}
.h-motion-scan span:nth-child(2) { animation-delay: .55s; opacity: .65; }
.h-motion-scan span:nth-child(3) { animation-delay: 1.1s; opacity: .45; }
@keyframes v345Scan { to { transform: translateX(-40%); } }
.h-motion-scroll {
  position: absolute;
  inset-inline-start: clamp(20px, 4vw, 42px);
  inset-block-end: 18px;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  color: rgba(255,255,255,.66);
  font-size: var(--fs-xs);
  pointer-events: none;
}
.h-motion-scroll b {
  width: 7px;
  height: 26px;
  border-radius: 999px;
  background: linear-gradient(#fff, #34d399);
  box-shadow: 0 0 20px rgba(52,211,153,.65);
  animation: v345Down 1.3s ease-in-out infinite;
}
@keyframes v345Down { 50% { transform: translateY(8px); opacity: .45; } }

/* Scroll reveal on the home experience must be impossible to miss. */
.js .h-motion-section .reveal:not(.is-in),
.js .h-route-section .reveal:not(.is-in),
.js .h-stats .reveal:not(.is-in) {
  opacity: 0;
  transform: translate3d(0, 54px, 0) scale(.94);
  filter: blur(12px);
}
.js .h-motion-section .reveal.is-in,
.js .h-route-section .reveal.is-in,
.js .h-stats .reveal.is-in {
  opacity: 1;
  transform: none;
  filter: blur(0);
  transition: opacity 760ms var(--ease-out), transform 760ms var(--ease-out), filter 760ms var(--ease-out);
}
.js .h-motion-shell.reveal-3d:not(.is-in) {
  opacity: 0;
  transform: perspective(1100px) rotateX(16deg) translate3d(0, 72px, 0) scale(.92);
  filter: blur(8px) saturate(.9);
}
.js .h-motion-shell.reveal-3d.is-in {
  opacity: 1;
  transform: perspective(1100px) rotateX(0) translate3d(0, 0, 0) scale(1);
  filter: blur(0) saturate(1);
  transition: opacity 900ms var(--ease-out), transform 980ms cubic-bezier(.17,.84,.28,1), filter 900ms var(--ease-out);
}

@media (max-width: 900px) {
  .h-motion-shell { grid-template-columns: 1fr; min-height: auto; }
  .h-motion-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .h-motion-section { padding-top: 18px; }
  .h-motion-shell { padding: 18px; border-radius: 28px; }
  .h-motion-metrics { grid-template-columns: 1fr; }
  .h-motion-stat { min-height: 116px; border-radius: 22px; }
  .h-motion-scroll { position: relative; inset: auto; margin-top: 16px; }
}
@media (prefers-reduced-motion: reduce) {
  .h-motion-shell::before,
  .h-motion-aurora,
  .h-motion-kicker::before,
  .h-motion-stat::after,
  .h-motion-scan span,
  .h-motion-scroll b {
    animation: none !important;
  }
  .js .h-motion-section .reveal,
  .js .h-route-section .reveal,
  .js .h-stats .reveal,
  .js .h-motion-shell.reveal-3d {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    transition: none !important;
  }
}

/* v345 pass 2 — mobile must show the requested counting immediately, not after
   another long scroll through copy. Put counters first on small screens. */
@media (max-width: 900px) {
  .h-motion-metrics { order: -1; }
  .h-motion-copy { order: 1; }
  .h-motion-scroll { order: 2; }
}
@media (max-width: 560px) {
  .h-motion-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .h-motion-stat { min-height: 104px; padding: 13px; border-radius: 20px; }
  .h-motion-stat strong { font-size: clamp(2rem, 13vw, 3.4rem); }
  .h-motion-stat span { font-size: 12px; line-height: 1.6; }
}

/* ==========================================================================
   v346 — Make every home number and route card visibly wake up on scroll
   بعد از بازخورد «ادامه بده»: صحنهٔ v345 حفظ شد، اما ردیف آمار واقعی خانه
   و کارت‌های مسیر هم حالا تغییر دیدنی، شمارش بزرگ و reveal مستقل دارند.
   ========================================================================== */
.h-stats-section {
  position: relative;
  overflow: hidden;
  padding-block: clamp(34px, 6vw, 74px);
  margin-block: clamp(12px, 2vw, 24px);
  background:
    radial-gradient(34rem 22rem at 12% 0%, color-mix(in oklab, var(--color-primary) 22%, transparent), transparent 65%),
    radial-gradient(28rem 20rem at 88% 100%, color-mix(in oklab, var(--amber-400) 20%, transparent), transparent 62%),
    linear-gradient(180deg, color-mix(in oklab, var(--color-card) 94%, transparent), color-mix(in oklab, var(--color-muted) 88%, transparent));
  border-block: 1px solid color-mix(in oklab, var(--color-primary) 18%, var(--color-border));
}
.h-stats-section::before {
  content: "";
  position: absolute;
  inset-inline: -10%;
  inset-block-start: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--color-primary), var(--amber-400), transparent);
  transform: translate3d(42%, 0, 0);
  animation: v346StatsBeam 4.4s var(--ease-inout) infinite;
}
@keyframes v346StatsBeam { to { transform: translate3d(-42%, 0, 0); } }
.h-stats-live-head {
  position: relative;
  z-index: 2;
  display: grid;
  gap: 10px;
  max-width: 760px;
  margin: 0 auto clamp(18px, 3vw, 30px);
  text-align: center;
}
.h-stats-live-head .h-motion-kicker {
  justify-self: center;
  margin-bottom: 0;
  color: var(--color-primary-text);
  background: color-mix(in oklab, var(--color-primary) 13%, var(--color-card));
  border-color: color-mix(in oklab, var(--color-primary) 26%, var(--color-border));
  box-shadow: var(--e2);
}
.h-stats-live-head h2 {
  margin: 0;
  font-size: clamp(1.65rem, 3.2vw, 3rem);
  line-height: 1.25;
  font-weight: 950;
  color: var(--color-foreground);
}
.h-stats-live-head p {
  margin: 0;
  color: var(--color-muted-foreground);
  line-height: 1.9;
}
.h-stats-section .h-stats {
  position: relative;
  z-index: 2;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(10px, 2vw, 18px);
}
.h-stats-section .stat {
  overflow: hidden;
  min-height: clamp(150px, 18vw, 220px);
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-start;
  padding: clamp(16px, 2.4vw, 28px);
  border-radius: clamp(20px, 3vw, 32px);
  border: 1px solid color-mix(in oklab, var(--color-primary) 22%, var(--color-border));
  background:
    radial-gradient(16rem 12rem at 18% -10%, color-mix(in oklab, var(--color-primary) 24%, transparent), transparent 70%),
    linear-gradient(155deg, color-mix(in oklab, var(--color-card) 94%, transparent), color-mix(in oklab, var(--color-card) 70%, var(--color-primary) 8%));
  box-shadow: var(--e3), inset 0 1px 0 rgba(255,255,255,.45);
}
.h-stats-section .stat::after {
  content: "";
  position: absolute;
  inset: -40% -70%;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(112deg, transparent 42%, rgba(255,255,255,.58) 50%, transparent 58%);
  transform: translate3d(48%, 0, 0) skewX(-15deg);
}
.h-stats-section .stat.is-in::after,
.h-stats-section .stat.is-counting::after {
  animation: v346CardFlash 1.7s ease-out .18s both;
}
@keyframes v346CardFlash {
  0% { opacity: 0; transform: translate3d(48%,0,0) skewX(-15deg); }
  38% { opacity: .9; }
  100% { opacity: 0; transform: translate3d(-48%,0,0) skewX(-15deg); }
}
.h-stats-section .stat-icon {
  width: 58px;
  height: 58px;
  border-radius: 18px;
  background: linear-gradient(145deg, color-mix(in oklab, var(--color-primary) 28%, transparent), color-mix(in oklab, var(--amber-400) 18%, transparent));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.38), 0 12px 28px color-mix(in oklab, var(--color-primary) 18%, transparent);
}
.h-stats-section .stat-value {
  font-size: clamp(2.6rem, 5.8vw, 5.7rem);
  line-height: .9;
  font-weight: 1000;
  letter-spacing: -.05em;
  color: var(--color-primary-text);
  text-shadow: 0 0 24px color-mix(in oklab, var(--color-primary) 18%, transparent);
}
.h-stats-section .stat-label {
  font-size: var(--fs-sm);
  font-weight: 850;
  color: var(--color-muted-foreground);
}
.h-stats-section .stat.is-counting {
  transform: translate3d(0, -4px, 0) scale(1.018);
  border-color: color-mix(in oklab, var(--amber-400) 42%, var(--color-primary));
  box-shadow: var(--e4), 0 0 0 1px color-mix(in oklab, var(--amber-400) 22%, transparent), 0 18px 48px color-mix(in oklab, var(--color-primary) 18%, transparent);
}
.h-stats-section .stat.is-counting .stat-value {
  color: color-mix(in oklab, var(--amber-500) 62%, var(--color-primary-text));
}

/* Route cards now reveal one by one independently, with visible depth. */
.h-route-board.is-in .h-route-card.reveal.is-in {
  animation: v346RoutePop 780ms cubic-bezier(.16,.84,.31,1.18) both;
}
@keyframes v346RoutePop {
  0% { transform: translate3d(0, 28px, 0) scale(.9); filter: blur(10px); opacity: 0; }
  70% { transform: translate3d(0, -4px, 0) scale(1.025); filter: blur(0); opacity: 1; }
  100% { transform: translate3d(0, 0, 0) scale(1); filter: blur(0); opacity: 1; }
}
.h-route-card.reveal.is-in .h-route-ic {
  animation: v346IconWake 900ms var(--ease-out) both;
}
@keyframes v346IconWake {
  0% { transform: scale(.72) rotate(10deg); opacity: .35; }
  60% { transform: scale(1.12) rotate(-4deg); opacity: 1; }
  100% { transform: scale(1) rotate(0); opacity: 1; }
}

@media (max-width: 900px) {
  .h-stats-section .h-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 540px) {
  .h-stats-section { padding-block: 28px; }
  .h-stats-live-head { text-align: start; margin-bottom: 16px; }
  .h-stats-live-head .h-motion-kicker { justify-self: start; }
  .h-stats-section .h-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .h-stats-section .stat { min-height: 132px; padding: 14px; border-radius: 20px; }
  .h-stats-section .stat-icon { width: 42px; height: 42px; border-radius: 14px; }
  .h-stats-section .stat-value { font-size: clamp(2rem, 13vw, 3.6rem); }
}
@media (prefers-reduced-motion: reduce) {
  .h-stats-section::before,
  .h-stats-section .stat.is-in::after,
  .h-stats-section .stat.is-counting::after,
  .h-route-board.is-in .h-route-card.reveal.is-in,
  .h-route-card.reveal.is-in .h-route-ic {
    animation: none !important;
  }
  .h-stats-section .stat.is-counting { transform: none !important; }
}

/* v349 — homepage density pass: no demo scene, no explanatory filler. */
.h-route-section-compact { padding-top: clamp(10px, 2vw, 18px); }
.h-route-section-compact .h-route-board {
  grid-template-columns: 1fr;
  gap: clamp(10px, 2vw, 14px);
  padding: clamp(12px, 2.5vw, 20px);
  border-radius: clamp(18px, 3vw, 26px);
}
.h-route-section-compact .h-route-board::before { inset-block: 14px; width: 4px; opacity: .65; }
.h-route-head-compact {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 0 4px 2px;
  background: transparent;
  border: 0;
}
.h-route-head-compact h2 {
  margin: 0;
  font-size: clamp(1.05rem, 3.5vw, 1.35rem);
  font-weight: 950;
  line-height: 1.35;
}
.h-route-section-compact .h-route-grid { gap: clamp(8px, 2vw, 12px); }
.h-route-section-compact .h-route-card {
  min-height: 96px;
  padding: clamp(12px, 2vw, 16px);
}
.h-route-section-compact .h-route-card small { line-height: 1.55; }
.h-stats-section-compact {
  padding-block: clamp(12px, 2.5vw, 24px);
  margin-block: 0 clamp(4px, 1vw, 10px);
  background: transparent;
  border-block: 0;
}
.h-stats-section-compact::before { display: none; }
.h-stats-section-compact .stat {
  min-height: clamp(84px, 11vw, 118px);
  padding: clamp(12px, 2vw, 18px);
  border-radius: clamp(16px, 2.4vw, 22px);
  justify-content: center;
  gap: 8px;
}
.h-stats-section-compact .stat-icon { width: 40px; height: 40px; border-radius: 13px; }
.h-stats-section-compact .stat-value {
  font-size: clamp(1.75rem, 4vw, 3.1rem);
  letter-spacing: -.03em;
}
.h-stats-section-compact .stat-label { font-size: var(--fs-xs); }
@media (max-width: 540px) {
  .h-route-section-compact .h-route-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .h-route-section-compact .h-route-card {
    min-height: 86px;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 6px;
  }
  .h-route-section-compact .h-route-ic { width: 36px; height: 36px; border-radius: 12px; }
  .h-route-section-compact .h-route-ic svg { width: 19px; height: 19px; }
  .h-route-section-compact .h-route-card strong { font-size: var(--fs-sm); }
  .h-route-section-compact .h-route-card small { display: none; }
  .h-stats-section-compact { padding-block: 10px 18px; }
  .h-stats-section-compact .stat { min-height: 82px; padding: 10px; }
  .h-stats-section-compact .stat-icon { width: 34px; height: 34px; border-radius: 11px; }
  .h-stats-section-compact .stat-value { font-size: clamp(1.55rem, 9vw, 2.35rem); }
}

/* v349 — admin command center: clearer workflow, search, and priority triage. */
.panel-command-center {
  display: grid;
  gap: clamp(14px, 2vw, 20px);
  border-color: color-mix(in oklab, var(--color-primary) 22%, var(--color-border));
  background:
    radial-gradient(34rem 18rem at 8% 0%, color-mix(in oklab, var(--color-primary) 12%, transparent), transparent 64%),
    linear-gradient(135deg, color-mix(in oklab, var(--color-card) 96%, transparent), color-mix(in oklab, var(--color-muted) 86%, transparent));
}
.panel-command-main {
  display: grid;
  grid-template-columns: minmax(220px, .9fr) minmax(300px, 1.25fr);
  gap: clamp(14px, 2vw, 24px);
  align-items: end;
}
.panel-command-main h2 {
  margin: 8px 0 4px;
  font-size: clamp(1.2rem, 2.4vw, 1.8rem);
  line-height: 1.35;
}
.panel-command-main p { margin: 0; color: var(--color-muted-foreground); line-height: 1.8; }
.panel-command-search {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 8px;
  align-items: center;
}
.panel-command-actions {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 8px;
}
.panel-command-actions a {
  min-height: 74px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  padding: 11px 12px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  background: color-mix(in oklab, var(--color-card) 88%, transparent);
  color: var(--color-foreground);
  text-decoration: none;
  box-shadow: var(--e1);
}
.panel-command-actions a:hover,
.panel-command-actions a:focus-visible {
  border-color: color-mix(in oklab, var(--color-primary) 38%, var(--color-border));
  outline: none;
  box-shadow: var(--e3);
}
.panel-command-actions strong {
  min-height: 28px;
  display: inline-flex;
  align-items: center;
  font-size: clamp(1.05rem, 2vw, 1.45rem);
  color: var(--color-primary-text);
}
.panel-command-actions strong svg { width: 24px; height: 24px; }
.panel-command-actions span { font-size: var(--fs-xs); color: var(--color-muted-foreground); font-weight: 800; line-height: 1.55; }
@media (max-width: 1020px) {
  .panel-command-main { grid-template-columns: 1fr; align-items: stretch; }
  .panel-command-actions { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .panel-command-search { grid-template-columns: 1fr; }
  .panel-command-actions { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .panel-command-actions a { min-height: 66px; }
}

/* v349 audit fix: compact home route header actions must remain touch-safe. */
.h-route-head-compact .btn { min-height: 44px; }
}

/* ======================================================================
   v359 COHERENT COMPACT SYSTEM
   One late, narrow layer resolves the measured cascade conflicts without
   repainting the Daastgir identity: smaller headers, one panel hierarchy,
   explicit selected-business tools, and phone-only fixed navigation.
   ====================================================================== */

/* Public interior pages: keep the breadcrumb, but stop spending a quarter of
   the first viewport on breadcrumb + heading whitespace. */
.breadcrumb { padding-block: 12px 6px; }
.page-hero { padding-block: 22px 18px; }
.page-hero h1 { font-size: clamp(1.55rem, 2.6vw, 2.25rem); line-height: 1.35; }
.page-hero p { margin-top: 5px; max-width: 64ch; }

/* Panel rhythm and hierarchy. The previous late `.panel-head{display:flex}`
   made its title, context strip and mobile shortcuts siblings on one row;
   this restores the intended vertical header structure. */
.panel-layout { gap: 18px; padding-block: 18px; }
.panel-head {
  display: block;
  padding: 12px 14px;
  margin-bottom: 16px;
  border-radius: var(--radius-lg);
}
.panel-head > .between { align-items: center; gap: 12px; }
.panel-head h1 { font-size: clamp(1.08rem, 1.6vw, 1.35rem); line-height: 1.45; }
.panel-head p { margin-top: 2px; line-height: 1.65; }
.panel-context-bar {
  grid-template-columns: minmax(190px, auto) minmax(0, 1fr);
  gap: 8px; margin-top: 9px; padding: 6px;
  border-radius: var(--radius-md);
}
.panel-context-current { min-height: 36px; padding-inline: 6px; }
.panel-context-links { gap: 6px; padding-bottom: 1px; scroll-snap-type: inline proximity; }
.panel-context-link { min-height: 36px; padding: 6px 10px; scroll-snap-align: start; }
.page-panel .card-pad { padding: clamp(16px, 1.8vw, 22px); }
.page-panel .card-title { font-size: var(--fs-md); line-height: 1.55; }
.page-panel .field { margin-bottom: 14px; }
.page-panel .mb-lg { margin-bottom: 16px; }
.page-panel .table th,
.page-panel .table td { padding-block: 11px; }
.page-panel .hours-row { min-height: 50px; }

@media (min-width: 1025px) {
  .panel-layout { grid-template-columns: minmax(0, 272px) minmax(0, 1fr); }
  .panel-side { width: 272px; padding: 16px; }
  .panel-nav a { min-height: 40px; padding: 8px 10px; }
  .panel-nav-title { margin: 12px 10px 5px; }
}

/* The selected business is now a stable workspace instead of a long form
   followed by unrelated gallery/catalog buttons. */
.business-workspace {
  margin-bottom: 16px;
  overflow: hidden;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  background: color-mix(in oklab, var(--color-card) 94%, var(--color-primary) 6%);
  box-shadow: var(--e1);
}
.business-workspace-head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--color-border);
}
.business-workspace-mark {
  display: grid; place-items: center; width: 38px; height: 38px;
  border-radius: 12px; background: var(--color-primary); color: var(--color-on-primary);
}
.business-workspace-mark svg { width: 20px; height: 20px; }
.business-workspace-head div { min-width: 0; }
.business-workspace-head small {
  display: block; color: var(--color-muted-foreground);
  font-size: var(--fs-xs); font-weight: 700; line-height: 1.3;
}
.business-workspace-head strong {
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: var(--fs-md); line-height: 1.55;
}
.business-workspace-nav {
  display: flex; align-items: stretch; gap: 4px;
  padding: 7px; overflow-x: auto; scrollbar-width: thin;
  overscroll-behavior-inline: contain; scroll-snap-type: inline proximity;
}
.business-workspace-link {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 7px;
  min-height: 42px; padding: 7px 11px; border-radius: var(--radius-md);
  color: var(--color-muted-foreground); font-size: var(--fs-sm); font-weight: 750;
  scroll-snap-align: start;
}
.business-workspace-link:hover { background: var(--color-muted); color: var(--color-foreground); }
.business-workspace-link.is-active {
  background: var(--color-primary); color: var(--color-on-primary);
}
.business-workspace-link svg { width: 17px; height: 17px; }
#business-profile, #business-location, #business-hours, #business-status {
  scroll-margin-top: calc(var(--header-h) + 16px);
}

/* Mobile/tablet panel: one short header and one accordion drawer. The current
   workflow remains visible; duplicate shortcut rows are available in the
   drawer rather than consuming another 52px on every page. */
.panel-drawer-box { width: min(92vw, 360px); }
.panel-drawer-head { padding: 12px 14px; }
.panel-drawer-head > div { min-width: 0; }
.panel-drawer-head strong,
.panel-drawer-head small { display: block; line-height: 1.5; }
.panel-drawer-body { padding: 10px 12px 18px; overscroll-behavior: contain; }
.panel-drawer-groups { display: grid; gap: 7px; }
.panel-drawer-group {
  border: 1px solid var(--color-border); border-radius: var(--radius-md);
  background: var(--color-card); overflow: hidden;
}
.panel-drawer-group > summary {
  list-style: none; display: flex; align-items: center; gap: 8px;
  min-height: 46px; padding: 9px 11px; cursor: pointer;
  font-size: var(--fs-sm); font-weight: 850;
}
.panel-drawer-group > summary::-webkit-details-marker { display: none; }
.panel-drawer-group > summary span { flex: 1; }
.panel-drawer-group > summary svg { width: 17px; height: 17px; transition: transform var(--dur-2); }
.panel-drawer-group[open] > summary svg { transform: rotate(-90deg); }
.panel-drawer-group > nav { display: grid; gap: 2px; padding: 0 6px 7px; }
.panel-drawer-group > nav a {
  display: flex; align-items: center; gap: 9px; min-height: 44px;
  padding: 8px 10px; border-radius: 10px; color: var(--color-muted-foreground);
  font-size: var(--fs-sm); font-weight: 650;
}
.panel-drawer-group > nav a[aria-current="page"] {
  color: var(--color-primary-text);
  background: color-mix(in oklab, var(--color-primary) 12%, transparent);
}
.panel-drawer-group > nav a svg { width: 17px; height: 17px; flex: none; }
.panel-drawer-group > nav .nav-count { margin-inline-start: auto; }

@media (max-width: 1024px) {
  .panel-layout { padding-block: 10px 16px; }
  .panel-head { padding: 10px 11px; margin-bottom: 12px; }
  .panel-head > .between > div:first-child { min-width: 0; }
  .panel-head h1 { font-size: 1.03rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .panel-head p { display: none; }
  .panel-head > .between > .cluster { flex: none; gap: 5px; }
  .panel-head .btn-sm { min-height: 40px; padding: 7px 10px; }
  .panel-head .cmdk-kbd { display: none; }
  .panel-context-bar { display: block; margin-top: 7px; padding: 4px 6px; }
  .panel-context-current { min-height: 34px; gap: 6px; white-space: nowrap; overflow: hidden; }
  .panel-context-current span,
  .panel-context-current strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .panel-context-current span::after { content: " /"; }
  .panel-context-links,
  .panel-mob-quick-bar { display: none !important; }
  .page-panel .grid-4 { gap: 9px; }
  .business-workspace { border-radius: var(--radius-lg); }
}

@media (max-width: 560px) {
  .breadcrumb { padding-block: 8px 3px; font-size: var(--fs-xs); }
  .page-hero { padding-block: 14px 12px; }
  .page-hero h1 { font-size: 1.42rem; }
  .page-hero p { font-size: var(--fs-sm); line-height: 1.7; }
  .panel-head [data-panel-drawer-open] span,
  .panel-head [data-cmdk] span { display: none; }
  .panel-head [data-panel-drawer-open],
  .panel-head [data-cmdk] { width: 40px; padding: 0; justify-content: center; }
  .panel-head > .between > .cluster > .badge { display: none; }
  .business-workspace-head {
    grid-template-columns: auto minmax(0, 1fr) auto;
    padding: 10px 11px; gap: 8px;
  }
  .business-workspace-head > .badge { display: none; }
  .business-workspace-preview { width: 40px; padding: 0; justify-content: center; }
  .business-workspace-preview span { display: none; }
  .business-workspace-nav { padding: 6px; }
  .business-workspace-link { min-height: 40px; padding: 6px 9px; font-size: var(--fs-xs); }
  .page-panel .card-pad { padding: 15px; }
}

@media (prefers-reduced-motion: reduce) {
  .panel-drawer-box { animation: none; }
  .panel-drawer-group > summary svg { transition: none; }
}

/* v359 measured compaction pass 2: explicit physical breadcrumb padding is
   used because some deployed Chromium builds discarded the logical shorthand
   when the earlier mobile cascade was parsed. */
.breadcrumb { padding-top: 10px; padding-bottom: 6px; }
.page-hero > .eyebrow {
  min-height: 28px; padding: 4px 11px; margin-bottom: 8px;
  font-size: var(--fs-xs); line-height: 1.55;
}
.page-hero h1 { font-size: clamp(1.45rem, 2.25vw, 2rem); }
.page-hero p { font-size: var(--fs-base); line-height: 1.75; }
@media (min-width: 1025px) {
  .panel-head > .between > div:first-child {
    display: flex; align-items: baseline; gap: 10px; min-width: 0;
  }
  .panel-head > .between > div:first-child p {
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
}
@media (max-width: 1024px) {
  .panel-head { padding: 8px 10px; }
  .panel-context-bar { margin-top: 5px; padding: 2px 5px; }
  .panel-context-current { min-height: 30px; }
}
@media (max-width: 560px) {
  .breadcrumb { padding-top: 6px; padding-bottom: 2px; }
  .page-hero > .eyebrow { min-height: 26px; margin-bottom: 6px; padding: 3px 9px; }
  .page-hero h1 { font-size: 1.3rem; }
}

/* WCAG 2.2 target floor for native range controls and disclosure rows. */
input[type="range"] { min-height: 24px; }
details.card > summary { min-height: 40px; display: flex; align-items: center; cursor: pointer; }

/* v366 — per-field trust/freshness disclosure on public business profiles. */
.fact-freshness {
  border: 1px solid var(--color-border); border-radius: var(--radius-md);
  padding: 0 var(--space-md); background: color-mix(in oklab, var(--color-info) 6%, transparent);
}
.fact-freshness > summary {
  min-height: 44px; display: flex; align-items: center; gap: 8px;
  color: var(--color-text); font-weight: 700; cursor: pointer;
}
.fact-freshness ul { margin: 4px 0 var(--space-md); padding: 0; list-style: none; }
.fact-freshness li {
  display: flex; justify-content: space-between; gap: 12px; padding: 7px 0;
  border-top: 1px solid var(--color-border); color: var(--color-text-muted);
}
.fact-freshness li strong { color: var(--color-text); }
@media (max-width: 560px) {
  .fact-freshness li { align-items: flex-start; flex-direction: column; gap: 2px; }
}

/* ===== v410: ارتقای پَلِت فرمان پنل (Ctrl+K) و نوار جست‌وجوی فهرست‌ها ===== */
.cmdk-item.is-active{background:rgba(5,150,105,.14);outline:1px solid rgba(5,150,105,.35)}
.cmdk-item .cmdk-group{margin-inline-start:auto;opacity:.55;font-size:.72rem;white-space:nowrap}
.cmdk-list{max-height:56vh;overflow:auto}
.filter-bar [data-filter-count][data-empty="1"]{background:rgba(220,38,38,.14);color:#b91c1c}
/* ===== END pages.css ===== */

/* ===== BEGIN mobile-refine.css sha256:5619fe71d1d81634 ===== */
/* ==========================================================================
   Bazarche Najafabad — Mobile-First Refinements (v19, deep overhaul)
   Loaded AFTER pages.css so these rules win by source order.

   ROOT CAUSE of "zoomed in" (found via deep research, not guessing): the
   design's fluid type uses clamp(..vw..), so headings GROW with viewport
   width — on a phone/tablet/medium preview they hit 34–48px and the whole
   page reads as oversized. The mobile breakpoint was also only 1024px, so
   860–1440px still showed the desktop layout with those giant headings.

   THE FIX (mobile-first, per 2026 standards — 375px first, lg=1024px):
     1. Cap the fluid type TOKENS (--fs-xl..4xl) below 1100px so headings
        stay modest instead of ballooning with viewport width.
     2. Move the compact layout breakpoint up to 1024px (standard `lg`),
        so tablets AND medium-width previews get the real mobile layout.
     3. Drop the old html{font-size:14px} hack; keep a 16px root (standard)
        and a 15px body, with 16px form fields so iOS does not auto-zoom.
   Floors held: smallest text 12px, touch targets 44px.
   ========================================================================== */

.ms-descr { -webkit-line-clamp: 1 !important; margin: 0; }
.ms-row { font-weight: 600; color: var(--color-foreground); display: flex; align-items: flex-start; gap: 6px; line-height: 1.5; }
.ms-row::before { content: '📍'; flex: none; }
.ms-acts { flex-wrap: wrap; }

/* ---------- ADMIN EDIT MODE (site-wide inline editor) ---------- */
.admin-bar { position: fixed; top: calc(var(--header-h) + 10px); inset-inline-start: 12px; z-index: 350;
  display: flex; gap: 6px; padding: 6px; border-radius: var(--radius-pill); max-width: calc(100% - 24px);
  background: var(--glass-bg-strong); -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  border: 1px solid var(--glass-border); box-shadow: var(--e3); }
.admin-bar .admin-edit-toggle, .admin-bar .admin-link {
  display: inline-flex; align-items: center; gap: 6px; min-height: var(--tap); padding: 8px 14px;
  border-radius: var(--radius-pill); font-size: 13px; font-weight: 700; cursor: pointer;
  white-space: nowrap; border: 0; text-decoration: none; }
.admin-bar .admin-edit-toggle { background: var(--color-primary); color: var(--color-on-primary); }
.admin-bar .admin-edit-toggle[aria-pressed="true"] { background: var(--color-primary); }
.admin-bar .admin-link { background: var(--color-muted); color: var(--color-foreground); }
.admin-bar svg { width: 16px; height: 16px; flex: none; }
body.admin-editing [data-edit] { outline: 2px dashed var(--color-primary); outline-offset: 3px;
  border-radius: 4px; cursor: text; transition: background .15s; }
body.admin-editing [data-edit]:hover { background: color-mix(in oklab, var(--color-primary) 12%, transparent); }
body.admin-editing [data-edit].is-editable:focus { outline-style: solid; outline-width: 3px;
  background: color-mix(in oklab, var(--color-primary) 8%, #fff); }
body.admin-editing [data-edit].is-saving { outline-color: var(--color-warning); }
@media (max-width: 1024px) {
  .admin-bar { top: calc(var(--header-h) + 6px); inset-inline: 10px; max-width: none; overflow-x: auto; }
}

/* ---------- BILLING PERIOD TOGGLE (pricing page) ---------- */
.bill-toggle { display: flex; justify-content: center; flex-wrap: wrap; gap: 4px;
  padding: 4px; margin: 0 auto var(--space-lg); border-radius: var(--radius-pill);
  background: var(--color-muted); max-width: max-content; }
.bill-toggle button { min-height: var(--tap); padding: 8px 16px; border-radius: var(--radius-pill);
  border: 0; background: none; cursor: pointer; font-weight: 700; font-size: 13px;
  color: var(--color-muted-foreground); white-space: nowrap; transition: all var(--dur-2) var(--ease-out); }
.bill-toggle button.is-active { background: var(--color-card); color: var(--color-primary); box-shadow: var(--e1); }

/* ---------- IMAGE EDITOR (pre-upload) ---------- */
.imgedit-overlay { position: fixed; inset: 0; z-index: 500; background: rgba(4,16,14,.72);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); display: grid; place-items: center;
  padding: 14px; overflow-y: auto; }
.imgedit-modal { width: min(100%, 460px); background: var(--color-card); border-radius: var(--radius-lg);
  padding: 16px; box-shadow: var(--e4); max-height: 94dvh; overflow-y: auto; }
.imgedit-title { font-size: 1rem; margin-bottom: 12px; display: flex; gap: 8px; align-items: center; }
.imgedit-title svg { width: 18px; height: 18px; }
.imgedit-stage { background: var(--color-muted); border-radius: var(--radius-md); overflow: hidden;
  margin-bottom: 12px; display: grid; place-items: center; min-height: 150px; }
.imgedit-stage canvas { max-width: 100%; max-height: 46vh; width: auto; height: auto; display: block; }
.imgedit-controls { display: grid; gap: 10px; }
.imgedit-row { display: flex; align-items: center; gap: 10px; }
.imgedit-lbl { width: 56px; font-size: 13px; font-weight: 700; flex: none; }
.imgedit-row input[type="range"] { flex: 1; accent-color: var(--color-primary); }
.imgedit-crops { display: flex; gap: 4px; flex: 1; flex-wrap: wrap; }
.imgedit-btn { padding: 7px 11px; border-radius: var(--radius-sm); border: 1px solid var(--color-border);
  background: var(--color-muted); cursor: pointer; font-size: 13px; font-weight: 600; color: var(--color-foreground); }
.imgedit-btn.is-on { background: var(--color-primary); color: var(--color-on-primary); border-color: transparent; }
.imgedit-actions { display: flex; gap: 8px; margin-top: 14px; }
.imgedit-actions .btn { flex: 1; }
.imgedit-cancel { flex: 1; padding: 11px; border-radius: var(--radius-md); background: var(--color-muted);
  cursor: pointer; font-weight: 700; color: var(--color-foreground); }

/* image field: gallery + camera pickers side by side */
.imgf-pick { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.imgf-cam { cursor: pointer; }

/* profile completeness meter */
.cmp-bar { height: 10px; border-radius: var(--radius-pill); background: var(--color-muted); overflow: hidden; }
.cmp-fill { display: block; height: 100%; border-radius: inherit; transition: width .6s var(--ease-out); }
.cmp-fill.is-low  { background: linear-gradient(90deg, var(--color-destructive), #f97316); }
.cmp-fill.is-mid  { background: linear-gradient(90deg, var(--accent-500), var(--brand-500)); }
.cmp-fill.is-full { background: linear-gradient(90deg, var(--brand-400), var(--brand-600)); }
.cmp-list { display: grid; gap: 6px; }
.cmp-row { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: var(--radius-md); background: var(--color-muted); min-height: 44px; }
.cmp-row:not(.is-done) { background: color-mix(in oklab, var(--color-primary) 7%, transparent); cursor: pointer; transition: background var(--dur-2) var(--ease-out); }
.cmp-row:not(.is-done):hover { background: color-mix(in oklab, var(--color-primary) 13%, transparent); }
.cmp-row svg { width: 18px; height: 18px; flex: none; }
.cmp-row.is-done svg { color: var(--color-success); }
.cmp-row:not(.is-done) svg { color: var(--color-primary); }
.cmp-row > span { flex: 1; }
.cmp-tick { flex: none !important; font-size: 12px; color: var(--color-success); font-weight: 700; }
.cmp-go { flex: none !important; color: var(--color-primary); display: inline-flex; }
.cmp-go svg { width: 16px; height: 16px; }

/* ---------- 1. CAP THE FLUID TYPE (the actual "zoom" fix) ----------
   Below 1100px the vw-driven headings stop growing. This is the single
   change that stops the page looking blown-up on phones, tablets and
   medium-width previews. */
@media (max-width: 1100px) {
  :root {
    --fs-xl:  1.0625rem;   /* 17px */
    --fs-2xl: 1.25rem;     /* 20px */
    --fs-3xl: 1.5rem;      /* 24px — section titles, page heros */
    --fs-4xl: 1.75rem;     /* 28px — hero */
  }
}

/* ---------- 2. COMPACT LAYOUT at the standard `lg` breakpoint (1024px) ---------- */
@media (max-width: 1024px) {
  :root { --fs-sm: 0.8125rem; }            /* 13px secondary */
  body { font-size: 0.9375rem; line-height: 1.55; }   /* 15px body, standard-ish */
  /* form fields stay 16px so iOS Safari does not auto-zoom on focus */
  .input, .textarea, .select { font-size: 16px !important; }
  .card-desc, .review-body, p { line-height: 1.6; }

  /* gutter + section rhythm */
  .container, .container-wide { width: min(100% - 24px, var(--container-wide)) !important; }
  .section    { padding-block: 22px !important; }
  .section-sm { padding-block: 16px !important; }

  /* Standard mobile business directory listing (Divar/Torob single-column horizontal card) */
  [data-dir-grid] {
    grid-template-columns: 1fr !important;
    gap: 12px !important;
  }
  [data-dir-grid] .biz-card {
    display: flex !important;
    flex-direction: row-reverse !important;
    align-items: stretch !important;
    padding: 12px 14px !important;
    border-radius: var(--radius-xl) !important;
    gap: 14px !important;
    background: var(--color-card) !important;
    border: 1px solid var(--color-border) !important;
    box-shadow: var(--e1) !important;
  }
  [data-dir-grid] .biz-card .sheen { display: none !important; }
  [data-dir-grid] .biz-card .card-media {
    width: 112px !important;
    min-width: 112px !important;
    height: 112px !important;
    aspect-ratio: 1 / 1 !important;
    border-radius: var(--radius-lg) !important;
    flex: 0 0 112px !important;
    align-self: center !important;
    position: relative !important;
  }
  [data-dir-grid] .biz-card .biz-thumb-art {
    width: 100% !important;
    height: 100% !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
  }
  [data-dir-grid] .biz-card .biz-thumb-art img,
  [data-dir-grid] .biz-card .biz-thumb-art .ic {
    width: 100% !important;
    height: 100% !important;
    object-fit: cover !important;
  }
  [data-dir-grid] .biz-card .card-body {
    flex: 1 1 auto !important;
    min-width: 0 !important;
    padding: 0 !important;
    display: flex !important;
    flex-direction: column !important;
    justify-content: space-between !important;
  }
  [data-dir-grid] .biz-card .between {
    display: flex !important;
    align-items: flex-start !important;
    justify-content: space-between !important;
    gap: 8px !important;
  }
  [data-dir-grid] .biz-card .card-title-wrap {
    flex: 1 1 auto !important;
    min-width: 0 !important;
  }
  [data-dir-grid] .biz-card .card-title,
  [data-dir-grid] .biz-card .card-title a {
    font-size: 15px !important;
    font-weight: 800 !important;
    line-height: 1.35 !important;
    display: -webkit-box !important;
    -webkit-line-clamp: 2 !important;
    -webkit-box-orient: vertical !important;
    overflow: hidden !important;
    color: var(--color-foreground) !important;
  }
  [data-dir-grid] .biz-card .card-badges-row {
    display: flex !important;
    align-items: center !important;
    gap: 4px !important;
    margin-top: 3px !important;
    flex-wrap: wrap !important;
  }
  [data-dir-grid] .biz-card .card-fav-btn {
    width: 44px !important;
    height: 44px !important;
    min-width: 44px !important;
    min-height: 44px !important;
    flex: 0 0 44px !important;
  }
  [data-dir-grid] .biz-card .card-fav-btn svg {
    width: 18px !important;
    height: 18px !important;
  }
  [data-dir-grid] .biz-card .card-desc {
    display: -webkit-box !important;
    -webkit-line-clamp: 1 !important;
    -webkit-box-orient: vertical !important;
    overflow: hidden !important;
    font-size: 12.5px !important;
    color: var(--color-muted-foreground) !important;
    margin-top: 3px !important;
    line-height: 1.4 !important;
  }
  [data-dir-grid] .biz-card .cluster.mt-sm,
  [data-dir-grid] .biz-card .cluster.mt-md { display: none !important; }
  [data-dir-grid] .biz-card .stars svg { width: 13px !important; height: 13px !important; }
  [data-dir-grid] .biz-card .card-meta {
    font-size: 12px !important;
    gap: 5px !important;
    margin-top: 3px !important;
    color: var(--color-muted-foreground) !important;
    display: flex !important;
    align-items: center !important;
    flex-wrap: wrap !important;
  }
  [data-dir-grid] .biz-card .card-foot {
    margin-top: 6px !important;
    padding-top: 4px !important;
    border-top: 1px dashed var(--color-border) !important;
    display: flex !important;
    align-items: center !important;
    justify-content: space-between !important;
  }
  [data-dir-grid] .biz-card .card-foot .card-meta {
    font-size: 12px !important;
    color: var(--color-muted-foreground) !important;
    margin: 0 !important;
  }
  [data-dir-grid] .biz-card .card-foot .card-meta span {
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    white-space: nowrap !important;
    max-width: 200px !important;
  }
  [data-dir-grid] .biz-card .badge {
    font-size: 12px !important;
    padding: 2px 7px !important;
    border-radius: var(--radius-pill) !important;
    gap: 3px !important;
  }
  [data-dir-grid] .biz-card [data-open-badge] { padding: 2px 7px !important; font-size: 12px !important; }
  [data-dir-grid] .biz-card [data-open-badge] svg { width: 12px !important; height: 12px !important; }

  /* Directory toolbar on mobile */
  .dir-toolbar {
    padding: 12px !important;
    border-radius: var(--radius-xl) !important;
    gap: 10px !important;
  }
  .dir-toolbar .input {
    min-height: 46px !important;
    /* v375: 16px prevents mobile browser text zoom and preserves readable search. */
    font-size: 16px !important;
  }
  .dir-chips {
    display: flex !important;
    flex-wrap: wrap !important;
    gap: 8px !important;
    overflow-x: visible !important;
    overflow-y: hidden !important;
    max-height: 104px !important;
    scrollbar-width: none !important;
    padding-block: 4px !important;
  }
  .dir-chips::-webkit-scrollbar { display: none !important; }
  .dir-chips.is-expanded {
    max-height: 58vh !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch !important;
  }
  .dir-chips .chip {
    flex: 0 0 auto !important;
    min-height: 44px !important;
    padding: 8px 14px !important;
    font-size: 13px !important;
    border-radius: var(--radius-pill) !important;
    white-space: nowrap !important;
  }

  /* hero: compact, search-forward */
  .hero { padding-block: var(--space-md) var(--space-sm); gap: var(--space-sm); min-height: auto !important; }
  .hero h1 { font-size: 1.2rem !important; line-height: 1.3; }
  .hero-lead { font-size: 0.875rem; line-height: 1.6; }
  .hero-trust { display: none; }
  /* v66: .hero-side stays visible on phones (see mobile-standard.css) */
  .hero-search { flex-wrap: nowrap; }
  .hero-search .input { min-height: 44px; font-size: 16px; }
  .hero-cta { gap: 12px; margin-top: var(--space-sm); }
  .hero-cta .btn { flex: 1 1 auto; }
  .hero-panel { padding: var(--space-sm) var(--space-md); }
  .hero-mini { gap: 6px; }
  .hero-mini .t { font-size: var(--fs-sm); }
  .hero-mini .s { font-size: 12px; }

  /* stat numbers + section heads (token-capped above; tighten the rest) */
  .stat-value { font-size: 1.2rem !important; }
  .stat-card { padding: var(--space-sm) var(--space-md); min-height: auto; }
  .stat-icon { width: 40px; height: 40px; }
  .stat-icon svg { width: 20px; height: 20px; }
  .stat-label { font-size: 12px; }
  .section-head { gap: 6px; margin-bottom: var(--space-md); }
  .section-head .eyebrow { font-size: 12px; padding: 4px 10px; margin-bottom: 6px; }
  .section-head p { font-size: var(--fs-sm); line-height: 1.6; }
  .page-hero { padding-block: var(--space-md) var(--space-sm); }

  .card-pad { padding: var(--space-md); }
  .cluster { gap: 8px; flex-wrap: wrap; }

  /* owner/admin dashboard inline 2-col grid must stack (was merging) */
  .panel-layout .grid-2,
  .panel-layout .grid-3 { grid-template-columns: 1fr !important; }

  /* smaller menu drawer */
  .mobile-nav .panel { width: min(72vw, 280px) !important; padding: var(--space-md) var(--space-sm) !important; gap: 2px !important; }
  .mobile-nav .panel a,
  .mobile-nav .panel button { min-height: var(--tap) !important; padding-block: 8px !important; padding-inline: 12px !important; font-size: 0.9286rem !important; border-radius: var(--radius-sm) !important; }
  .mobile-nav .panel a svg { width: 17px; height: 17px; }

  /* submit form door */
  .more-fields > summary { padding: var(--space-md); border-radius: var(--radius-md); border: 1px dashed var(--color-border-strong); background: color-mix(in oklab, var(--color-primary) 4%, transparent); }
  .more-fields > summary small { display: block; margin-top: 2px; }
  .more-fields-body { padding: var(--space-md) 4px var(--space-sm); }
  .sub-fields { margin-block: var(--space-md); }

  /* map sheet — v109: the 40vh !important cap broke the 45%-of-stage rule in
     pages.css (the sheet grew past half the map again). The stage cap stays. */
  .map-stage { min-height: 56vh !important; }
  .cat-grid { gap: 10px !important; }

  /* global text-safety: flex children shrink, long words wrap, call-bar truncates.
     Icon buttons in the header are EXCLUDED — min-width:0 was squashing them to
     16px and making the theme/cart toggles impossible to tap. */
  .between > *, .cluster > *, .card-foot > *, .call-bar > *, .hero-cta > *,
  .header-actions > :not(.btn-icon):not(.nav-toggle):not(.fav-btn):not(.icon-btn) { min-width: 0; }
  /* v118: but real buttons must keep the tap floor — the generic min-width:0
     above was collapsing short action labels («ویرایش») to 28px wide */
  .between .btn, .cluster .btn, .card-foot .btn { min-width: var(--tap); }
  .header-actions .btn-icon, .header-actions .nav-toggle, .header-actions .fav-btn,
  .header-actions .icon-btn { min-width: var(--tap); flex: 0 0 auto; }
  .card-title, .card-desc, .card-meta, .review-body, .info-row .v,
  .hero-lead, .hero h1, .section-head h2, .page-hero h1, .tk-meta, .ms-row,
  .brand-text, .panel-head h1 { overflow-wrap: anywhere; }
  .call-bar { flex-wrap: nowrap; }
  .call-bar .cb-main { min-width: 0; flex: 1 1 auto; }
  .call-bar .cb-main span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .call-bar .cb-side { flex: none; }
  .info-row { gap: 10px; }
}

/* ---------- 3. PHONES (≤480px): cap headings a touch smaller ---------- */
@media (max-width: 480px) {
  :root {
    --fs-3xl: 1.25rem;   /* 20px */
    --fs-4xl: 1.5rem;    /* 24px */
  }
  .hero h1 { font-size: 1.1rem !important; }
  .hero-cta { flex-direction: column; }
  .hero-cta .btn { width: 100%; }
}

/* ---------- 3b. DENSER PHONE LAYOUT (v24 — "still zoomed" fix) ----------
   On a 360–430px screen 15px body + 24px titles still reads oversized.
   Torob/Digikala run 12–14px text with tight cards. Shrink type and gutters
   one notch further so more cards fit per screen — cards are the product. */
@media (max-width: 480px) {
  :root {
    --space-md: 12px;
    --space-lg: 16px;
    --fs-base: 0.875rem;   /* 14px body */
    --fs-lg:  0.9375rem;   /* 15px card titles */
    --fs-2xl: 1.125rem;    /* 18px stats */
    --fs-3xl: 1.1875rem;   /* 19px section titles */
    --fs-4xl: 1.3125rem;   /* 21px hero */
  }
  body { font-size: 0.875rem; line-height: 1.5; }
  .section    { padding-block: 20px !important; }
  .section-sm { padding-block: 14px !important; }
  .container, .container-wide { width: min(100% - 20px, var(--container-wide)) !important; }

  /* cards first: tighter, more per screen */
  .grid, .grid-2, .grid-3, .grid-4 { gap: 8px !important; }
  .biz-card .card-title, .biz-card .card-title a { font-size: 0.8125rem !important; } /* 13px */
  .biz-card .card-meta { font-size: 12px !important; }
  .biz-card .badge { font-size: 12px !important; }

  .section-head { margin-bottom: 10px; }
  .section-head h2 { font-size: 1.0625rem !important; }   /* 17px */
  .section-head p { font-size: 0.8125rem !important; }
  .section-head .eyebrow { font-size: 12px !important; }

  .hero { padding-block: 10px 8px !important; }
  .hero h1 { font-size: 1.0625rem !important; line-height: 1.35; }
  .hero-lead { font-size: 0.8125rem !important; }
  .page-hero { padding-block: 12px 8px !important; }
  .page-hero h1 { font-size: 1.125rem !important; }

  .stat-value { font-size: 1.125rem !important; }
  .card-pad { padding: 12px !important; }
  .btn { min-height: var(--tap); }   /* v116-audit: 42px violated the 44px touch law */
  .btn-sm { min-height: var(--tap); padding: 8px 14px; font-size: 12px; }
}

@media (max-width: 380px) {
  .grid-3, .grid-4 { gap: 8px !important; }
}

/* ==========================================================================
   v119 — کارت انتخاب‌شدهٔ نقشه: پنل ثابت بدون اسکرول (قفل نهایی)
   این بلوک باید بعد از قواعد پایهٔ .ms-* بیاید تا wrap نشوند.
   ========================================================================== */
@media (max-width: 1024px) {
  .map-selected .ms-head { flex-wrap: nowrap !important; }
  .map-selected .ms-head .badge { margin-inline-start: auto; flex: none; white-space: nowrap; }
  .map-selected .ms-title strong {
    display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .map-selected .ms-acts { flex-wrap: nowrap !important; }
  .map-selected .ms-acts .btn {
    flex: 1 1 0 !important; min-width: 0 !important;
    padding-inline: 4px !important; font-size: var(--fs-xs);
  }
}

/* v119 — فشرده‌سازی نهایی پنل ثابت (بدون اسکرول) */
@media (max-width: 1024px) {
  .map-selected { gap: 4px !important; padding: 7px 10px !important; }
  .map-selected .ms-head img { width: 24px !important; height: 24px !important; }
  .map-selected .ms-head { gap: 6px; }
  .map-selected .ms-meta { gap: 4px; }
  .map-selected .ms-row { line-height: 1.4; }
  .map-selected .ms-acts .btn { min-height: 44px; } /* v176: قانون لمس */
}

/* v119 — حذف ردیف «دسته» در پنل موبایل: نام + آدرس + دکمهها کافی‌اند */
@media (max-width: 1024px) {
  .map-selected .ms-sub { display: none !important; }
}

/* v119 — آیکون پنل نقشه در موبایل کوچک (فقط ۲۸px تا کارت بدون اسکرول جا شود) */
@media (max-width: 1024px) {
  .map-selected .ms-head .ic { width: 28px !important; height: 28px !important; }
}

/* v120 — PRICING موبایل استاندارد: قیمت باید درشت باشد، نه هماندازهٔ توضیح.
   (قانون آئودیت موبایل `.nums` را به ۱۲px با !important میبرد و قیمت پلن
   را کوچک میکرد — اینجا همان اندازهٔ واقعی بازگردانده میشود.) */
@media (max-width: 1024px) {
  .price-grid { gap: var(--space-md); }
  .price-card { padding: var(--space-lg) 18px; border-radius: var(--radius-xl); }
  .price-amount { margin: var(--space-md) 0; }
  .price-amount .n { font-size: var(--fs-3xl) !important; line-height: 1.25; }
  .price-amount .u { font-size: 13px; }
  .price-name { font-size: var(--fs-lg); }
  .price-desc { font-size: 13px; }
  .price-feat { font-size: 13px; }
  .price-card .btn { min-height: 48px; width: 100%; justify-content: center; }
  .bill-toggle { width: 100%; gap: 6px; }
  .bill-toggle button { flex: 1 1 auto; padding: 10px 6px; font-size: 13px; white-space: nowrap; }

  /* v124 — استانداردهای موبایل پنل دکان‌دار */
  .biz-own-card {
    padding: 14px !important;
    border-radius: var(--radius-xl) !important;
  }
  .biz-own-head {
    flex-direction: column !important;
    gap: 12px !important;
  }
  .biz-own-media {
    width: 100% !important;
    height: 150px !important;
    border-radius: var(--radius-lg) !important;
  }
  .biz-own-stats {
    display: grid !important;
    grid-template-columns: repeat(4, 1fr) !important;
    gap: 4px !important;
    padding: 8px 4px !important;
    margin-block: 8px 10px !important;
  }
  .biz-stat-item {
    font-size: 12px !important;
    gap: 1px !important;
  }
  .biz-stat-item strong {
    font-size: 14px !important;
  }
  .biz-own-actions {
    display: grid !important;
    grid-template-columns: repeat(3, 1fr) !important;
    gap: 6px !important;
  }
  .biz-own-actions .btn {
    padding: 6px 4px !important;
    font-size: 12px !important;
    min-height: 44px !important; /* v176: قانون لمس ≥۴۴px (قبلاً ۳۸px) */
    border-radius: var(--radius-md) !important;
    gap: 4px !important;
  }
  .biz-own-actions .btn svg {
    width: 13px !important;
    height: 13px !important;
  }
  .panel-nav-grid {
    grid-template-columns: repeat(2, 1fr) !important;
    gap: 8px !important;
  }
  .panel-nav-tile {
    padding: 8px 10px !important;
    min-height: 48px !important;
    font-size: 12.5px !important;
    gap: 6px !important;
  }
  .panel-nav-tile svg {
    width: 16px !important;
    height: 16px !important;
  }
  .story-own-row {
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 10px !important;
  }
  .story-own-form {
    display: flex !important;
    flex-direction: column !important;
    gap: 8px !important;
    width: 100% !important;
  }
  .story-own-form .input {
    width: 100% !important;
    min-height: 44px !important;
  }
}
/* ===== END mobile-refine.css ===== */

/* ===== BEGIN mobile-standard.css sha256:ca189a4bf35b6eee ===== */
/* ==========================================================================
   Bazarche — MOBILE STANDARD DESIGN SYSTEM  (v35)
   Loaded LAST. Two jobs:
     1. Kill the Chrome/Android-WebView "font boosting" bug — the real cause
        of the site looking permanently zoomed-in on phones (text-size-adjust
        alone is NOT enough; the browser inflates text on elements with no
        explicit height, so every text block gets max-height).
     2. A clean, standards-based mobile layer (Material/HIG-informed):
        4pt spacing grid, 44px touch floor, fluid clamp() type, tight hero,
        two-up cards with a 4:3 image and a soft elevation.
   ========================================================================== */

/* ---- 1. DEFINITIVE ANTI-ZOOM (Chrome & WebView font boosting) ---------- */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
/* Font boosting only hits blocks with "dynamic" (auto) height. Giving every
   text block an effectively unbounded max-height switches the heuristic off
   and stops Android inflating the whole page. Does not affect layout. */
body,
h1, h2, h3, h4, h5, h6,
p, .card-title, .card-desc, .card-meta, .hero-lead, .hero-badge,
.section-head, .section-head h2, .section-head p, .eyebrow,
.stat-value, .stat-label, .biz-card .card-body, .item-card .card-body,
li, blockquote, figcaption, .review-body, .msg-bubble, .brand-text {
  max-height: 999999px;
}

/* ---- 2. FLUID TYPE SCALE (clamp — grows with screen, never absurd) ---- */
@media (max-width: 768px) {
  :root {
    --fs-xs:   0.75rem;    /* v66: 12px floor — captions included */
    --fs-sm:   0.75rem;                                     /* 12px secondary */
    --fs-base: 0.875rem; /* v66: 14px body floor (owner red line) */
    --fs-lg:   clamp(0.875rem, 0.84rem + 0.4vw, 0.9375rem); /* 14–15px titles*/
    --fs-xl:   clamp(1rem, 0.96rem + 0.5vw, 1.125rem);      /* 16–18px      */
    --fs-2xl:  clamp(1.125rem, 1.06rem + 0.7vw, 1.3125rem); /* 18–21px stats*/
    --fs-3xl:  clamp(1.125rem, 1.05rem + 0.8vw, 1.375rem);  /* 18–22px h2   */
    --fs-4xl:  clamp(1.25rem, 1.12rem + 1vw, 1.625rem);     /* 20–26px hero */
    /* 4pt spacing grid */
    --space-xs: 4px;  --space-sm: 8px;  --space-md: 12px;
    --space-lg: 16px; --space-xl: 24px; --space-2xl: 32px;
  }
  body { font-size: var(--fs-base); line-height: 1.6; }

  /* ---- 3. COMPACT, ELEGANT HERO ---- */
  .hero { padding-block: 14px 12px !important; gap: 10px; min-height: auto !important; }
  .hero h1 { font-size: var(--fs-4xl) !important; line-height: 1.35;
             letter-spacing: -.01em; }
  .hero-lead { font-size: var(--fs-base) !important; line-height: 1.7;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden; }
  .hero-badge { font-size: 12px; padding: 5px 12px; }
  .hero-search { gap: 8px; }
  .hero-search .input { min-height: 48px; font-size: 16px; border-radius: 14px; }
  .hero-search .btn { min-height: 48px; border-radius: 14px; flex: none; }
  /* two primary actions side-by-side — never stacked (saves a full row).
     v89: 8px read as "touching"; 12px gives the two CTAs breathing room
     without costing a row or overflowing a 360px screen. */
  .hero-cta { flex-direction: row !important; gap: 12px; }
  .hero-cta .btn { flex: 1 1 0; min-height: 46px; border-radius: 13px;
    padding-inline: 10px; font-size: 13px; white-space: nowrap; }
  /* v66: hero-side (the "open now" panel) is back on mobile — the page it
     lives on is the most-seen surface, and the test suite + the owner both
     want it visible. Trust row + scroll cue stay hidden to keep the hero
     compact (pages.css re-orders the panel right under the CTAs). */
  .hero-trust, .scroll-cue { display: none !important; }

  /* ---- 4. SECTION RHYTHM ---- */
  .section { padding-block: 22px !important; }
  .section-sm { padding-block: 16px !important; }
  .section-head { margin-bottom: 12px; }
  .section-head .eyebrow { font-size: 12px; padding: 4px 10px; }
  .section-head h2 { font-size: var(--fs-3xl); letter-spacing: -.01em; }
  .section-head p { font-size: var(--fs-sm); }
  .page-hero { padding-block: 14px 10px !important; }
  .page-hero h1 { font-size: var(--fs-4xl) !important; letter-spacing: -.01em; }
  .page-hero p { font-size: var(--fs-sm); }
  /* Specific override stays compact and raises the title row slightly. */
  .page-hero.notifications-hero { padding-block: 2px 12px !important; }
  /* v286 audit (ممیزی کامل به دستور مدیر): سربرگِ یک‌ردیفه و فشرده برمی‌گردد.
     wrap در v157 برای جلوگیری از له‌شدنِ تک‌دکمه بود، ولی بعد از افزودنِ
     «تنظیم اعلان‌ها» هیرو در ۳۶۰–۴۱۲px دورِدیفه و ۹۳px شد (آزمون
     test_section1: هم‌ردیفی ≤6px و ارتفاع ≤80px). دکمه‌ها همچنان هرگز له
     نمی‌شوند (flex:none باقی است) — در عوض آیکون‌ها در صفحهٔ باریک حذف
     می‌شوند تا ردیف جا شود. */
  .page-hero.notifications-hero { flex-wrap: nowrap; }
  .page-hero.notifications-hero h1 svg,
  .page-hero.notifications-hero .cluster .btn svg { display: none; }
  .page-hero.notifications-hero .cluster { gap: 6px; flex-wrap: nowrap; }
  .page-hero.notifications-hero .cluster .btn-sm { padding-inline: 10px; }
  .page-hero.notifications-hero p { flex: 1 1 100%; order: 3; margin-top: 2px; }
  .page-hero.notifications-hero .btn { flex: none; }

  /* ---- 5. STANDARD MOBILE BUSINESS DIRECTORY CARDS (DIVAR/TOROB 1-COLUMN) ---- */
  [data-dir-grid], .grid-3:has(> .biz-card), .grid-4:has(> .biz-card) {
    grid-template-columns: 1fr !important;
    gap: 12px !important;
  }
  .biz-card {
    border-radius: 16px !important;
    box-shadow: 0 1px 4px rgba(0,0,0,.08);
  }
  .biz-card .card-title, .biz-card .card-title a {
    font-size: 15px !important;
    font-weight: 800 !important;
    line-height: 1.35;
  }
  .biz-card .card-meta { font-size: 12px; gap: 5px; margin-top: 3px; }
  .biz-card .card-foot { margin-top: 6px; padding-top: 6px; }
  .biz-card .card-foot .card-meta { font-size: 12px; }
  .biz-card .badge { font-size: 12px; padding: 2px 7px; }
  .biz-card .fav-btn { width: 44px; height: 44px; }

  /* item cards in the catalogue */
  .item-card .card-title { font-size: 0.8125rem; -webkit-line-clamp: 2; }
  .item-price { font-size: var(--fs-lg); }

  /* ---- 6. STATS ---- */
  .stat-card { padding: 12px 14px; border-radius: 14px; }
  .stat-value { font-size: var(--fs-2xl) !important; }
  .stat-icon { width: 38px; height: 38px; }
  .stat-label { font-size: 12px; }

  /* ---- 7. CONTAINER GUTTERS (even 16px) ---- */
  .container, .container-wide { width: min(100% - 24px, var(--container-wide)) !important; }

  /* ---- 8. CARDS / SURFACES ---- */
  .card { border-radius: 16px; }
  .card-pad { padding: 14px; }
  .btn { border-radius: 12px; }
  .btn-lg { border-radius: 14px; }
  .input, .textarea, .select { border-radius: 12px; min-height: 46px; font-size: 16px; }
  .chip, .sub-pill { border-radius: 999px; }

  /* ---- 9. STORY BAR ---- */
  .story-ring-inner { width: 56px; height: 56px; }
  .story-name { font-size: 12px; max-width: 58px; }

  /* ---- 10. FOOTER ---- */
  .site-footer { padding-block: 22px 90px; }
}

/* ---- 11. VERY SMALL (≤360px) — keep it readable but never cramped ---- */
@media (max-width: 360px) {
  .grid-3, .grid-4 { gap: 8px !important; }
  .biz-card .card-body { padding: 8px; }
}

/* v286 audit: در ۳۲۰–۳۵۹px هم ردیفِ عنوان+دو دکمه جا شود (نگرانی v157). */
@media (max-width: 359px) {
  .page-hero.notifications-hero .cluster { gap: 4px; }
  .page-hero.notifications-hero .cluster .btn-sm { padding-inline: 8px; }
}
/* ===== END mobile-standard.css ===== */

/* ===== BEGIN theme-night.css sha256:d1117d264b667b7c ===== */
/* ==========================================================================
   Bazarche — Night theme (حالت شب) · v111 «رسمی»
   ==========================================================================
   ⚠️ این فایل عمداً «تقریباً خالی» است — توکن‌های شب در tokens.css زیر
   :root[data-theme="dark|night|luxury"] تعریف شده‌اند.

   حذف‌شده‌های نسخهٔ قبلی (به درخواست کاربر: «نه خیلی لوکس و رنگی»):
     • هاله‌های محیطی طلایی/پاتینه روی body (radial-gradient)
     • بافت گره‌چینی SVG روی body::before
     • تیترهای گرادیانی (عاج ← شامپاین ← طلا)
     • خط‌های مویی طلایی، سایه‌های درخشان (e-glow-gold)، بلور ۲۸px
   جایگزین: پس‌زمینهٔ یکدست تیره، مرز خاکستری، سایهٔ کوتاه، یک رنگ آبی.

   قانون: هیچ رنگ مستقیمی اینجا ننویس. اگر چیزی در شب محو شد، توکنِ شب را
   در tokens.css درست کن، نه اینکه یک override اینجا اضافه کنی.
   ========================================================================== */

:root[data-theme="dark"],
:root[data-theme="night"],
:root[data-theme="luxury"] {
  color-scheme: dark;
}

body {
  background-color: var(--color-background);
  background-image: none;
}

/* لایهٔ شیشه‌ای در شب هم مات است؛ بلور حذف شد (خوانایی + سرعت روی گوشی). */
.glass,
.site-header,
.bottom-nav {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
/* ===== END theme-night.css ===== */

/* ===== BEGIN theme-light.css sha256:5e1d80f07ece3795 ===== */
/* ==========================================================================
   Bazarche — Day theme (حالت روز) · v111 «رسمی»
   ==========================================================================
   ⚠️ این فایل عمداً «تقریباً خالی» است.

   تا v110 دو فایل theme-night.css و theme-light.css ده‌ها قانون ساختاری
   (هاله، گرادیان طلایی، بافت گره‌چینی، بلور شیشه‌ای، override رنگ متنِ
   کلاس‌های خاص) داشتند. همان overrideها ریشهٔ «متن محو» بودند: هر کلاسی
   که در این فایل‌ها جا می‌ماند، در یکی از دو حالت با رنگ غلط رندر می‌شد.

   قانون v111 (قانون ۷ در RULES.md):
     • هر دو تم یک CSS مشترک دارند؛ تفاوت فقط در «مقادیر توکن» است.
     • توکن‌های حالت روز در tokens.css زیر :root تعریف شده‌اند (پیش‌فرض).
     • این فایل فقط استثنائای واقعاً لازمِ روز را نگه می‌دارد و هر استثنایی
       که اینجا اضافه می‌شود باید دلیل AA داشته باشد و در CLAUDE.md ثبت شود.
   ========================================================================== */

:root[data-theme="light"] {
  color-scheme: light;
}

/* صفحهٔ روز رنگِ یکدست دارد: بدون هاله، بدون گرادیان محیطی، بدون بافت. */
body {
  background-color: var(--color-background);
  background-image: none;
}

/* لایهٔ «شیشه‌ای» در روز مات است؛ بلور فقط بار رندر اضافه می‌کند و متنِ
   پشتش را نیمه‌محو می‌کند. */
.glass,
.site-header,
.bottom-nav {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
/* ===== END theme-light.css ===== */
