/* ==========================================================================
   CloudSnap Customer Panel — Design System
   --------------------------------------------------------------------------
   One hand-authored stylesheet. No build step, no Tailwind, no Filament.
   Semantic `cs-` classes only. Light theme (palette is mandated light).

   Palette (fixed, from brand):
     paper   #D8E1E7  — page background, dominant
     ink     #2A231F  — text, borders, hard shadows
     navy    #00478F  — primary
     orange  #FF5D00  — secondary / CTA accent

   Physics: every interactive surface is "tactile" — 2px ink border + hard
   offset shadow; hover lifts, press collapses the shadow. The offset flips
   horizontally in RTL via --px.
   ========================================================================== */

/* ----- Fonts (vendored, variable) ---------------------------------------- */
@font-face {
  font-family: 'Space Grotesk';
  src: url('../fonts/SpaceGrotesk-var.woff2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('../fonts/Inter-var.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Vazirmatn';
  src: url('../fonts/Vazirmatn-var.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
/* Country-flag glyphs (Twemoji, via country-flag-emoji-polyfill): Windows
   ships no emoji flags, so 🇩🇪 renders as bare "DE" letters there. The
   unicode-range pins this face to the regional-indicator pair block only, so
   it downloads once and touches nothing but flags. */
@font-face {
  font-family: 'Twemoji Country Flags';
  src: url('../fonts/TwemojiCountryFlags.woff2') format('woff2');
  unicode-range: U+1F1E6-1F1FF;
  font-display: swap;
}

/* ----- Tokens ------------------------------------------------------------- */
:root {
  /* Brand */
  --paper:        #D8E1E7;
  --paper-soft:   #E6EDF1;   /* wells on paper */
  --surface:      #FFFFFF;
  --surface-2:    #F2F6F8;   /* wells on white */
  --ink:          #2A231F;
  --ink-70:       rgba(42, 35, 31, .72);
  --ink-50:       rgba(42, 35, 31, .52);
  --ink-15:       rgba(42, 35, 31, .16);
  --ink-08:       rgba(42, 35, 31, .08);

  --navy:         #00478F;
  --navy-deep:    #003568;
  --navy-tint:    #DBE7F3;
  --orange:       #FF5D00;
  --orange-deep:  #E14F00;
  --orange-tint:  #FFE4D4;

  /* Semantic */
  --success:      #0E7B43;
  --success-tint: #DDF1E6;
  --warning:      #A85B00;
  --warning-tint: #FFEDD6;
  --danger:       #CC2B2B;
  --danger-tint:  #FBE2E2;
  --info:         var(--navy);
  --info-tint:    var(--navy-tint);

  /* Text-sized accent usages. The deep brand accents work as SURFACES in both
     themes (white label on navy stays AA on a dark page), but as 12–15px TEXT
     they vanish on a dark ground — night mode swaps only these for brightened
     siblings while the surface tokens above stay put. */
  --link:           var(--navy);
  --link-hover:     var(--navy-deep);
  --navy-bright:    var(--navy);
  --success-bright: var(--success);
  --warning-bright: var(--warning);
  --danger-bright:  var(--danger);
  /* Ink-on-accent (orange buttons, tape, checkbox tick): stays dark in night
     mode even though --ink flips to the light paper tone. */
  --on-accent:      var(--ink);
  /* Hard offset shadows stay dark in both themes (a light "shadow" reads as a
     glow, not print) — so shadows get their own colour, decoupled from --ink. */
  --shadow-ink:     var(--ink);

  /* Type */
  --font-display: 'Space Grotesk';
  --font-body:    'Inter';
  --font-mono:    ui-monospace, 'SF Mono', 'Cascadia Mono', Menlo, Consolas, monospace;
  --fs-xs:  .75rem;    /* 12 */
  --fs-sm:  .8125rem;  /* 13 */
  --fs-md:  .9375rem;  /* 15 — base */
  --fs-lg:  1.0625rem; /* 17 */
  --fs-xl:  1.3125rem; /* 21 */
  --fs-2xl: 1.625rem;  /* 26 */
  --fs-3xl: 2.0625rem; /* 33 */
  --fs-4xl: 2.5625rem; /* 41 */
  --fs-5xl: 3.25rem;   /* 52 */

  /* Space (4px scale) */
  --sp-1: .25rem;  --sp-2: .5rem;  --sp-3: .75rem; --sp-4: 1rem;
  --sp-5: 1.25rem; --sp-6: 1.5rem; --sp-8: 2rem;   --sp-10: 2.5rem;
  --sp-12: 3rem;   --sp-16: 4rem;  --sp-20: 5rem;

  /* Shape */
  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 18px;
  --r-xl: 26px;
  --r-full: 999px;
  --bw: 2px;                      /* signature border width */

  /* Tactile shadow offset — --px flips in RTL */
  --px: 4px;
  --py: 4px;
  --shadow:      var(--px) var(--py) 0 var(--shadow-ink);
  --shadow-lg:   calc(var(--px) * 1.5) calc(var(--py) * 1.5) 0 var(--shadow-ink);
  --shadow-soft: 0 1px 0 var(--ink-15);

  /* Layout */
  --sidebar-w: 264px;
  --content-max: 1180px;
  --topbar-h: 76px;

  /* Motion */
  --ease-snap: cubic-bezier(.2, .9, .3, 1.3);
  --ease-out:  cubic-bezier(.22, .8, .36, 1);
  --t-fast: 130ms;
  --t-med:  220ms;

  /* Z */
  --z-nav: 40; --z-drop: 50; --z-modal: 70; --z-toast: 90; --z-busy: 100;

  accent-color: var(--navy-bright);
  color-scheme: light;
}

html[dir='rtl'] { --px: -4px; }
html[lang='fa'] {
  --font-display: 'Vazirmatn';
  --font-body:    'Vazirmatn';
}

/* ----- Night mode -----------------------------------------------------------
   The same four brand codes, printed in negative: light mode is ink on paper,
   night mode is paper on ink. Surfaces come from the brand ink (#2A231F),
   text and borders from the brand paper (#D8E1E7); navy and orange stay the
   accents, with brightened siblings for text-sized uses (see --link et al.).
   The attribute is set before first paint by boot.js (localStorage → system
   preference) and server-rendered from the cs_theme cookie, so there is no
   flash on either path. */
html[data-theme='dark'] {
  --paper:        #16110D;   /* brand ink, deepened — page background */
  --paper-soft:   #201914;
  --surface:      #2A231F;   /* the brand ink, verbatim — cards */
  --surface-2:    #362D26;
  --ink:          #D8E1E7;   /* the brand paper, verbatim — text & borders */
  --ink-70:       rgba(216, 225, 231, .78);
  --ink-50:       rgba(216, 225, 231, .58);
  --ink-15:       rgba(216, 225, 231, .20);
  --ink-08:       rgba(216, 225, 231, .10);

  --navy-tint:    #1D3450;
  --orange-tint:  #46250F;

  --success-tint: #123B27;
  --warning-tint: #3D2B10;
  --danger-tint:  #421715;

  --link:           #7FB2E8;
  --link-hover:     #A6CBF2;
  --navy-bright:    #7FB2E8;
  --success-bright: #4CC98A;
  --warning-bright: #E7A94F;
  --danger-bright:  #F27A6F;
  --on-accent:      #16110D;
  --shadow-ink:     #0A0705;

  color-scheme: dark;
}

/* ----- Reset / base -------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  /* The flag face first: its unicode-range means it ONLY ever serves the
     regional-indicator flag pairs; all real text falls through. */
  font-family: 'Twemoji Country Flags', var(--font-body), 'Vazirmatn', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: var(--fs-md);
  line-height: 1.55;
  color: var(--ink);
  background: var(--paper);
  min-height: 100dvh;
  -webkit-font-smoothing: antialiased;
  touch-action: manipulation;
}

img, svg { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; padding: 0; }
a { color: var(--link); text-decoration-thickness: 2px; text-underline-offset: 3px; }
a:hover { color: var(--link-hover); }
::selection { background: var(--orange-tint); color: var(--ink); }
::placeholder { color: var(--ink-50); opacity: 1; }
[hidden] { display: none !important; }

:focus-visible {
  outline: 3px solid var(--navy-bright);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Language-conditional helpers */
html[lang='fa'] [data-only='en'] { display: none !important; }
html[lang='en'] [data-only='fa'] { display: none !important; }
html[lang='fa'] body { letter-spacing: 0; }
.cs-latin { direction: ltr; unicode-bidi: isolate; font-family: var(--font-mono); }

/* ----- Typography ----------------------------------------------------------- */
h1, h2, h3, h4, .cs-display {
  font-family: var(--font-display), 'Vazirmatn', system-ui, sans-serif;
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.015em;
  text-wrap: balance;
}
html[lang='fa'] :is(h1, h2, h3, h4, .cs-display) { letter-spacing: 0; line-height: 1.35; }

h1 { font-size: var(--fs-3xl); }
h2 { font-size: var(--fs-2xl); }
h3 { font-size: var(--fs-xl); }
h4 { font-size: var(--fs-lg); }

.cs-eyebrow {
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--navy-bright);
}
html[lang='fa'] .cs-eyebrow { letter-spacing: .04em; }

.cs-muted   { color: var(--ink-70); }
.cs-faint   { color: var(--ink-50); }
.cs-small   { font-size: var(--fs-sm); }
.cs-xs      { font-size: var(--fs-xs); }
.cs-strong  { font-weight: 650; }
.cs-num {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum';
}
.cs-mono { font-family: var(--font-mono); font-size: .92em; direction: ltr; unicode-bidi: isolate; }
.cs-nowrap { white-space: nowrap; }
.cs-break  { overflow-wrap: anywhere; }

/* Signature: straight orange marker under key titles. A pure-CSS ::after bar,
   so it is always exactly as wide as the text, perfectly straight, and visible
   even without JS; the draw animation runs only on JS-marked documents. */
.cs-scribble { position: relative; display: inline-block; }
.cs-scribble::after {
  content: '';
  position: absolute;
  inset-inline: 0.04em;
  bottom: -0.18em;
  height: 0.14em;
  border-radius: var(--r-full);
  background: var(--orange);
  transform-origin: 0 50%;
}
html[dir='rtl'] .cs-scribble::after { transform-origin: 100% 50%; }
html.js .cs-scribble::after { animation: cs-scribble-draw .55s var(--ease-out) .3s backwards; }
@keyframes cs-scribble-draw { from { transform: scaleX(0); } }

/* ----- Page scaffolding ------------------------------------------------------ */
/* Fully mirrored RTL: the shell uses logical properties throughout, so under
   dir=rtl the sidebar sits on the RIGHT, the topbar reads right-to-left and
   every menu/offset flips — nothing stays in its LTR spot. */
.cs-app { display: flex; min-height: 100dvh; }

.cs-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.cs-page {
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
  padding: var(--sp-6) var(--sp-8) var(--sp-16);
}

.cs-page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-4);
  flex-wrap: wrap;
  margin-block: var(--sp-2) var(--sp-8);
}
.cs-page-head h1 { font-size: var(--fs-3xl); }
.cs-page-sub { margin-top: var(--sp-2); color: var(--ink-70); max-width: 60ch; }

.cs-section { margin-block: var(--sp-10); }
.cs-section-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-4); margin-bottom: var(--sp-4); flex-wrap: wrap;
}

.cs-grid { display: grid; gap: var(--sp-5); }
.cs-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cs-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cs-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.cs-grid--cards { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
.cs-grid--tiles { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); }

.cs-stack   { display: flex; flex-direction: column; gap: var(--sp-4); }
.cs-stack-2 { display: flex; flex-direction: column; gap: var(--sp-2); }
.cs-row     { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.cs-row--between { justify-content: space-between; }
.cs-row--end { justify-content: flex-end; }
.cs-grow { flex: 1; min-width: 0; }
.cs-center { text-align: center; }

.cs-divider { border: 0; border-top: var(--bw) solid var(--ink); opacity: .14; margin-block: var(--sp-6); }

/* ----- Sidebar ---------------------------------------------------------------- */
.cs-sidebar {
  width: var(--sidebar-w);
  flex-shrink: 0;
  position: sticky;
  top: 0;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border-inline-end: var(--bw) solid var(--ink);
  padding: var(--sp-5) var(--sp-4);
  z-index: var(--z-nav);
}

.cs-logo {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-2) var(--sp-5);
  text-decoration: none; color: var(--ink);
}
.cs-logo svg { width: 40px; height: 40px; flex-shrink: 0; }
.cs-logo b {
  font-family: var(--font-display), 'Vazirmatn', sans-serif;
  font-size: var(--fs-xl); font-weight: 700; letter-spacing: -.02em;
}
html[lang='fa'] .cs-logo b { letter-spacing: 0; }

.cs-nav { display: flex; flex-direction: column; gap: var(--sp-1); flex: 1; overflow-y: auto; }
.cs-nav-label {
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-50);
  padding: var(--sp-4) var(--sp-3) var(--sp-1);
}
html[lang='fa'] .cs-nav-label { letter-spacing: .03em; }

.cs-nav-item {
  display: flex; align-items: center; gap: var(--sp-3);
  min-height: 44px;
  padding: var(--sp-2) var(--sp-3);
  border: var(--bw) solid transparent;
  border-radius: var(--r-sm);
  color: var(--ink);
  font-weight: 550;
  text-decoration: none;
  transition: background var(--t-fast) ease, transform var(--t-fast) var(--ease-out);
}
.cs-nav-item svg { width: 19px; height: 19px; flex-shrink: 0; }
.cs-nav-item:hover { background: var(--paper-soft); color: var(--ink); }
.cs-nav-item.is-active {
  background: var(--surface);
  border-color: var(--ink);
  box-shadow: var(--shadow);
  font-weight: 700;
}
.cs-nav-item.is-active svg { color: var(--orange); }
.cs-nav-item .cs-chip { margin-inline-start: auto; }

.cs-sidebar-foot { padding-top: var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-2); }

/* Wallet mini-card pinned in the sidebar */
.cs-wallet-pin {
  display: block;
  background: var(--navy);
  color: #fff;
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-md);
  box-shadow: var(--shadow);
  padding: var(--sp-3) var(--sp-4);
  text-decoration: none;
  transition: transform var(--t-fast) var(--ease-out), box-shadow var(--t-fast) var(--ease-out);
}
.cs-wallet-pin:hover { transform: translate(calc(var(--px) * -0.5), -2px); box-shadow: var(--shadow-lg); color: #fff; }
.cs-wallet-pin .cs-xs { color: rgba(255,255,255,.75); }
.cs-wallet-pin strong { font-size: var(--fs-lg); font-variant-numeric: tabular-nums; }
.cs-wallet-pin.is-debt { background: var(--danger); }

/* ----- Topbar ------------------------------------------------------------------ */
.cs-topbar {
  height: var(--topbar-h);
  display: flex; align-items: center; gap: var(--sp-4);
  padding-inline: var(--sp-8);
  border-bottom: var(--bw) solid var(--ink);
  background: var(--paper);
  position: sticky; top: 0; z-index: var(--z-nav);
}
.cs-topbar-title { font-family: var(--font-display), 'Vazirmatn', sans-serif; font-weight: 700; font-size: var(--fs-lg); }
.cs-topbar-spacer { flex: 1; }

/* Fully mirrored in RTL: burger + title start from the right, the controls
   cluster ends at the left, and the account menu drops from its own edge —
   the flex row and the menu's inset-inline-end mirror on their own. */

/* Desktop: no drawer, no burger. Doubled class beats `.cs-btn`'s later
   display:inline-flex (same-specificity order bug that left a dead burger
   visible on desktop). */
.cs-btn.cs-burger { display: none; }

/* ----- Buttons ------------------------------------------------------------------ */
.cs-btn {
  --btn-bg: var(--surface);
  --btn-fg: var(--ink);
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: 44px;
  padding: 0 var(--sp-5);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-weight: 650;
  font-size: var(--fs-md);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow);
  text-decoration: none;
  user-select: none;
  white-space: nowrap;
  transition: transform var(--t-fast) var(--ease-out), box-shadow var(--t-fast) var(--ease-out), background var(--t-fast) ease;
}
/* Icons scale WITH the label (1.05em) and sit on its optical centre, so they
   read as part of the text on every button size instead of floating beside it. */
.cs-btn svg { width: 1.05em; height: 1.05em; flex-shrink: 0; margin-block: -0.1em; }
.cs-btn:hover { transform: translate(calc(var(--px) * -0.5), -2px); box-shadow: var(--shadow-lg); color: var(--btn-fg); }
.cs-btn:active { transform: translate(var(--px), var(--py)); box-shadow: 0 0 0 var(--shadow-ink); }
.cs-btn:disabled, .cs-btn[aria-disabled='true'] {
  opacity: .55; cursor: not-allowed;
  transform: none; box-shadow: var(--shadow);
}

.cs-btn--primary { --btn-bg: var(--navy);   --btn-fg: #fff; }
.cs-btn--primary:hover { background: var(--navy-deep); }
.cs-btn--accent  { --btn-bg: var(--orange); --btn-fg: var(--on-accent); }
.cs-btn--accent:hover { background: var(--orange-deep); }
.cs-btn--danger  { --btn-bg: var(--danger); --btn-fg: #fff; }
.cs-btn--success { --btn-bg: var(--success); --btn-fg: #fff; }
.cs-btn--ghost {
  border-color: transparent; box-shadow: none; background: transparent;
}
.cs-btn--ghost:hover { background: var(--ink-08); transform: none; box-shadow: none; }
.cs-btn--ghost:active { transform: translate(1px, 1px); }

.cs-btn--sm { min-height: 36px; padding: 0 var(--sp-3); font-size: var(--fs-sm); border-radius: 9px; }
.cs-btn--lg { min-height: 54px; padding: 0 var(--sp-8); font-size: var(--fs-lg); border-radius: var(--r-md); }
.cs-btn--block { width: 100%; }

.cs-btn--icon { width: 44px; padding: 0; }
.cs-btn--icon.cs-btn--sm { width: 36px; }

/* Button spinner (shown while a form is in flight) */
.cs-btn .cs-spin { display: none; }
.cs-btn.is-loading { pointer-events: none; }
.cs-btn.is-loading .cs-spin { display: inline-block; }
.cs-btn.is-loading .cs-btn-label { opacity: .6; }

.cs-spin {
  width: 18px; height: 18px;
  border: 3px solid currentColor;
  border-inline-start-color: transparent;
  border-radius: 50%;
  animation: cs-rot .7s linear infinite;
}
@keyframes cs-rot { to { transform: rotate(360deg); } }

/* ----- Cards --------------------------------------------------------------------- */
.cs-card {
  background: var(--surface);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--sp-6);
  position: relative;
}
.cs-card--flat { box-shadow: none; }
.cs-card--pad-sm { padding: var(--sp-4); }
/* Dense variant (wallet balance / top-up): tighter padding + type so the pair
   stays about half its former height. */
.cs-card--compact { padding: var(--sp-5); }
.cs-card--compact .cs-stat-value { font-size: var(--fs-2xl); }
.cs-card--paper { background: var(--paper-soft); }
.cs-card--navy  { background: var(--navy); color: #fff; }
.cs-card--navy .cs-muted, .cs-card--navy .cs-faint { color: rgba(255,255,255,.75); }
.cs-card--tint  { background: var(--orange-tint); }

a.cs-card, .cs-card--tap {
  display: block; color: inherit; text-decoration: none; cursor: pointer;
  transition: transform var(--t-fast) var(--ease-out), box-shadow var(--t-fast) var(--ease-out);
}
a.cs-card:hover, .cs-card--tap:hover { transform: translate(calc(var(--px) * -0.5), -3px); box-shadow: calc(var(--px) * 2) calc(var(--py) * 2) 0 var(--shadow-ink); }
a.cs-card:active, .cs-card--tap:active { transform: translate(var(--px), var(--py)); box-shadow: 0 0 0 var(--shadow-ink); }

.cs-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-3); margin-bottom: var(--sp-4); }
.cs-card-title { font-size: var(--fs-lg); font-weight: 700; font-family: var(--font-display), 'Vazirmatn', sans-serif; }

/* Corner tape — small decorative brand sticker on hero cards */
.cs-tape {
  position: absolute;
  top: -12px;
  inset-inline-end: 22px;
  background: var(--orange);
  color: var(--on-accent);
  border: var(--bw) solid var(--ink);
  border-radius: 7px;
  padding: 2px 12px;
  font-size: var(--fs-xs);
  font-weight: 700;
  transform: rotate(3deg);
  box-shadow: 2px 2px 0 var(--shadow-ink);
}
html[dir='rtl'] .cs-tape { transform: rotate(-3deg); }

/* ----- Chips & badges --------------------------------------------------------------- */
.cs-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 11px;
  font-size: var(--fs-xs);
  font-weight: 700;
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-full);
  background: var(--surface);
  color: var(--ink);
  white-space: nowrap;
}
.cs-chip svg { width: 13px; height: 13px; }
.cs-chip--success { background: var(--success-tint); }
.cs-chip--warning { background: var(--warning-tint); }
.cs-chip--danger  { background: var(--danger-tint); }
.cs-chip--info    { background: var(--navy-tint); }
.cs-chip--accent  { background: var(--orange-tint); }
.cs-chip--navy    { background: var(--navy); color: #fff; border-color: var(--ink); }
.cs-chip--ghost   { border-color: var(--ink-15); background: transparent; color: var(--ink-70); }

.cs-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--ink-50); flex-shrink: 0; }
.cs-dot--on   { background: var(--success-bright); box-shadow: 0 0 0 3px var(--success-tint); }
.cs-dot--off  { background: var(--ink-50); }
.cs-dot--warn { background: var(--warning); box-shadow: 0 0 0 3px var(--warning-tint); }
.cs-dot--busy { background: var(--orange); animation: cs-pulse 1.1s ease-in-out infinite; }
@keyframes cs-pulse { 50% { opacity: .35; } }

/* ----- Stat blocks -------------------------------------------------------------------- */
.cs-stat { display: flex; flex-direction: column; gap: 2px; }
.cs-stat-label { font-size: var(--fs-sm); color: var(--ink-70); font-weight: 600; }
.cs-stat-value {
  font-family: var(--font-display), 'Vazirmatn', sans-serif;
  font-size: var(--fs-2xl); font-weight: 700; line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.cs-stat-value--xl { font-size: var(--fs-4xl); }
.cs-stat-hint { font-size: var(--fs-xs); color: var(--ink-50); }

/* ----- Forms ----------------------------------------------------------------------- */
.cs-field { display: flex; flex-direction: column; gap: var(--sp-2); }
.cs-label { font-weight: 650; font-size: var(--fs-sm); }
.cs-label .cs-req { color: var(--danger-bright); }
.cs-help { font-size: var(--fs-xs); color: var(--ink-50); }
.cs-error { font-size: var(--fs-sm); color: var(--danger-bright); font-weight: 600; }

.cs-input, .cs-select, .cs-textarea {
  width: 100%;
  min-height: 48px;
  padding: 0 var(--sp-4);
  background: var(--surface);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-sm);
  box-shadow: inset 2px 2px 0 var(--ink-08);
  transition: box-shadow var(--t-fast) ease, border-color var(--t-fast) ease;
}
.cs-textarea { min-height: 110px; padding-block: var(--sp-3); resize: vertical; }
.cs-input:focus, .cs-select:focus, .cs-textarea:focus {
  outline: 3px solid var(--navy-bright); outline-offset: 1px;
}
.cs-input[aria-invalid='true'], .cs-select[aria-invalid='true'] { border-color: var(--danger-bright); }
.cs-input:disabled, .cs-select:disabled { background: var(--surface-2); color: var(--ink-50); cursor: not-allowed; }

.cs-select {
  appearance: none;
  padding-inline-end: var(--sp-10);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%232A231F' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--sp-4) center;
  cursor: pointer;
}
html[dir='rtl'] .cs-select { background-position: left var(--sp-4) center; }

/* Input with a leading/trailing affix (currency, unit, icon-button) */
.cs-input-wrap { position: relative; display: flex; align-items: stretch; }
.cs-input-wrap .cs-input { flex: 1; }
.cs-affix {
  display: flex; align-items: center;
  padding-inline: var(--sp-4);
  border: var(--bw) solid var(--ink);
  background: var(--paper-soft);
  font-weight: 700; font-size: var(--fs-sm);
  white-space: nowrap;
}
.cs-affix:first-child { border-inline-end: 0; border-start-start-radius: var(--r-sm); border-end-start-radius: var(--r-sm); }
.cs-affix:last-child  { border-inline-start: 0; border-start-end-radius: var(--r-sm); border-end-end-radius: var(--r-sm); }
.cs-input-wrap .cs-input:not(:first-child) { border-start-start-radius: 0; border-end-start-radius: 0; }
.cs-input-wrap .cs-input:not(:last-child)  { border-start-end-radius: 0; border-end-end-radius: 0; }

/* Wallet top-up: the amount unit and the preset rows follow the checked method
   radio in pure CSS, so they stay in sync with the POSTed value without JS. */
.cs-topup-form [data-topup-unit],
.cs-topup-form [data-topup-method] { display: none; }
.cs-topup-form:has(input[name='method'][value='card']:checked)   [data-topup-unit='card'],
.cs-topup-form:has(input[name='method'][value='crypto']:checked) [data-topup-unit='crypto'] { display: inline; }
.cs-topup-form:has(input[name='method'][value='card']:checked)   [data-topup-method='card'],
.cs-topup-form:has(input[name='method'][value='crypto']:checked) [data-topup-method='crypto'] { display: flex; }

/* Checkbox / toggle */
.cs-check { display: flex; align-items: flex-start; gap: var(--sp-3); cursor: pointer; font-size: var(--fs-sm); }
.cs-check input {
  appearance: none;
  width: 24px; height: 24px; flex-shrink: 0;
  border: var(--bw) solid var(--ink);
  border-radius: 7px;
  background: var(--surface);
  box-shadow: 2px 2px 0 var(--shadow-ink);
  display: grid; place-content: center;
  transition: transform var(--t-fast) var(--ease-out), box-shadow var(--t-fast) var(--ease-out), background var(--t-fast) ease;
  cursor: pointer;
}
.cs-check input:checked { background: var(--orange); }
.cs-check input:checked::before {
  content: '';
  width: 12px; height: 12px;
  background: var(--on-accent);
  clip-path: polygon(14% 44%, 0 62%, 40% 100%, 100% 16%, 84% 2%, 39% 66%);
}
.cs-check input:active { transform: translate(2px, 2px); box-shadow: 0 0 0 var(--shadow-ink); }

.cs-switch { display: inline-flex; align-items: center; gap: var(--sp-3); cursor: pointer; }
.cs-switch input {
  appearance: none;
  width: 52px; height: 30px; flex-shrink: 0;
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-full);
  background: var(--surface-2);
  position: relative;
  box-shadow: inset 2px 2px 0 var(--ink-08);
  transition: background var(--t-med) ease;
  cursor: pointer;
}
.cs-switch input::before {
  content: '';
  position: absolute;
  top: 3px; inset-inline-start: 3px;
  width: 20px; height: 20px;
  border-radius: 50%;
  background: var(--surface);
  border: var(--bw) solid var(--ink);
  transition: inset-inline-start var(--t-med) var(--ease-snap);
}
.cs-switch input:checked { background: var(--success); }
.cs-switch input:checked::before { inset-inline-start: 25px; }

/* Segmented control (language, payment method) */
.cs-seg {
  display: inline-flex;
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-sm);
  background: var(--surface);
  box-shadow: var(--shadow);
  padding: 3px;
  gap: 3px;
}
.cs-seg > form { display: contents; } /* form-wrapped buttons join the row */
.cs-seg > :not(form),
.cs-seg > form > button {
  border: 0; border-radius: 8px;
  padding: 7px 16px;
  min-height: 38px;
  font-weight: 650; font-size: var(--fs-sm);
  color: var(--ink-70);
  background: transparent;
  display: inline-flex; align-items: center; gap: var(--sp-2);
  text-decoration: none;
  transition: background var(--t-fast) ease, color var(--t-fast) ease;
}
.cs-seg > :not(form):hover,
.cs-seg > form > button:hover { color: var(--ink); background: var(--surface-2); }
.cs-seg .is-active { background: var(--ink); color: var(--paper); }
.cs-seg .is-active:hover { background: var(--ink); color: var(--paper); }

/* Radio-backed segment (top-up method): the checked state is form state, not
   Alpine state, so the posted value survives even when JS never runs. */
.cs-seg label {
  position: relative;
  cursor: pointer;
  flex: 1 1 0;
  justify-content: center;
  text-align: center;
  line-height: 1.25;
}
.cs-seg label input[type='radio'] {
  position: absolute; inset: 0;
  opacity: 0; margin: 0; cursor: pointer;
}
.cs-seg label:has(input:checked) { background: var(--ink); color: var(--paper); }
.cs-seg label:has(input:focus-visible) { outline: 3px solid var(--navy-bright); outline-offset: 2px; }
/* Icons inside segment options: text-sized, never free-growing (an unsized
   inline SVG ballooned the wallet's payment-method tiles to card height). */
.cs-seg svg { width: 18px; height: 18px; flex-shrink: 0; }

/* Radio-card group (buy wizard choices) */
.cs-pick { position: relative; display: block; cursor: pointer; height: 100%; }
.cs-pick input { position: absolute; opacity: 0; pointer-events: none; }
.cs-pick-body {
  height: 100%;
  background: var(--surface);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-md);
  box-shadow: var(--shadow);
  padding: var(--sp-4);
  display: flex; flex-direction: column; gap: var(--sp-2);
  transition: transform var(--t-fast) var(--ease-out), box-shadow var(--t-fast) var(--ease-out), background var(--t-fast) ease;
}
.cs-pick:hover .cs-pick-body { transform: translate(calc(var(--px) * -0.5), -2px); box-shadow: var(--shadow-lg); }
.cs-pick input:checked + .cs-pick-body {
  background: var(--navy-tint);
  box-shadow: var(--shadow), inset 0 0 0 2px var(--navy-bright);
}
.cs-pick input:focus-visible + .cs-pick-body { outline: 3px solid var(--navy-bright); outline-offset: 2px; }
.cs-pick input:checked + .cs-pick-body::after {
  content: '';
  position: absolute;
  top: 10px; inset-inline-end: 10px;
  width: 22px; height: 22px;
  border-radius: 50%;
  border: var(--bw) solid var(--ink);
  background: var(--orange);
  clip-path: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232A231F' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  background-size: 12px;
  background-repeat: no-repeat;
  background-position: center;
}

/* ----- Tables (ledger, lists) ------------------------------------------------------ */
.cs-table-wrap {
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  overflow-x: auto;
}
.cs-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); min-width: 560px; }
.cs-table th, .cs-table td { padding: var(--sp-3) var(--sp-5); text-align: start; }
.cs-table thead th {
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-70);
  border-bottom: var(--bw) solid var(--ink);
  background: var(--paper-soft);
  white-space: nowrap;
}
html[lang='fa'] .cs-table thead th { letter-spacing: .02em; }
.cs-table tbody tr { border-bottom: 1px solid var(--ink-15); }
.cs-table tbody tr:last-child { border-bottom: 0; }
.cs-table tbody tr:hover { background: var(--surface-2); }
/* Striped variant — the pricing rate card, matching the striped table the bot
   sends. Sits before :hover above in the cascade so hovering still highlights. */
.cs-table--striped tbody tr:nth-child(even) { background: var(--paper-soft); }
.cs-table--striped tbody tr:hover { background: var(--surface-2); }
/* Row heading (the provider name column) — a th inside tbody. */
.cs-table tbody th { padding: var(--sp-3) var(--sp-5); text-align: start; font-weight: 700; white-space: nowrap; }
.cs-amount--in  { color: var(--success-bright); font-weight: 700; }
.cs-amount--out { color: var(--ink); font-weight: 600; }

/* ----- Traffic / progress bars ----------------------------------------------------- */
.cs-bar {
  --bar-fill: var(--navy);
  height: 14px;
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-full);
  background: var(--surface);
  overflow: hidden;
  box-shadow: inset 2px 2px 0 var(--ink-08);
}
.cs-bar > i {
  display: block; height: 100%;
  background: var(--bar-fill);
  border-radius: inherit;
  transform-origin: 0 50%;
  transition: width .6s var(--ease-out);
}
html[dir='rtl'] .cs-bar > i { transform-origin: 100% 50%; }
.cs-bar--warn { --bar-fill: var(--warning); }
.cs-bar--danger { --bar-fill: var(--danger); }
.cs-bar--accent { --bar-fill: var(--orange); }
.cs-bar--lg { height: 20px; }

/* ----- Copyable value -------------------------------------------------------------- */
.cs-copy {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  max-width: 100%;
  padding: 5px 12px;
  background: var(--surface-2);
  border: var(--bw) solid var(--ink);
  border-radius: 9px;
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  direction: ltr;
  unicode-bidi: isolate;
  transition: background var(--t-fast) ease, transform var(--t-fast) var(--ease-out);
  color: var(--ink);
}
.cs-copy span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cs-copy svg { width: 15px; height: 15px; flex-shrink: 0; color: var(--ink-70); }
button.cs-copy:hover { background: var(--navy-tint); }
button.cs-copy:active { transform: translate(1px, 1px); }
.cs-copy.is-copied { background: var(--success-tint); }
.cs-copy.is-copied svg { color: var(--success-bright); }

.cs-secret { letter-spacing: .18em; }

/* ----- Dropdown menu ----------------------------------------------------------------- */
.cs-drop { position: relative; }
.cs-menu {
  position: absolute;
  top: calc(100% + 8px);
  inset-inline-end: 0;
  min-width: 230px;
  background: var(--surface);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  padding: var(--sp-2);
  z-index: var(--z-drop);
  display: flex; flex-direction: column; gap: 2px;
}
.cs-menu-item {
  display: flex; align-items: center; gap: var(--sp-3);
  width: 100%;
  min-height: 42px;
  padding: var(--sp-2) var(--sp-3);
  border-radius: 9px;
  font-weight: 550; font-size: var(--fs-sm);
  color: var(--ink);
  text-decoration: none;
  text-align: start;
  transition: background var(--t-fast) ease;
}
.cs-menu-item svg { width: 18px; height: 18px; color: var(--ink-70); flex-shrink: 0; }
.cs-menu-item:hover { background: var(--navy-tint); color: var(--ink); }
.cs-menu-item.is-danger { color: var(--danger-bright); }
.cs-menu-item.is-danger svg { color: var(--danger-bright); }
.cs-menu-item.is-danger:hover { background: var(--danger-tint); }
.cs-menu-sep { border: 0; border-top: 1px solid var(--ink-15); margin: var(--sp-1) var(--sp-2); }
.cs-menu-head { font-size: var(--fs-xs); font-weight: 700; color: var(--ink-50); padding: var(--sp-2) var(--sp-3) 2px; text-transform: uppercase; letter-spacing: .1em; }
html[lang='fa'] .cs-menu-head { letter-spacing: .02em; }

/* ----- Modal (native <dialog>, rendered in the top layer) ------------------------------- */
/* The top layer ignores ancestor transforms/overflow, so a modal opened from
   inside an animated card can never be trapped or clipped by it. */
dialog.cs-modal {
  width: min(560px, calc(100vw - var(--sp-8)));
  background: var(--surface);
  color: inherit;
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-xl);
  box-shadow: 8px 8px 0 var(--shadow-ink);
  padding: 0;                     /* padding lives on .cs-modal-inner (backdrop-click detection) */
  max-height: calc(100dvh - var(--sp-10));
  overflow-y: auto;
  margin: auto;                   /* centred by the dialog layout itself */
}
html[dir='rtl'] dialog.cs-modal { box-shadow: -8px 8px 0 var(--shadow-ink); }
dialog.cs-modal::backdrop { background: rgba(42, 35, 31, .45); }
dialog.cs-modal[open] { animation: cs-modal-in .28s var(--ease-snap); }
@keyframes cs-modal-in {
  from { opacity: 0; transform: translateY(18px) scale(.96); }
}
dialog.cs-modal[open]::backdrop { animation: cs-backdrop-in .28s ease; }
@keyframes cs-backdrop-in { from { opacity: 0; } }
/* Keep the page from scrolling underneath an open modal. */
body:has(dialog.cs-modal[open]) { overflow: hidden; }
.cs-modal-inner { padding: var(--sp-8); }
.cs-modal--wide { width: min(760px, calc(100vw - var(--sp-8))); }
.cs-modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-4); margin-bottom: var(--sp-4); }
.cs-modal-title { font-size: var(--fs-xl); }
.cs-modal-x {
  width: 40px; height: 40px; flex-shrink: 0;
  display: grid; place-items: center;
  border: var(--bw) solid var(--ink);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: 2px 2px 0 var(--shadow-ink);
  transition: transform var(--t-fast) var(--ease-out), box-shadow var(--t-fast) var(--ease-out), background var(--t-fast) ease;
}
.cs-modal-x:hover { background: var(--danger-tint); }
.cs-modal-x:active { transform: translate(2px, 2px); box-shadow: 0 0 0 var(--shadow-ink); }
.cs-modal-x svg { width: 17px; height: 17px; }
.cs-modal-foot { display: flex; justify-content: flex-end; gap: var(--sp-3); margin-top: var(--sp-6); flex-wrap: wrap; }

/* ----- Toasts ---------------------------------------------------------------------------- */
.cs-toasts {
  position: fixed;
  bottom: var(--sp-5);
  inset-inline-end: var(--sp-5);
  z-index: var(--z-toast);
  display: flex; flex-direction: column; gap: var(--sp-3);
  width: min(420px, calc(100vw - var(--sp-8)));
  pointer-events: none;
}
.cs-toast {
  pointer-events: auto;
  display: flex; align-items: flex-start; gap: var(--sp-3);
  background: var(--surface);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  padding: var(--sp-4);
}
.cs-toast-icon {
  width: 34px; height: 34px; flex-shrink: 0;
  display: grid; place-items: center;
  border: var(--bw) solid var(--ink);
  border-radius: 10px;
}
.cs-toast-icon svg { width: 17px; height: 17px; }
.cs-toast--success .cs-toast-icon { background: var(--success-tint); color: var(--success-bright); }
.cs-toast--danger  .cs-toast-icon { background: var(--danger-tint);  color: var(--danger-bright); }
.cs-toast--info    .cs-toast-icon { background: var(--navy-tint);    color: var(--navy-bright); }
.cs-toast--warning .cs-toast-icon { background: var(--warning-tint); color: var(--warning-bright); }
.cs-toast b { display: block; font-size: var(--fs-md); }
.cs-toast p { font-size: var(--fs-sm); color: var(--ink-70); margin-top: 2px; overflow-wrap: anywhere; }
.cs-toast .cs-copy { margin-top: var(--sp-2); }
.cs-toast-x { margin-inline-start: auto; color: var(--ink-50); flex-shrink: 0; padding: 4px; border-radius: 6px; }
.cs-toast-x:hover { color: var(--ink); background: var(--ink-08); }
.cs-toast-x svg { width: 15px; height: 15px; }

/* ----- Alerts / banners --------------------------------------------------------------------- */
.cs-alert {
  display: flex; gap: var(--sp-3); align-items: flex-start;
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-md);
  padding: var(--sp-4) var(--sp-5);
  font-size: var(--fs-sm);
  background: var(--surface);
}
.cs-alert svg { width: 20px; height: 20px; flex-shrink: 0; margin-top: 1px; }
.cs-alert--info    { background: var(--navy-tint); }    .cs-alert--info svg { color: var(--navy-bright); }
.cs-alert--warning { background: var(--warning-tint); } .cs-alert--warning svg { color: var(--warning-bright); }
.cs-alert--danger  { background: var(--danger-tint); }  .cs-alert--danger svg { color: var(--danger-bright); }
.cs-alert--success { background: var(--success-tint); } .cs-alert--success svg { color: var(--success-bright); }
.cs-alert b { display: block; }

/* ----- Empty states & skeletons --------------------------------------------------------------- */
.cs-empty {
  border: var(--bw) dashed var(--ink-50);
  border-radius: var(--r-lg);
  padding: var(--sp-12) var(--sp-6);
  text-align: center;
  color: var(--ink-70);
  background: repeating-linear-gradient(-45deg, transparent 0 14px, var(--ink-08) 14px 15px);
}
.cs-empty svg { width: 46px; height: 46px; margin: 0 auto var(--sp-4); color: var(--ink-50); }
.cs-empty h3 { color: var(--ink); margin-bottom: var(--sp-2); }
.cs-empty p { max-width: 44ch; margin: 0 auto var(--sp-5); }

.cs-skel {
  border-radius: 8px;
  background: linear-gradient(90deg, var(--ink-08) 25%, var(--ink-15) 40%, var(--ink-08) 55%);
  background-size: 300% 100%;
  animation: cs-shimmer 1.3s ease-in-out infinite;
  min-height: 1em;
}
@keyframes cs-shimmer { to { background-position: -200% 0; } }

/* ----- Wizard steps ------------------------------------------------------------------------------ */
/* Pills are BUTTONS: a completed pill is clickable and jumps straight back to
   its step. Numbers come from a CSS counter over the visible pills, so the
   optional Period pill renumbers the row automatically when it appears. */
.cs-steps { display: flex; gap: var(--sp-2); flex-wrap: wrap; counter-reset: cs-step; }
.cs-step {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: 7px 14px;
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-full);
  font-size: var(--fs-sm); font-weight: 650;
  background: var(--surface);
  color: var(--ink-50);
  cursor: default;
}
.cs-step::before {
  counter-increment: cs-step;
  content: counter(cs-step);
  width: 22px; height: 22px;
  display: grid; place-items: center;
  border-radius: 50%;
  border: var(--bw) solid currentColor;
  font-style: normal; font-size: var(--fs-xs); font-weight: 700;
}
/* The wizard's top controls carry the brand orange as their hard shadow. */
.cs-step.is-active { background: var(--ink); color: var(--paper); box-shadow: var(--px) var(--py) 0 var(--orange); }
.cs-step.is-done { color: var(--ink); background: var(--success-tint); }
.cs-step.is-done::before { content: '✓'; background: var(--success); border-color: var(--success); color: #fff; }
button.cs-step.is-done {
  cursor: pointer;
  transition: transform var(--t-fast) var(--ease-out), box-shadow var(--t-fast) var(--ease-out);
}
button.cs-step.is-done:hover { transform: translate(calc(var(--px) * -0.5), -2px); box-shadow: var(--px) var(--py) 0 var(--orange); }
button.cs-step.is-done:active { transform: translate(1px, 1px); box-shadow: none; }
[data-wiz-back] { box-shadow: var(--px) var(--py) 0 var(--orange); }
[data-wiz-back]:hover { box-shadow: calc(var(--px) * 1.5) calc(var(--py) * 1.5) 0 var(--orange); }

/* ----- Server card (signature component) ------------------------------------------------------------ */
.cs-srv { display: flex; flex-direction: column; gap: var(--sp-4); }
.cs-srv-top { display: flex; align-items: flex-start; gap: var(--sp-3); }
.cs-srv-name {
  font-family: var(--font-display), 'Vazirmatn', sans-serif;
  font-weight: 700; font-size: var(--fs-lg);
  overflow-wrap: anywhere;
}
.cs-srv-plate {
  margin-inline-start: auto;
  flex-shrink: 0;
  font-size: var(--fs-xs); font-weight: 700;
  padding: 3px 10px;
  border: var(--bw) solid var(--ink);
  border-radius: 7px;
  background: var(--paper-soft);
  transform: rotate(1.5deg);
}
html[dir='rtl'] .cs-srv-plate { transform: rotate(-1.5deg); }
.cs-srv-specs {
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4);
  font-size: var(--fs-sm); color: var(--ink-70);
}
.cs-srv-specs > span { display: inline-flex; align-items: center; gap: 6px; }
.cs-srv-specs svg { width: 15px; height: 15px; color: var(--ink-50); }
.cs-srv-foot {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--ink-15);
}

/* Spec strip on the server detail page */
.cs-specs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.cs-spec {
  padding: var(--sp-4) var(--sp-5);
  border-inline-end: 1px solid var(--ink-15);
  border-bottom: 1px solid var(--ink-15);
  min-width: 0;
}
.cs-spec dt { font-size: var(--fs-xs); font-weight: 700; color: var(--ink-50); text-transform: uppercase; letter-spacing: .08em; margin-bottom: 4px; }
html[lang='fa'] .cs-spec dt { letter-spacing: .02em; }
.cs-spec dd { font-weight: 650; overflow-wrap: anywhere; }

/* Management action tiles */
.cs-action-tile {
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-2);
  width: 100%; height: 100%;
  text-align: start;
  background: var(--surface);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-md);
  box-shadow: var(--shadow);
  padding: var(--sp-4);
  color: var(--ink);
  text-decoration: none;
  transition: transform var(--t-fast) var(--ease-out), box-shadow var(--t-fast) var(--ease-out), background var(--t-fast) ease;
}
.cs-action-tile svg { width: 21px; height: 21px; color: var(--navy-bright); }
.cs-action-tile b { font-size: var(--fs-md); }
.cs-action-tile span { font-size: var(--fs-xs); color: var(--ink-50); }
.cs-action-tile:hover { transform: translate(calc(var(--px) * -0.5), -2px); box-shadow: var(--shadow-lg); background: var(--navy-tint); }
.cs-action-tile:active { transform: translate(var(--px), var(--py)); box-shadow: 0 0 0 var(--shadow-ink); }
.cs-action-tile.is-danger svg { color: var(--danger-bright); }
.cs-action-tile.is-danger:hover { background: var(--danger-tint); }

/* ----- Busy overlay (provisioning / slow forms) ------------------------------------------------------- */
.cs-busy {
  position: fixed; inset: 0;
  z-index: var(--z-busy);
  background: rgba(216, 225, 231, .93);
  display: grid; place-items: center;
  text-align: center;
  padding: var(--sp-6);
}
.cs-busy-box { max-width: 460px; }
.cs-busy-title { font-size: var(--fs-2xl); margin-top: var(--sp-6); }
.cs-busy-sub { color: var(--ink-70); margin-top: var(--sp-2); }
.cs-busy-art { width: 132px; height: 132px; margin: 0 auto; position: relative; }
.cs-busy-art .cs-gear {
  position: absolute; inset: 0; margin: auto;
  width: 108px; height: 108px;
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  display: grid; place-items: center;
}
.cs-busy-art .cs-gear svg { width: 52px; height: 52px; color: var(--navy-bright); }
.cs-busy-art .cs-orbit {
  position: absolute; top: -6px; inset-inline-end: -10px;
  width: 36px; height: 36px;
  border: var(--bw) solid var(--ink);
  border-radius: 50%;
  background: var(--orange);
  box-shadow: 2px 2px 0 var(--shadow-ink);
}

/* Confetti pieces (spawned by JS on success) */
.cs-confetti {
  position: fixed;
  width: 12px; height: 12px;
  border: 2px solid var(--ink);
  z-index: var(--z-busy);
  pointer-events: none;
  top: 0; left: 0;
}

/* ----- In-page navigation loader (spa.js) ---------------------------------------------------------------
   The busy overlay's tactile art, miniaturised: a bordered chip with the cloud
   mark and an orange dot orbiting it. Shown only when a navigation takes
   longer than ~180ms; the outgoing page dims underneath it. */
.cs-page.is-loading {
  opacity: .35;
  transition: opacity .12s ease;
  pointer-events: none;
}
.cs-page.is-entering { opacity: 0; }
.cs-page {
  transition: opacity .18s ease;
  outline: none; /* programmatic focus target after each swap */
}
.cs-nav-loader {
  position: fixed;
  top: 34vh; left: 50%;
  transform: translate(-50%, 10px) scale(.94);
  z-index: calc(var(--z-modal) - 10);
  display: flex; flex-direction: column; align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-5) var(--sp-8);
  background: var(--surface);
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-lg);
  box-shadow: 5px 5px 0 var(--shadow-ink);
  font-size: var(--fs-sm);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .18s ease, transform .18s ease, visibility 0s .18s;
}
.cs-nav-loader.is-on {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0) scale(1);
  transition: opacity .18s ease, transform .18s ease;
}
.cs-nav-loader-art { position: relative; width: 54px; height: 54px; }
.cs-nav-loader-core {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  border: var(--bw) solid var(--ink);
  border-radius: var(--r);
  background: var(--paper-soft);
}
.cs-nav-loader-orbit {
  position: absolute; inset: -11px;
  animation: cs-orbit 1.05s linear infinite;
}
.cs-nav-loader-orbit i {
  position: absolute; top: -2px; left: 50%;
  width: 14px; height: 14px; margin-left: -7px;
  border: var(--bw) solid var(--ink);
  border-radius: 50%;
  background: var(--orange);
  box-shadow: 2px 2px 0 var(--shadow-ink);
}
@keyframes cs-orbit { to { transform: rotate(1turn); } }
@media (prefers-reduced-motion: reduce) {
  .cs-page.is-loading, .cs-page { transition: none; }
  .cs-nav-loader { transition: none; transform: translate(-50%, 0); }
  .cs-nav-loader-orbit { animation: none; }
}

/* ----- Auth (guest) layout ----------------------------------------------------------------------------- */
/* Fully mirrored in RTL: the grid flows with the document direction, so in fa
   the brand pane sits on the RIGHT and the form pane on the left. */
.cs-auth {
  min-height: 100dvh;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
}
.cs-auth-brand {
  position: relative;
  padding: var(--sp-10) var(--sp-12);
  display: flex; flex-direction: column;
  border-inline-end: var(--bw) solid var(--ink);
  overflow: hidden;
  background:
    radial-gradient(circle at 12% 18%, var(--navy-tint) 0 140px, transparent 141px),
    radial-gradient(circle at 88% 82%, var(--orange-tint) 0 170px, transparent 171px),
    var(--paper);
}
.cs-auth-brand h1 { font-size: clamp(2.2rem, 4.2vw, var(--fs-5xl)); margin-top: var(--sp-10); max-width: 13ch; }
.cs-auth-brand .cs-page-sub { font-size: var(--fs-lg); }
.cs-auth-points { margin-top: auto; display: flex; flex-direction: column; gap: var(--sp-3); padding-top: var(--sp-10); }
.cs-auth-point { display: flex; align-items: center; gap: var(--sp-3); font-weight: 600; }
.cs-auth-point i {
  width: 34px; height: 34px; flex-shrink: 0;
  display: grid; place-items: center;
  border: var(--bw) solid var(--ink); border-radius: 10px;
  background: var(--surface);
  box-shadow: 2px 2px 0 var(--shadow-ink);
}
.cs-auth-point svg { width: 17px; height: 17px; color: var(--navy-bright); }
.cs-auth-pane {
  display: grid; place-items: center;
  padding: var(--sp-8) var(--sp-6);
  background: var(--paper);
}
.cs-auth-card { width: min(430px, 100%); }

/* Six-box code input (Telegram link) */
.cs-code { display: flex; gap: var(--sp-2); direction: ltr; justify-content: center; }
.cs-code input {
  width: 52px; height: 62px;
  text-align: center;
  font-family: var(--font-mono);
  font-size: var(--fs-2xl); font-weight: 700;
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-sm);
  background: var(--surface);
  box-shadow: inset 2px 2px 0 var(--ink-08);
}
.cs-code input:focus { outline: 3px solid var(--navy-bright); outline-offset: 1px; }

/* ----- Pagination ---------------------------------------------------------------------------------------- */
.cs-pager { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); margin-top: var(--sp-4); flex-wrap: wrap; }
.cs-pager nav { display: flex; gap: var(--sp-2); }

/* ----- kbd ------------------------------------------------------------------------------------------------ */
.cs-kbd {
  font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: 700;
  padding: 2px 7px;
  border: var(--bw) solid var(--ink);
  border-bottom-width: 3px;
  border-radius: 6px;
  background: var(--surface);
}

/* ----- Buy wizard specifics --------------------------------------------------------------------------------- */
.cs-buy { display: grid; grid-template-columns: minmax(0, 1fr) 330px; gap: var(--sp-6); align-items: start; }
.cs-buy-summary { position: sticky; top: calc(var(--topbar-h) + var(--sp-5)); }
.cs-buy-line { display: flex; justify-content: space-between; gap: var(--sp-3); font-size: var(--fs-sm); padding-block: 6px; }
.cs-buy-line dt { color: var(--ink-70); }
.cs-buy-line dd { font-weight: 650; text-align: end; overflow-wrap: anywhere; }
.cs-buy-total { border-top: var(--bw) solid var(--ink); margin-top: var(--sp-3); padding-top: var(--sp-3); }
.cs-buy-total .cs-buy-line dd { font-size: var(--fs-lg); font-weight: 700; }

.cs-plan-price { display: flex; align-items: baseline; gap: 6px; margin-top: auto; padding-top: var(--sp-2); }
.cs-plan-price b { font-family: var(--font-display), 'Vazirmatn', sans-serif; font-size: var(--fs-xl); }
.cs-plan-specrow { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-3); font-size: var(--fs-sm); color: var(--ink-70); }

.cs-qty { display: inline-flex; align-items: stretch; border: var(--bw) solid var(--ink); border-radius: var(--r-sm); overflow: hidden; background: var(--surface); box-shadow: var(--shadow); }
.cs-qty button { width: 48px; display: grid; place-items: center; font-size: var(--fs-xl); font-weight: 700; background: var(--paper-soft); transition: background var(--t-fast) ease; }
.cs-qty button:hover { background: var(--navy-tint); }
.cs-qty button:active { background: var(--navy); color: #fff; }
.cs-qty input { width: 72px; border: 0; text-align: center; font-weight: 700; font-size: var(--fs-lg); -moz-appearance: textfield; }
.cs-qty input::-webkit-outer-spin-button, .cs-qty input::-webkit-inner-spin-button { -webkit-appearance: none; }
.cs-qty input:focus { outline: none; background: var(--navy-tint); }

/* Credentials reveal card (post-purchase / deploy) */
.cs-cred {
  border: var(--bw) solid var(--ink);
  border-radius: var(--r-md);
  background: var(--paper-soft);
  padding: var(--sp-4);
  display: flex; flex-direction: column; gap: var(--sp-2);
}
.cs-cred-row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap; }
.cs-cred-row > span:first-child { font-size: var(--fs-sm); color: var(--ink-70); font-weight: 600; }

/* ----- Ledger rows (dashboard activity) ------------------------------------------------------------------------ */
.cs-ledger { display: flex; flex-direction: column; }
.cs-ledger-row {
  display: flex; align-items: center; gap: var(--sp-4);
  padding: var(--sp-3) var(--sp-2);
  border-bottom: 1px solid var(--ink-15);
}
.cs-ledger-row:last-child { border-bottom: 0; }
.cs-ledger-icon {
  width: 40px; height: 40px; flex-shrink: 0;
  display: grid; place-items: center;
  border: var(--bw) solid var(--ink);
  border-radius: 12px;
  background: var(--surface-2);
}
.cs-ledger-icon svg { width: 19px; height: 19px; }
.cs-ledger-icon.is-in  { background: var(--success-tint); color: var(--success-bright); }
.cs-ledger-icon.is-out { background: var(--paper-soft);   color: var(--ink-70); }

/* ----- Language + theme toggles in guest pages ------------------------------------------------------------------- */
/* Mirrors with the document: top inline-end corner in both directions. */
.cs-guest-lang {
  position: absolute; top: var(--sp-5); inset-inline-end: var(--sp-5); z-index: 5;
  display: flex; align-items: center; gap: var(--sp-3);
}

/* ----- Footer ----------------------------------------------------------------------------------------------------- */
.cs-foot {
  margin-top: auto;
  padding: var(--sp-5) var(--sp-8);
  border-top: var(--bw) solid var(--ink);
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  font-size: var(--fs-xs); color: var(--ink-50);
  flex-wrap: wrap;
}

/* ----- Utility ------------------------------------------------------------------------------------------------------ */
.u-hide { display: none !important; }
.u-mt-2 { margin-top: var(--sp-2); } .u-mt-4 { margin-top: var(--sp-4); } .u-mt-6 { margin-top: var(--sp-6); } .u-mt-8 { margin-top: var(--sp-8); }
.u-mb-2 { margin-bottom: var(--sp-2); } .u-mb-4 { margin-bottom: var(--sp-4); } .u-mb-6 { margin-bottom: var(--sp-6); }
.u-w-full { width: 100%; }
/* Announced by screen readers, invisible on screen (async catalogue status). */
.u-sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

/* ----- GSAP entrance hooks: pre-hide only when JS is running -------------------------------------------------------- */
/* Failsafe: if app.js never gets to reveal these (blocked script, extension,
   an earlier throw), a pure-CSS animation forces them visible after 1.4s —
   content can never stay hidden forever. app.js cancels this animation when
   it takes over, so scroll-triggered entrances keep full control. */
html.js [data-animate] {
  opacity: 0;
  animation: cs-reveal-failsafe .01ms linear 1.4s forwards;
}
html.js [data-animate='none'] { opacity: 1; animation: none; }
@keyframes cs-reveal-failsafe { to { opacity: 1; } }

/* ----- Motion pack -------------------------------------------------------------------------------------------------------
   Micro-interactions layered on the tactile system. Everything here is
   decorative, CSS-only, and neutralized by the reduced-motion block below. */

/* Cross-page fade on same-origin navigations (progressive: browsers without
   view transitions simply navigate). */
@view-transition { navigation: auto; }

/* Dropdown menus pop from their anchor edge. */
.cs-menu { animation: cs-menu-in .16s var(--ease-out); transform-origin: top center; }
@keyframes cs-menu-in { from { opacity: 0; transform: translateY(-7px) scale(.97); } }

/* Sidebar nav: the icon leans toward the page you are about to open. */
.cs-nav-item svg { transition: transform var(--t-fast) var(--ease-out); }
.cs-nav-item:hover svg { transform: translateX(3px); }
html[dir='rtl'] .cs-nav-item:hover svg { transform: translateX(-3px); }

/* Management tiles: the glyph springs when the tile is considered. */
.cs-action-tile svg { transition: transform var(--t-med) var(--ease-snap); }
.cs-action-tile:hover svg { transform: scale(1.15) rotate(-5deg); }

/* Copy chip: a small pop confirms the copy beyond the color change. */
.cs-copy.is-copied { animation: cs-pop .3s var(--ease-snap); }
@keyframes cs-pop { 50% { transform: scale(1.07); } }

/* Theme toggle: sun and moon trade places with a quarter-turn. */
[data-theme-toggle] .cs-theme-sun,
[data-theme-toggle] .cs-theme-moon { animation: cs-theme-swap .35s var(--ease-snap); }
@keyframes cs-theme-swap {
  from { transform: rotate(-90deg) scale(.4); opacity: 0; }
}

/* Logo: a friendly tilt on hover — one playful brand moment. */
.cs-logo img { transition: transform var(--t-med) var(--ease-snap); }
.cs-logo:hover img { transform: rotate(-7deg) scale(1.06); }

/* Wallet pin: a light sheen sweeps across on hover. */
.cs-wallet-pin { overflow: hidden; position: relative; }
.cs-wallet-pin::before {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 42%, rgba(255, 255, 255, .16) 50%, transparent 58%);
  transform: translateX(-130%);
  pointer-events: none;
}
.cs-wallet-pin:hover::before { transition: transform .7s ease; transform: translateX(130%); }

/* Empty states: the illustration floats gently. */
.cs-empty svg { animation: cs-float 3.4s ease-in-out infinite; }
@keyframes cs-float { 50% { transform: translateY(-7px); } }

/* Segmented controls: the landing pill settles with a spring. */
.cs-seg .is-active,
.cs-seg label:has(input:checked) { animation: cs-seg-pop .25s var(--ease-snap); }
@keyframes cs-seg-pop { 50% { transform: scale(1.05); } }

/* Live-poll updates: a brief brightness flash marks a changed value. */
.cs-live-flash { animation: cs-live-flash .9s var(--ease-out); }
@keyframes cs-live-flash {
  0% { filter: brightness(1.6); }
  100% { filter: brightness(1); }
}

/* ----- Hold-to-confirm (destructive finals) --------------------------------------------------------------
   The button must be HELD for 2s: an orange progress ring sweeps around the
   button's own border while `--hold` runs 0→1 (driven by app.js), and the form
   submits only when the sweep completes. A plain click nudges the hint. */
.cs-hold { position: relative; }
.cs-hold::after {
  content: '';
  position: absolute;
  inset: calc(-1 * var(--bw) - 5px);
  border-radius: calc(var(--r-sm) + 6px);
  padding: 3px;
  background: conic-gradient(var(--orange) calc(var(--hold, 0) * 360deg), transparent 0);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask-composite: exclude;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t-fast) ease;
}
.cs-hold.is-holding::after { opacity: 1; }
.cs-hold.is-holding { transform: translate(1px, 1px); }
/* The "you must hold" nudge on a plain click. */
.cs-hold.is-nudge { animation: cs-hold-nudge .35s var(--ease-out); }
@keyframes cs-hold-nudge { 25% { transform: translateX(-3px); } 75% { transform: translateX(3px); } }

/* ----- Danger warning: the card trembles while a delete control is hovered -------------------------------
   Driven by JS (`.cs-warn` with a short leave-debounce), NOT by :hover — a
   hover-driven transform moves the button under the cursor, un-hovers it, and
   the loop flickers violently at the button's edge/shadow. Pointer-only: on
   touch there is no hover, and the tap-time shake was displacing the button
   out from under the finger (taps failing to register). */
@media (hover: hover) and (pointer: fine) {
  .cs-warn { animation: cs-warn-shake .42s linear infinite; }
}
@keyframes cs-warn-shake {
  0%, 100% { transform: translate(0, 0) rotate(0); }
  25% { transform: translate(0.5px, -0.3px) rotate(0.08deg); }
  50% { transform: translate(-0.4px, 0.4px) rotate(-0.08deg); }
  75% { transform: translate(0.4px, 0.3px) rotate(0.06deg); }
}

/* ----- Region flags: a gentle, continuous wave ------------------------------------------------------------ */
.cs-flag {
  display: inline-block;
  font-size: 1.6rem;
  line-height: 1;
  transform-origin: 30% 80%;
  animation: cs-flag-wave 2.8s ease-in-out infinite;
}
/* Neighbouring flags drift out of phase so a grid doesn't wave in lockstep. */
.cs-pick:nth-child(2n) .cs-flag { animation-delay: -.9s; }
.cs-pick:nth-child(3n) .cs-flag { animation-delay: -1.7s; }
@keyframes cs-flag-wave {
  0%, 100% { transform: rotate(-3deg) skewY(0.5deg); }
  50% { transform: rotate(3.5deg) skewY(-1deg); }
}

/* ----- OS pick cards (buy wizard + reinstall modal) ------------------------------------------------------- */
.cs-grid--os { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--sp-3); }
.cs-pick--os .cs-pick-body {
  flex-direction: row; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
}
.cs-pick--os b { font-size: var(--fs-sm); line-height: 1.3; overflow-wrap: anywhere; }
.cs-os-logo { width: 26px; height: 26px; flex-shrink: 0; color: var(--ink); }
.cs-pick--os input:checked + .cs-pick-body .cs-os-logo { color: var(--navy-bright); }
/* The checked tick would overlap the row layout's end — tuck it tighter. */
.cs-pick--os input:checked + .cs-pick-body::after { width: 18px; height: 18px; top: -7px; inset-inline-end: -7px; background-size: 10px; }

/* A pick tile that navigates instead of selecting (the buy wizard's "Server
   finder" card, which opens its own page): same card, no radio, no link chrome.
   Logical properties only, so it needs no html[dir='rtl'] twin. */
.cs-pick--link { text-decoration: none; color: inherit; }

/* Heading above one billing set on the by-location plan step ("Hourly" /
   "Monthly"), mirroring the bot's two heading buttons. */
.cs-plan-set + .cs-plan-set { margin-block-start: var(--sp-6); }
.cs-plan-set-head { display: flex; align-items: center; gap: var(--sp-2); margin-block-end: var(--sp-3); }

/* Provider capability panel, above the region/plan list of the provider the
   customer just picked. Logical properties only, so RTL needs no twin. */
.cs-feats {
  margin-block-end: var(--sp-5);
  padding: var(--sp-4);
  background: var(--surface-2);
  border: 1px solid var(--ink-15);
  border-radius: var(--r-md);
}
.cs-feats-title { font-size: var(--fs-sm); font-weight: 700; margin: 0 0 var(--sp-3); }
.cs-feats-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--sp-2) var(--sp-4);
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}
.cs-feat { display: flex; align-items: baseline; gap: var(--sp-2); font-size: var(--fs-sm); }
.cs-feat-mark { flex-shrink: 0; }
.cs-feat.is-off .cs-feat-label { color: var(--ink-70); }
.cs-feat-note { margin-inline-start: auto; color: var(--ink-70); white-space: nowrap; }

/* ----- Sold-out / restricted provider tiles ---------------------------------------------------------------- */
.cs-pick.is-soldout .cs-pick-body { opacity: .55; }
.cs-pick.is-soldout, .cs-pick.is-restricted { cursor: not-allowed; }
.cs-pick.is-restricted .cs-pick-body { background: var(--paper-soft); }
.cs-pick.is-soldout:hover .cs-pick-body,
.cs-pick.is-restricted:hover .cs-pick-body { transform: none; box-shadow: var(--shadow); }

/* ----- Centered popup (must-see results: passwords, credentials) ------------------------------------------- */
.cs-popup { width: min(480px, calc(100vw - var(--sp-8))); }
.cs-popup .cs-modal-head { align-items: center; margin-bottom: var(--sp-3); }
.cs-popup-icon { width: 38px; height: 38px; }
/* Tone tints (the toast rules are descendant-scoped; the popup icon carries
   both classes on one element). */
.cs-popup-icon.cs-toast--success { background: var(--success-tint); color: var(--success-bright); }
.cs-popup-icon.cs-toast--danger  { background: var(--danger-tint);  color: var(--danger-bright); }
.cs-popup-icon.cs-toast--warning { background: var(--warning-tint); color: var(--warning-bright); }
.cs-popup-icon.cs-toast--info    { background: var(--navy-tint);    color: var(--navy-bright); }
.cs-popup-copy { max-width: 100%; }

/* ----- Busy-overlay progress line -------------------------------------------------------------------------- */
.cs-busy-progress {
  display: flex; align-items: center; gap: var(--sp-3);
  margin-top: var(--sp-6);
}
.cs-busy-progress .cs-bar { background: var(--surface); }
.cs-busy-progress .cs-bar > i { transition: none; } /* rAF drives the width directly */
.cs-busy-pct { min-width: 3.2em; text-align: start; font-size: var(--fs-lg); }

/* ----- Responsive ------------------------------------------------------------------------------------------------------ */
@media (max-width: 1080px) {
  .cs-buy { grid-template-columns: 1fr; }
  .cs-buy-summary { position: static; }
  .cs-grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 920px) {
  .cs-auth { grid-template-columns: 1fr; }
  /* Reserve headroom for the floating language/theme cluster (44px controls at
     top: var(--sp-5)) — single-column puts the brand pane, and in fa its
     start-aligned logo, right underneath it. */
  .cs-auth-brand { border-inline-end: 0; border-bottom: var(--bw) solid var(--ink); padding: calc(var(--sp-5) + 44px + var(--sp-4)) var(--sp-6) var(--sp-8); }
  .cs-auth-points { display: none; }
  .cs-auth-brand h1 { margin-top: var(--sp-6); }
}

@media (max-width: 860px) {
  :root { --topbar-h: 66px; }
  .cs-app { flex-direction: column; }
  .cs-sidebar {
    position: fixed;
    inset-block: 0;
    /* The drawer mirrors with the document: it lives at (and slides in from)
       the inline-start edge — left in en, RIGHT in fa. */
    inset-inline-start: 0;
    transform: translateX(calc(-100% - 4px));
    transition: transform var(--t-med) var(--ease-out);
    width: min(310px, 86vw);
    box-shadow: none;
    border-inline-end: var(--bw) solid var(--ink);
  }
  html[dir='rtl'] .cs-sidebar { transform: translateX(calc(100% + 4px)); }
  .cs-sidebar.is-open { transform: translateX(0); box-shadow: 12px 0 0 rgba(42,35,31,.2); }
  /* The transform must repeat here: the closed rtl rule above outranks
     `.cs-sidebar.is-open` (extra [dir] attribute), so without it the Persian
     drawer never slid in. */
  html[dir='rtl'] .cs-sidebar.is-open { transform: translateX(0); box-shadow: -12px 0 0 rgba(42,35,31,.2); }
  .cs-nav-veil { position: fixed; inset: 0; background: rgba(42,35,31,.4); z-index: calc(var(--z-nav) - 1); }
  .cs-btn.cs-burger { display: grid; }
  .cs-topbar { padding-inline: var(--sp-4); }
  .cs-page { padding: var(--sp-5) var(--sp-4) var(--sp-16); }
  .cs-page-head h1 { font-size: var(--fs-2xl); }
  .cs-grid--2, .cs-grid--3 { grid-template-columns: 1fr; }
  .cs-modal-inner { padding: var(--sp-6); }
  .cs-specs { grid-template-columns: repeat(2, 1fr); }
  .cs-code input { width: 44px; height: 54px; font-size: var(--fs-xl); }
  .cs-toasts { inset-inline: var(--sp-4); width: auto; }
}

@media (max-width: 480px) {
  .cs-grid--4 { grid-template-columns: 1fr; }
  .cs-specs { grid-template-columns: 1fr; }
  .cs-page-head { align-items: stretch; flex-direction: column; }
  .cs-btn--lg { min-height: 50px; padding: 0 var(--sp-6); }
  /* Phone topbar: burger + title + language + theme toggle + account no longer
     fit at 16px gaps — tighten the rhythm, let the title truncate instead of
     pushing the bar wide, and drop the account name (the menu shows the email). */
  .cs-topbar { gap: var(--sp-2); }
  .cs-topbar-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .cs-topbar-user { display: none; }
}

/* ----- Reduced motion ---------------------------------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  html.js [data-animate] { opacity: 1; }
  /* The draw animation has a start delay whose `backwards` fill would blank the
     underline for that long — skip it entirely instead. */
  .cs-scribble::after { animation: none !important; }
  /* No cross-document fade either. */
  @view-transition { navigation: none; }
}

/* ----- Night-mode component overrides ---------------------------------------
   The few places a colour is baked into a value (data-URI artwork, veils)
   rather than a token. Kept together so a token audit stays one screen. */
html[data-theme='dark'] .cs-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23D8E1E7' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
html[data-theme='dark'] dialog.cs-modal::backdrop { background: rgba(0, 0, 0, .6); }
html[data-theme='dark'] .cs-busy { background: rgba(22, 17, 13, .93); }
html[data-theme='dark'] .cs-nav-veil { background: rgba(0, 0, 0, .55); }
html[data-theme='dark'] .cs-sidebar.is-open { box-shadow: 12px 0 0 rgba(0, 0, 0, .45); }
html[data-theme='dark'][dir='rtl'] .cs-sidebar.is-open { box-shadow: -12px 0 0 rgba(0, 0, 0, .45); }

/* Theme toggle: shows the mode you would switch TO. */
.cs-theme-sun, .cs-theme-moon { display: grid; place-items: center; }
html:not([data-theme='dark']) .cs-theme-sun { display: none; }
html[data-theme='dark'] .cs-theme-moon { display: none; }

/* ----- Alpine cloak + misc late additions ----------------------------------- */
[x-cloak] { display: none !important; }
.cs-veil-hidden { display: none; }
.cs-toast .cs-btn { margin-top: var(--sp-2); }
html[dir='rtl'] .cs-flip-rtl { transform: scaleX(-1); }
