/* BigoIraq.com — design system. Layered on top of Bootstrap 5 RTL. */

@font-face {
  font-family: 'Cairo Display';
  font-weight: 800;
  font-style: normal;
  font-display: swap;
  src: url(../fonts/cairo800-arabic.woff2) format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+FB50-FDFF, U+FE70-FEFC, U+200C-200E;
}
@font-face {
  font-family: 'Cairo Display';
  font-weight: 800;
  font-style: normal;
  font-display: swap;
  src: url(../fonts/cairo800-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+2000-206F;
}
@font-face {
  font-family: 'Tajawal Text';
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  src: url(../fonts/tajawal400-arabic.woff2) format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+FB50-FDFF, U+FE70-FEFC, U+200C-200E;
}
@font-face {
  font-family: 'Tajawal Text';
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  src: url(../fonts/tajawal400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+2000-206F;
}
@font-face {
  font-family: 'Tajawal Text';
  font-weight: 700;
  font-style: normal;
  font-display: swap;
  src: url(../fonts/tajawal700-arabic.woff2) format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+FB50-FDFF, U+FE70-FEFC, U+200C-200E;
}
@font-face {
  font-family: 'Tajawal Text';
  font-weight: 700;
  font-style: normal;
  font-display: swap;
  src: url(../fonts/tajawal700-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+2000-206F;
}

:root {
  /* Base surfaces -- dark mode is the unconditional default, not a media-query variant */
  --paper: #0E0E10;
  --paper-2: #17171A;
  --base: #0E0E10;
  --base-deep: #0A0A0C;
  --card: #17171A;
  --border: rgba(255, 255, 255, 0.09);
  --border-strong: rgba(255, 255, 255, 0.16);

  /* Text */
  --ink: #F4F2ED;
  --ink-dim: #C9C6C1;
  --ink-faint: #ADAAA6;
  --ink-muted: #7A7773;

  /* The one actionable color in the system */
  --gold: #D4AF37;
  --gold-hover: #E3C557;
  --gold-pressed: #B8912E;
  --gold-soft: rgba(212, 175, 55, 0.12);

  /* Identity accents -- rare, symbolic, never functional (see DESIGN.md) */
  --flag-red: #A32D2D;
  --flag-green: #14603A;

  /* Functional, kept distinct from brand color on purpose */
  --danger: #e5484d;
  --good: #12B76A;
  --good-bright: #34D399;
  --warning: #F79009;
  --warning-soft: rgba(247, 144, 9, 0.14);
  --info: #7FB4E8;
  --info-soft: rgba(66, 133, 220, 0.14);
  --refund: #8b5cf6;

  /* The one deliberate light surface (closing CTA band only) */
  --light-surface: #F6F4EF;
  --light-ink: #1a1a1a;

  /* Legacy aliases: old variable names kept working, pointed at the new
     palette, until the hero/admin/component rename pass. Don't add new
     usages of these names -- use the ones above instead. */
  --navy: var(--base-deep);
  --navy-2: #141416;
  --navy-3: #1c1c1f;
  --teal: var(--gold);
  --teal-deep: var(--gold-pressed);
  --teal-soft: var(--gold-soft);
  --gold-deep: var(--gold-pressed);

  --shadow: 0 20px 45px -25px rgba(0, 0, 0, 0.6);
  --shadow-lg: 0 30px 80px -30px rgba(0, 0, 0, 0.75);
  --radius: 20px;

  /* 8px spacing scale (see DESIGN.md "The 8px Discipline Rule") */
  --space-1: 8px;
  --space-2: 16px;
  --space-3: 24px;
  --space-4: 32px;
  --space-5: 40px;
  --space-6: 48px;
  --space-7: 64px;

  --bs-body-font-family: 'Tajawal Text', 'Segoe UI', Tahoma, sans-serif;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: 'Tajawal Text', 'Segoe UI', Tahoma, sans-serif;
  font-size: 16px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, .display {
  font-family: 'Cairo Display', 'Tajawal Text', sans-serif;
  font-weight: 800;
  letter-spacing: -0.01em;
  text-wrap: balance;
  margin: 0;
  color: var(--ink);
}

p { margin: 0; }
a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; }
img, svg { display: block; max-width: 100%; }
.tnum { font-variant-numeric: tabular-nums; }

/* Page-container horizontal padding, on the 8px scale, defined once here so
   every page (and the header's own inner .wrap.nav-row) inherits it rather
   than each section re-declaring its own gutter. overflow-x: hidden is a
   containment backstop (not overflow-x: clip -- unsupported on iOS Safari
   < 16, and this audience skews toward older/budget devices): if a
   grid/table/flex child inside ever computes wider than the container (a
   common responsive bug), it gets clipped at this padded edge instead of
   visually escaping past it to the viewport edge -- which is what "content
   flush against the screen" actually looks like even when the container's
   own padding value is correct. */
/* Fluid, not a breakpoint lookup table: scales continuously with viewport
   width instead of jumping between 16/24/32px at fixed widths, so every
   real phone size in between (not just the ones that happen to land inside
   a tested tier) gets a proportionally-correct inset. */
.wrap, .wrap-narrow { margin: 0 auto; padding-inline: clamp(16px, 4vw, 32px); overflow-x: hidden; }
.wrap { max-width: 1180px; }
.wrap-narrow { max-width: 640px; }

/* ---------- header (glass moment #1 -- see DESIGN.md) ---------- */
header.site {
  position: sticky; top: 0; z-index: 40;
  background: rgba(14,14,16,0.55);
  -webkit-backdrop-filter: blur(20px) saturate(1.4);
  backdrop-filter: blur(20px) saturate(1.4);
  border-bottom: 1px solid rgba(255,255,255,0.08);
  transition: background 220ms ease, box-shadow 220ms ease;
}
header.site.scrolled {
  background: rgba(14,14,16,0.86);
  box-shadow: 0 12px 30px -18px rgba(0,0,0,0.9);
}
/* padding-top/bottom only -- .nav-row shares the .wrap class on the same
   element for its horizontal inset; a padding shorthand here would zero
   that out (padding-left/right: 0), same bug fixed in the mobile rule below.
   The nav is a thin, persistent strip, not a content section, so its inset
   is a single flat 16px at every breakpoint instead of following .wrap's
   16/24/32 content scale -- following it out to 24-32px read as too much
   on a single-row bar. padding-inline (not left/right) keeps this RTL-correct. */
.nav-row { display: flex; align-items: center; justify-content: space-between; gap: 32px; padding-top: var(--space-3); padding-bottom: var(--space-3); padding-inline: var(--space-2); }
.brand { display: flex; align-items: center; gap: 12px; font-family: 'Cairo Display', sans-serif; font-weight: 800; font-size: 1.32rem; color: #fff; }
/* Bootstrap ships a `.mark` UTILITY CLASS (background-color: #fff3cd;
   padding: 0.2em;, mirroring the native <mark> highlight element) that
   collides directly with this component's class name on every page that
   loads bootstrap.rtl.min.css (all of them). It's same-specificity as the
   bare `.mark` reset below and loads before main.css, so our rule wins by
   source order without needing `.brand` scoping -- this is what actually
   produced the cream badge behind the logo through every prior round of
   SVG/CSS changes, none of which touched this element at all. */
.mark { background: none; padding: 0; }
.brand .mark {
  width: 40px; height: 40px;
  display: grid; place-items: center;
  flex: none;
}
/* The mascot is a standalone illustration (its own body/eyes/crest colors),
   not a small icon that needs a colored badge behind it -- every application
   mockup in the logo exploration renders it directly against the page
   background. A custom admin-uploaded logo (the .mark img case) still gets
   the gold rounded-badge treatment, since an arbitrary uploaded image isn't
   guaranteed to read well with no backing shape. */
.brand .mark svg, .brand .mark img.mark-full, .brand .mark img.mark-head { width: 100%; height: 100%; }
.brand .mark .mark-head { display: none; }
@media (max-width: 640px) {
  /* Below 640px the full mascot loses too much detail at the shrunk 32px
     size -- swap to the simplified head cut instead of just scaling the
     same artwork down, per the logo exploration's own documented
     breakpoint rule ("full lockup down to 40px mascot height, head mark
     from 48px down"). */
  .brand .mark .mark-full { display: none; }
  .brand .mark .mark-head { display: block; }
}
/* The canonical mascot SVGs (referenced directly, not the .mark img case
   below) are standalone illustrations with their own colors -- no backing
   badge needed, unlike an arbitrary admin-uploaded logo. */
.brand .mark img.mark-full, .brand .mark img.mark-head {
  object-fit: contain; border-radius: 0; background: none; box-shadow: none;
}
.brand .mark img {
  width: 100%; height: 100%; object-fit: cover; border-radius: 12px;
  background: linear-gradient(155deg, var(--gold), var(--gold-pressed) 70%);
  box-shadow: 0 8px 18px -6px rgba(212,175,55,0.5);
}
.brand small { display: block; font-family: 'Tajawal Text', sans-serif; font-weight: 400; font-size: 0.68rem; color: var(--gold); letter-spacing: 0.04em; }
nav.links { display: flex; gap: 38px; font-size: 0.95rem; color: rgba(255,255,255,0.78); }
nav.links a { position: relative; padding: 8px 0; transition: color 0.2s; }
nav.links a:hover, nav.links a.active { color: #fff; }
nav.links a::after { content: ""; position: absolute; right: 0; bottom: 0; height: 2px; width: 100%; background: var(--gold); transform: scaleX(0); transform-origin: right; transition: transform 0.25s ease; }
nav.links a:hover::after, nav.links a.active::after { transform: scaleX(1); }

.nav-actions { display: flex; align-items: center; gap: 16px; }
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  border: none; border-radius: 12px; padding: 8px 24px; min-height: 44px;
  font-weight: 700; font-size: 0.95rem; white-space: nowrap;
  transition: transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease;
}
.btn:active { transform: translateY(1px); }
/* Primary action: gold fill, dark text -- the only color in the system that means "click me" (DESIGN.md) */
.btn-teal { background: linear-gradient(180deg, var(--gold-hover), var(--gold)); color: var(--light-ink); box-shadow: 0 12px 24px -10px rgba(212,175,55,0.55); }
.btn-teal:hover { background: linear-gradient(180deg, var(--gold-hover), var(--gold-hover)); box-shadow: 0 16px 30px -10px rgba(212,175,55,0.7); transform: translateY(-1px); color: var(--light-ink); }
.btn-teal:active { background: var(--gold-pressed); color: var(--light-ink); }
.btn-ghost-light { background: rgba(255,255,255,0.08); color: #fff; border: 1px solid rgba(255,255,255,0.22); }
.btn-ghost-light:hover { background: rgba(255,255,255,0.16); color: #fff; }
.btn-ghost-light.active { background: var(--gold-soft); border-color: var(--gold); color: var(--gold); box-shadow: 0 0 0 3px rgba(212,175,55,0.15); }
/* Customer header context for the shared .lang-menu component (see
   .lang-menu-btn's base rules further down, built for the admin topbar's
   opaque --paper-2 surface) -- on the customer site's translucent glass
   header, the button instead matches its immediate siblings in the same row
   (.btn-ghost-light, .btn-icon-ghost's logout button), so it reads as part
   of that row rather than an imported admin control. The floating panel
   itself (a dropdown overlay, not part of the header surface) stays the
   shared --card treatment used for every other elevated surface in this
   design system. */
.nav-actions .lang-menu-btn,
.sidebar-links .lang-menu-btn {
  background: rgba(255,255,255,0.08); border-color: rgba(255,255,255,0.22); color: #fff;
}
.nav-actions .lang-menu-btn:hover,
.sidebar-links .lang-menu-btn:hover { background: rgba(255,255,255,0.16); }
.lang-menu--block { width: 100%; margin-top: var(--space-1); }
.lang-menu--block .lang-menu-btn { width: 100%; }
.lang-menu--block .lang-menu-btn > svg { margin-inline-start: auto; }
.btn-icon-ghost {
  width: 38px; height: 38px; flex: none; display: grid; place-items: center; border-radius: 10px;
  background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.22); color: #fff; cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease;
}
.btn-icon-ghost:hover { background: rgba(255,80,80,0.22); border-color: rgba(255,80,80,0.4); color: #ffb3b3; }
#bj-mobile-account-link { display: none; }
#bj-mobile-account-link:hover { background: var(--gold-soft); border-color: var(--gold); color: var(--gold); }
#bj-mobile-account-link.active { background: var(--gold-soft); border-color: var(--gold); color: var(--gold); box-shadow: 0 0 0 3px rgba(212,175,55,0.15); }
.btn-outline { background: transparent; color: var(--ink); border: 1.5px solid var(--border); }
.btn-outline:hover { border-color: var(--gold); color: var(--gold); }
.btn-lg { padding: 16px 32px; font-size: 1.02rem; border-radius: 12px; }
.btn-block { width: 100%; }
.btn:disabled, .btn.disabled { opacity: 0.55; cursor: not-allowed; pointer-events: none; }

/* ---------- loading system (shared by customer site + admin panel) ----------
   One small vocabulary reused everywhere instead of one-off spinners per
   feature: .spinner (inline/button), [data-loading] (button state), .skeleton
   (placeholder blocks shaped to match the real content, not one generic
   rectangle everywhere -- see .skel-* shapes below), .bj-page-loader
   (full-page, used only where a real network wait exists -- never added to
   the instant language-swap gate, which would just turn a sub-frame flash
   into a bug). The brand thread running through all three: the real gold
   diamond badge (the same mark used in every header/sidebar -- see .brand
   .mark) catching a light sweep, echoed as a fainter gold-tinted shimmer on
   skeletons and a gold leading edge on the spinner ring -- one motif, not
   three unrelated effects. All of it rides plain CSS transitions/animations,
   so the existing global reduced-motion rule further down (`*, *::before,
   *::after { animation-duration:0.01ms !important }` -- the pseudo-element
   selectors were added during this system's own audit, since the bare `*`
   it originally shipped with doesn't reach a ::after-only animation like the
   loader's gleam) already neutralizes every animation below for free -- a
   frozen single frame of each still reads clearly as "ring" / "shimmer
   block" / "badge", so no extra reduced-motion rule is needed here. */
@keyframes bj-spin { to { transform: rotate(360deg); } }
.spinner {
  width: 18px; height: 18px; flex: none; border-radius: 50%;
  border: 2px solid rgba(255,255,255,0.22); border-inline-start-color: var(--gold);
  animation: bj-spin 0.85s cubic-bezier(0.5,0.05,0.5,0.95) infinite;
}
.spinner-sm { width: 14px; height: 14px; border-width: 2px; }
.spinner-lg { width: 28px; height: 28px; border-width: 2.5px; }
/* On the gold-filled primary button, a gold ring on gold would vanish --
   flip the ring to the dark ink used for that button's own text instead. */
.btn-teal .spinner { border-color: rgba(26,26,26,0.2); border-inline-start-color: var(--light-ink); }

/* Button loading state: the label stays in the DOM (so its own natural width
   keeps informing the button's box) but is visually swapped for a spinner +
   optional text absolutely centered over it -- set via JS (bjSetBtnLoading /
   adminSetBtnLoading) locking min-width to the button's pre-loading width
   first, which is what actually guarantees no layout shift regardless of how
   the label's length compares to "Processing..." in any language. */
.btn[data-loading] { position: relative; pointer-events: none; }
.btn-label-hidden { visibility: hidden; }
.btn-loading-overlay {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 8px;
  color: var(--ink); font-weight: inherit; font-size: inherit;
}
.btn-teal .btn-loading-overlay { color: var(--light-ink); }

/* Skeleton placeholders: shaped to match the real component they stand in
   for (see .skel-pkg-card, .skel-row below) rather than one generic block
   everywhere, sitting on the same solid Card surface every real card uses,
   with a gold-tinted sweep (not flat white) so it reads as this product's
   skeleton, not a UI-kit default -- faint enough to never look clickable
   (the One Actionable Color Rule is about buttons, not a passive shimmer,
   but the same restraint applies). */
@keyframes bj-shimmer { 0% { background-position: -120% 0; } 100% { background-position: 220% 0; } }
.skeleton {
  display: inline-block; border-radius: 6px; background-color: rgba(255,255,255,0.06);
  background-image: linear-gradient(90deg, transparent, rgba(212,175,55,0.18), transparent);
  background-size: 60% 100%; background-repeat: no-repeat; animation: bj-shimmer 1.5s ease-in-out infinite;
}
.skeleton-text { display: block; height: 0.85em; width: 100%; margin: 0.2em 0; }
.skeleton-text.w-60 { width: 60%; }
.skeleton-text.w-40 { width: 40%; }
.skeleton-block { display: block; width: 100%; height: 100%; border-radius: 10px; }
.skeleton-circle { border-radius: 50%; }
.skeleton-pill { border-radius: 100px; }
/* Standard accessible-label pattern: the shimmering blocks are aria-hidden
   (decorative -- a screen reader gains nothing from "gray rectangle"), while
   this carries the one real "Loading..." announcement via the container's
   aria-live region, so it fires once per load rather than once per frame. */
.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; }

/* Package-card-shaped skeleton (packages.html / checkout.html bundle lists)
   -- mirrors .pkg-card's real shape (coin circle, coin count, price) instead
   of a plain "Loading packages..." line. */
.skel-pkg-card {
  background: var(--card); border: 1.5px solid var(--border); border-radius: var(--radius);
  padding: 26px 20px 22px; display: flex; flex-direction: column; align-items: center; gap: 12px;
}
.skel-pkg-card .skeleton-block.pkg-coin-skel { width: 44px; height: 44px; border-radius: 12px; margin-bottom: 4px; }
.skel-pkg-card .skeleton-text { height: 1.35rem; }
/* Matches .btn's real min-height (44px) + border-radius (12px) so the real
   card's CTA doesn't visibly grow the layout the moment content replaces
   this skeleton -- previously omitted entirely, leaving the skeleton ~60px
   shorter than any real card. */
.skel-pkg-card .skeleton-block.pkg-btn-skel { width: 100%; height: 44px; border-radius: 12px; margin-top: auto; }

/* Payment-method-card-shaped skeleton (payments.html) -- mirrors .pay-card's
   real horizontal badge+text shape. */
.skel-pay-card {
  background: var(--card); border: 1.5px solid var(--border); border-radius: 16px;
  padding: 18px; display: flex; align-items: center; gap: 12px;
}
.skel-pay-card .skeleton-block { width: 46px; height: 46px; border-radius: 12px; flex: none; }
.skel-pay-card__lines { flex: 1; display: flex; flex-direction: column; gap: 6px; }

/* Row-shaped skeleton (account orders/transactions, payment-method list) --
   a status-pill-shaped bar + label bar on top, one detail line below,
   mirroring .acc-order-item/.acc-txn-item's real two-line shape. */
.skel-row { padding: 14px 0; border-bottom: 1px solid var(--border); }
.skel-row:last-child { border-bottom: none; }
.skel-row__top { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 10px; }

/* Full-page loader: reserved for a genuine network wait before real content
   can render at all (e.g. the "are you signed in?" check on login.html) --
   NOT for the instant per-page translation swap, which already avoids FOUC
   without needing a visible loader of its own (see bj-lang-loading below).
   Sits on Base Deep (the hero's tone) rather than flat Base -- the same
   "this is a moment" signal the hero already uses, not a new device. */
.bj-page-loader {
  position: fixed; inset: 0; z-index: 500; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 22px; background: var(--base-deep);
  opacity: 1; transition: opacity 0.2s ease;
  /* Explicit override: this can be mounted while an ancestor (html.bj-lang-loading
     body) is visibility:hidden for the anti-FOUC gate -- without this it would
     silently inherit hidden too, since visibility (unlike display) inherits. */
  visibility: visible;
}
.bj-page-loader.is-hidden { opacity: 0; pointer-events: none; }
.bj-page-loader-text { color: var(--ink-dim); font-family: 'Cairo Display', 'Cairo', sans-serif; font-weight: 700; font-size: 1.15rem; }

/* The brand mark itself (same badge as .brand .mark: gold-gradient rounded
   square, white diamond outline) at loader scale, with one idea carried
   through the whole system: light catching a facet. A soft diagonal band
   sweeps once across the badge, pauses off-badge, then repeats -- clearly
   visible (a real bright band, not a 5%-opacity hint) but never frantic:
   about 1s of visible travel inside the 2.2s cycle, so it reads as a
   deliberate, premium beat rather than "is something happening?". */
.bj-loader-mark {
  width: 64px; height: 64px; border-radius: 18px; flex: none; position: relative; overflow: hidden;
  background: linear-gradient(155deg, var(--gold), var(--gold-pressed) 70%);
  display: grid; place-items: center; box-shadow: 0 16px 32px -14px rgba(212,175,55,0.6);
}
.bj-loader-mark svg, .bj-loader-mark img { width: 32px; height: 32px; position: relative; z-index: 1; }
/* A defined, crisp band (not a soft indistinct glow) so the sweep reads as
   "light hitting an edge" at actual loader size, not just under magnification --
   verified against real, unscaled screenshots at this exact size. */
.bj-loader-mark::after {
  content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: linear-gradient(115deg, transparent 38%, rgba(255,255,255,0.35) 46%, #fff 50%, rgba(255,255,255,0.35) 54%, transparent 62%);
  background-size: 300% 300%; background-position: -130% -130%;
  animation: bj-gleam 2.2s ease-in-out infinite;
}
@keyframes bj-gleam {
  0% { background-position: -130% -130%; }
  45% { background-position: 130% 130%; }
  100% { background-position: 130% 130%; }
}

@keyframes bj-install-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(212,175,55,0.55); }
  50% { box-shadow: 0 0 0 12px rgba(212,175,55,0); }
}
@keyframes bj-install-bounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-3px); }
}
.install-cta {
  background: var(--gold-soft) !important; border-color: var(--gold) !important; color: var(--gold) !important;
  animation: bj-install-pulse 2.2s ease-in-out infinite;
}
.install-cta svg { animation: bj-install-bounce 2.2s ease-in-out infinite; }

.burger { display: none; width: 40px; height: 40px; border-radius: 10px; background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.16); align-items: center; justify-content: center; }
.burger svg { width: 18px; height: 18px; stroke: #fff; }

/* off-canvas sidebar menu (mobile) */
.sidebar-overlay {
  position: fixed; inset: 0; background: rgba(6,13,30,0.6);
  opacity: 0; pointer-events: none; transition: opacity 0.25s ease; z-index: 90;
}
.sidebar-overlay.open { opacity: 1; pointer-events: auto; }
.sidebar-nav {
  position: fixed; top: 0; left: 0; height: 100vh; height: 100dvh; width: min(300px, 82vw);
  background: var(--navy); z-index: 95; transform: translateX(-100%);
  transition: transform 0.3s ease; display: flex; flex-direction: column;
  box-shadow: 20px 0 60px rgba(0,0,0,0.4);
}
.sidebar-nav.open { transform: translateX(0); }
.sidebar-nav-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px; border-bottom: 1px solid rgba(255,255,255,0.08); flex: none;
}
.sidebar-close {
  width: 36px; height: 36px; border-radius: 10px; background: rgba(255,255,255,0.08);
  border: none; display: grid; place-items: center;
}
.sidebar-close svg { width: 16px; height: 16px; stroke: #fff; }
.sidebar-links { display: flex; flex-direction: column; padding: 10px 12px 24px; overflow-y: auto; gap: 2px; }
.sidebar-links a {
  color: rgba(255,255,255,0.82); padding: 13px 12px; border-radius: 10px;
  font-size: 0.98rem; font-weight: 700; transition: background 0.15s ease, color 0.15s ease;
}
.sidebar-links a:hover, .sidebar-links a.active { background: rgba(255,255,255,0.08); color: #fff; }
.sidebar-divider { height: 1px; background: rgba(255,255,255,0.08); margin: 10px 4px; }

/* Signed-in identity summary at the top of the mobile drawer -- previously
   the only account trace in this menu was a bare "تسجيل الخروج" text link at
   the bottom, so opening the hamburger while signed in gave zero indication
   of *who* was signed in. Populated by bjRefreshAuthLink() in site.js off the
   same /auth/me call every page already makes -- no extra request. Hidden
   entirely for guests (unauthenticated sidebar is unchanged). */
.sidebar-profile { display: flex; align-items: center; gap: 12px; padding: 16px 18px; border-bottom: 1px solid rgba(255,255,255,0.08); flex: none; }
.sidebar-profile__avatar {
  width: 42px; height: 42px; border-radius: 50%; flex: none; display: grid; place-items: center;
  background: linear-gradient(155deg,#ffd27a,var(--gold)); color: #4a2e00; font-weight: 800; font-size: 1rem;
  font-family: 'Cairo Display', sans-serif;
}
.sidebar-profile__info { min-width: 0; flex: 1; }
.sidebar-profile__name { color: #fff; font-weight: 700; font-size: 0.94rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Client ID chip + copy control -- shared between the sidebar summary above
   and account.html's profile card (renderProfile()) so there is exactly one
   copy interaction/markup shape to maintain, not two. Client ID is
   customers.id, the one identifier BigoIraq already uses to address a
   client account throughout the system (wallet_transactions.customer_id,
   orders.customer_id, admin customer lookups) -- there is no separate
   public-facing code to prefer over it. Deliberately NOT the Bigo ID (a
   BIGO LIVE account identifier the customer enters at checkout, unrelated to
   their BigoIraq account) and NOT an order number. */
.acc-client-id {
  display: inline-flex; align-items: center; gap: 8px; max-width: 100%;
  background: rgba(255,255,255,0.05); border: 1px solid var(--border); border-radius: 100px;
  padding: 4px 6px 4px 12px;
}
html[dir="rtl"] .acc-client-id { padding: 4px 12px 4px 6px; }
.acc-client-id__label { font-size: 0.72rem; color: var(--ink-faint); font-weight: 700; white-space: nowrap; flex: none; }
.acc-client-id__value { font-size: 0.82rem; font-weight: 700; color: var(--ink); white-space: nowrap; }
.acc-client-id__copy-btn {
  position: relative; display: inline-flex; align-items: center; gap: 5px; flex: none;
  background: rgba(255,255,255,0.08); border: none; border-radius: 100px; padding: 5px 11px;
  min-height: 32px; color: var(--ink-dim); font-size: 0.72rem; font-weight: 700; cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
/* Invisible expanded hit area, not a bigger pill -- DESIGN.md's 44px minimum
   tap target satisfied without visually inflating a small inline control
   (WCAG 2.5.8's "target offset" allowance: the visible control can be
   smaller than 44px as long as the actual pointer/touch target isn't). */
.acc-client-id__copy-btn::before { content: ""; position: absolute; inset: -6px; }
.acc-client-id__copy-btn svg { width: 13px; height: 13px; flex: none; }
.acc-client-id__copy-btn .icon-check { display: none; }
.acc-client-id__copy-btn.is-copied .icon-copy { display: none; }
.acc-client-id__copy-btn.is-copied .icon-check { display: block; }
@media (hover: hover) {
  .acc-client-id__copy-btn:hover { background: var(--gold-soft); color: var(--gold); }
}
.acc-client-id__copy-btn:active { background: var(--gold-soft); color: var(--gold); transform: scale(0.96); }
.acc-client-id__copy-btn.is-copied { background: rgba(18,183,106,0.14); color: var(--good); }
.acc-client-id__copy-btn:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }
@media (max-width: 360px) {
  /* Narrowest supported phone width: the label ("Client ID" / "معرّف
     العميل") is the one part safe to drop -- the value and Copy control
     (the two functional parts) never shrink or wrap. */
  .acc-client-id__label { display: none; }
}

/* ---------- hero (literal flag, once -- see DESIGN.md "The Flag Is Literal,
   Once Rule"). The flag is drawn as three CSS bands rather than an image
   asset, so its colors and the 3:2 proportion are exact and crisp at any
   size. bjHeroFlag() in site.js cover-crops it precisely and centers the
   Takbir text; both degrade to a static, uncropped layout with JS off. ---------- */
.hero {
  position: relative;
  background: var(--base-deep);
  overflow: hidden;
  min-height: clamp(460px, 58vh, 620px);
  display: flex;
  align-items: center;
  padding: var(--space-5) 0 56px;
}
.hero-flag {
  /* left/top/width/height are physical on purpose: bjHeroFlag() in site.js
     computes a symmetric cover-crop from the hero's raw pixel geometry, the
     same math regardless of text direction -- only the scrim (below) needs
     to flip for RTL/LTR, not the flag's own centering. */
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  transform-origin: center;
  will-change: transform;
  pointer-events: none;
  display: flex;
  flex-direction: column;
}
.hero-flag-band { flex: 1; position: relative; }
.hero-flag-band--red { background: var(--flag-red); }
.hero-flag-band--white { background: #F4F2ED; }
.hero-flag-band--black { background: #101012; }
.hero-flag-takbir {
  position: absolute; top: 50%; transform: translate(-50%, -50%);
  font-family: 'Reem Kufi', 'Cairo Display', sans-serif;
  font-weight: 600;
  color: var(--flag-green);
  line-height: 1;
  letter-spacing: 0.06em;
  white-space: nowrap;
}
.hero-scrim-x {
  position: absolute; inset: 0;
  background: linear-gradient(to left, rgba(10,10,12,0.96) 0%, rgba(10,10,12,0.93) 46%, rgba(10,10,12,0.46) 74%, rgba(10,10,12,0.18) 100%);
}
html[dir="ltr"] .hero-scrim-x {
  background: linear-gradient(to right, rgba(10,10,12,0.96) 0%, rgba(10,10,12,0.93) 46%, rgba(10,10,12,0.46) 74%, rgba(10,10,12,0.18) 100%);
}
.hero-scrim-y {
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(10,10,12,0.55), rgba(10,10,12,0) 42%);
}
.hero .wrap { position: relative; z-index: 2; width: 100%; }
.hero-copy { max-width: min(600px, 54%); }
.eyebrow { display: inline-flex; align-items: center; gap: 8px; background: var(--gold-soft); border: 1px solid rgba(212,175,55,0.4); color: var(--gold); font-size: 0.82rem; font-weight: 700; padding: 7px 14px; border-radius: 100px; margin-bottom: var(--space-3); }
.eyebrow .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--gold); box-shadow: 0 0 0 4px rgba(212,175,55,0.25); }
.hero h1 { color: #fff; font-size: clamp(2.1rem, 4vw, 3.15rem); line-height: 1.22; }
.hero h1 em { font-style: normal; color: var(--gold); }
.hero p.lead { color: rgba(255,255,255,0.72); font-size: 1.08rem; max-width: 46ch; margin-top: var(--space-3); }
.hero-cta { display: flex; gap: 14px; margin-top: var(--space-4); flex-wrap: wrap; }

@media (max-width: 640px) {
  /* The flag renders full-bleed at every width via bjHeroFlag()'s cover-crop
     (site.js) -- same literal-flag treatment as desktop, not a separate
     mobile asset or a hidden/placeholder background. The previous pass hid
     this outright below 640px because the Takbir text could clip against
     the hero's overflow:hidden edge at narrow widths; that's now fixed at
     the source in bjHeroFlag() (measures the text's real rendered width and
     shrinks it to fit, instead of guessing a font-size from a fixed
     formula), so there's nothing mobile-specific to override here for the
     flag graphic itself. */

  /* Full-width instead of a 54% column, so the scrim goes uniform instead of
     directional: a partial-width fade would leave the wrapped end of
     full-width RTL text sitting on barely-darkened flag. padding-right
     reserves a safe zone the fixed WhatsApp bubble (.wa-float) sits in --
     but .wa-float itself mirrors to the LEFT for ar/ku (see its own rule
     below), so the reservation must mirror too instead of always guarding
     the right; the previous single-sided padding-right was the actual cause
     of the WA bubble overlapping wrapped Arabic/Kurdish text discovered in
     the mobile hero audit. */
  .hero-copy { max-width: 100%; padding-right: 84px; }
  html[lang="ar"] .hero-copy,
  html[lang="ku"] .hero-copy { padding-right: 0; padding-left: 84px; }
  .hero-scrim-x { background: rgba(10,10,12,0.85); }
  /* html[dir="ltr"] .hero-scrim-x (desktop, unscoped) has higher specificity
     (attribute selector + class) than the flat mobile override directly
     above (class only), so it was still winning over it for English at
     every mobile width -- English never actually got the flat 0.85 mobile
     scrim, it kept desktop's directional 0.96->0.18 gradient, which fades to
     nearly nothing by the paragraph's position and made the Takbir bleed-
     through worse specifically for English. Same specificity, same
     @media block, so source order now correctly wins for mobile. */
  html[dir="ltr"] .hero-scrim-x { background: rgba(10,10,12,0.85); }
  .hero-scrim-y { background: linear-gradient(to bottom, rgba(10,10,12,0.15), rgba(10,10,12,0) 30%, rgba(10,10,12,0) 65%, rgba(10,10,12,0.3)); }


  /* Mobile hero is composed on its own vertical budget, not a shrunk copy of
     desktop's: tighter spacing steps (still on the 8px scale), the h1
     dropped to the Headline type step (DESIGN.md) instead of Display, the
     desktop-tuned <br/> removed so each language wraps on its own terms, and
     the eyebrow forced to one line so its pill shape never breaks. */
  .hero { padding: var(--space-4) 0 var(--space-3); }
  .hero .eyebrow { white-space: nowrap; margin-bottom: var(--space-2); }
  .hero h1 { font-size: clamp(1.5rem, 6.5vw, 2.1rem); line-height: 1.2; }
  .hero h1 br { display: none; }
  /* Hiding the <br/> above removes the only separator between "...LIVE</em>"
     and the word right after it in every language's string (there's no literal
     space there in the source -- the <br/> itself was providing the gap) --
     without this, the words render glued together ("LIVEdiamonds"). Keeping
     "BIGO LIVE" unbreakable (it's a product name, not a phrase that should
     ever split mid-word) also keeps it a single line fragment, so the margin
     below lands predictably on one clean outer edge instead of a wrapped
     inline's ambiguous first/last-fragment edges. <em> is always dir="ltr"
     content (explicit for ar/ku, implicit for en); the gap has to land on
     whichever physical side the next word actually continues on, which is
     the surrounding paragraph's direction, not <em>'s own. */
  .hero h1 em { white-space: nowrap; }
  html[dir="rtl"] .hero h1 em { margin-left: 0.55em; }
  html[dir="ltr"] .hero h1 em { margin-right: 0.55em; }
  .hero p.lead { font-size: 1rem; max-width: 34ch; margin-top: var(--space-2); }
  .hero-cta { flex-direction: column; margin-top: var(--space-3); }
  .hero-cta .btn { flex: none; width: 100%; }
  /* Professional mobile button sizing: the desktop .btn-lg's 16px vertical
     padding (56-58px rendered) is comfortable for a wide desktop button row
     but reads slightly oversized once stacked full-width on a phone --
     trimmed to a still-generous ~50-52px, well clear of the 44px minimum
     tap target, without touching .btn-lg anywhere else in the app
     (:not(.install-cta) since it already has its own smaller treatment). */
  .hero .hero-cta .btn-lg:not(.install-cta) { padding-block: 12px; min-height: 50px; }
  /* The PWA install prompt is a bonus action, not a third conversion CTA --
     keeping it full-width and .btn-lg-sized here would give it equal visual
     weight to "start topping up", the opposite of the mobile hierarchy this
     redesign is meant to establish. */
  .hero .hero-cta .install-cta { width: auto; align-self: flex-start; padding: 10px 20px; font-size: 0.88rem; }
}

@media (max-width: 400px) {
  /* Critical narrow-mobile layout (320-400px, iPhone SE-class phones): the
     widths where the audit measured the primary CTA landing below the fold.
     Same composition as the 640px step above, just budgeted tighter --
     confirmed against Kurdish (this project's longest-running language in
     every hero string) with real Playwright measurements, not guessed. */
  .hero { padding: var(--space-3) 0 var(--space-1); }
  .hero h1 { font-size: clamp(1.375rem, 7.5vw, 1.75rem); }
  .hero .eyebrow { margin-bottom: var(--space-1); }
  .hero p.lead { max-width: 30ch; line-height: 1.45; margin-top: var(--space-1); }
  .hero .hero-cta { margin-top: var(--space-1); gap: var(--space-1); }
  /* .install-cta's pulse animation (bj-install-pulse, main.css above) grows a
     box-shadow ring up to 12px past its own border -- box-shadow doesn't
     affect layout, so it isn't covered by the shared 8px flex gap above,
     and would otherwise visually bleed into the secondary CTA sitting
     directly above it at this width. This margin only widens the install
     button's own top clearance -- it stacks on top of (doesn't replace)
     the shared gap, so primary/secondary spacing is unaffected. */
  .hero .hero-cta .install-cta { margin-top: var(--space-1); }
}

@media (min-width: 641px) and (max-width: 1024px) {
  /* Tablet CTA layout. Above 640px .hero-cta's base rule (unscoped, further
     below) reverts to row + flex-wrap with content-sized buttons -- fine at
     true desktop widths where the 54% copy column is wide, but between
     roughly 641-833px that same column (.hero-copy's own min(600px,54%),
     untouched here) isn't consistently wide enough for both buttons' natural
     content width, so the row silently half-wraps: an unintentional, uneven
     break rather than a designed tablet composition. Grid replaces the ad
     hoc wrap math with an explicit, deterministic layout: two equal columns
     for primary/secondary (matching "equal visual weight"), with install
     spanning both and centered on its own row below -- no flex-basis wrap
     hacks, no JS, nothing outside normal document flow. 1024px reuses this
     file's own existing tablet/desktop breakpoint value rather than
     introducing a new one solely for this. */
  .hero .hero-cta {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-3);
    margin-top: var(--space-4);
  }
  /* min-width:0 overrides the grid-item default of min-width:auto (each
     track's minimum content size = its longest word/nowrap text), which
     would otherwise let the longer button's label force its own column
     wider than a true 50/50 split -- both labels are short enough that
     nothing wraps or clips once this is reset. */
  .hero .hero-cta .btn-lg:not(.install-cta) { width: 100%; min-width: 0; }
  /* Same compact/secondary treatment as mobile above -- without this the
     install button reverts to full .btn-lg sizing here (56-58px, full
     natural width) and, once it wraps to its own row under the flex-wrap
     rule this replaces, that generic full-size button reads as a third
     equal-weight CTA rather than the optional action it's meant to be. */
  .hero .hero-cta .install-cta {
    grid-column: 1 / -1;
    justify-self: start;
    width: auto;
    padding: 10px 20px;
    font-size: 0.88rem;
    margin-top: var(--space-2);
  }
}

/* small page hero for inner pages */
.page-hero {
  background: linear-gradient(160deg, var(--navy) 0%, var(--navy-2) 62%, var(--navy-3) 100%);
  padding: 56px 0 64px;
  position: relative;
  overflow: hidden;
}
.page-hero::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(55% 90% at 85% 0%, rgba(20,184,162,0.3), transparent 60%);
}
.page-hero .wrap { position: relative; z-index: 1; }
.page-hero h1 { color: #fff; font-size: clamp(1.7rem, 3.4vw, 2.4rem); }
.page-hero p { color: rgba(255,255,255,0.72); margin-top: 10px; max-width: 60ch; }
.breadcrumb-min { display: flex; gap: 8px; align-items: center; color: rgba(255,255,255,0.5); font-size: 0.85rem; margin-bottom: 14px; }
.breadcrumb-min a:hover { color: #fff; }

/* "live" status pill -- still used standalone (e.g. checkout.html order
   status), independent of the old hero device mockup this used to live in. */
.live-pill { display: flex; align-items: center; gap: 6px; background: var(--gold-soft); color: var(--gold); font-size: 0.72rem; font-weight: 700; padding: 5px 10px; border-radius: 100px; }
.live-pill .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--gold); animation: pulse 1.6s infinite; }
@keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.35} }

/* ---------- sections ---------- */
section.pad { padding: 84px 0; }
.section-head { text-align: center; max-width: 620px; margin: 0 auto 48px; }
.section-head .eyebrow-alt { display: inline-block; color: var(--teal-deep); background: var(--teal-soft); font-size: 0.8rem; font-weight: 700; padding: 6px 14px; border-radius: 100px; margin-bottom: 14px; }
.section-head h2 { font-size: clamp(1.6rem, 3vw, 2.15rem); }
.section-head p { color: var(--ink-dim); margin-top: 12px; font-size: 1.02rem; }

/* ---------- packages ---------- */
.pkg-scroller { display: grid; grid-template-columns: repeat(5, 1fr); gap: 18px; }
.pkg-card { position: relative; background: var(--card); border: 1.5px solid var(--border); border-radius: var(--radius); padding: 26px 20px 22px; text-align: center; box-shadow: var(--shadow); transition: transform 0.22s ease, box-shadow 0.22s ease, border-color 0.22s ease; }
/* Standard package cards only (never .pkg-card-custom, whose layout is
   unrelated) -- CSS Grid's default align-items:stretch already equalizes
   every card's OUTER height within a row, but without this, each card's CTA
   still sits at its own natural offset from the top, so a card with a
   type-tag/bonus-tag pill (taller natural content) pushes its button lower
   than a plain sibling's -- same row, misaligned buttons. Flex-column +
   margin-top:auto on .btn lets the button absorb exactly the row's stretch
   surplus, pinning every CTA in a row to the same baseline. align-items:
   center (not the flex default stretch) keeps .pkg-type-tag/.pkg-bonus-tag
   shrink-wrapped pills instead of stretching them to the card's full width. */
.pkg-card:not(.pkg-card-custom) { display: flex; flex-direction: column; align-items: center; }
.pkg-card:not(.pkg-card-custom) .btn { margin-top: auto; }
.pkg-card:hover { transform: translateY(-6px); box-shadow: var(--shadow-lg); border-color: var(--gold); }
.pkg-card.best { border-color: var(--gold); box-shadow: 0 24px 55px -25px rgba(212,175,55,0.5); }
.pkg-ribbon { position: absolute; top: -13px; left: 50%; transform: translateX(-50%); background: linear-gradient(180deg, var(--gold-hover), var(--gold)); color: var(--light-ink); font-size: 0.72rem; font-weight: 700; padding: 6px 16px; border-radius: 100px; box-shadow: 0 8px 16px -6px rgba(212,175,55,0.6); white-space: nowrap; }
.pkg-ribbon.gold { background: linear-gradient(180deg, var(--gold-hover), var(--gold-pressed)); box-shadow: 0 8px 16px -6px rgba(212,175,55,0.55); }
/* Flat, bordered tile per DESIGN.md's elevation rule ("flat-and-bordered by
   default, not shadow-driven... real elevation reserved for named glass
   moments") -- the previous glossy radial-gradient sphere with a heavy
   inset+outer shadow was the one shadow-driven ornament on an otherwise flat
   card, which is what read as "an image dropped into the UI" rather than a
   package-card element. gold-soft + a gold-tinted hairline is the same
   accent language the FAQ's open-state border and the best-value ribbon
   already use elsewhere in this system. */
.pkg-coin { width: 44px; height: 44px; margin: 0 auto 16px; border-radius: 12px; background: var(--gold-soft); border: 1px solid rgba(212,175,55,0.35); display: grid; place-items: center; }
.pkg-coin svg { width: 24px; height: 24px; }
.pkg-coin img { width: 100%; height: 100%; object-fit: cover; border-radius: 10px; }
.pkg-card .coins { font-family: 'Cairo Display', sans-serif; font-size: 1.5rem; }
.pkg-card .coins span { color: var(--ink-dim); font-family: 'Tajawal Text',sans-serif; font-weight: 400; font-size: 0.62em; margin-inline-start: 4px; }
.pkg-card .price { margin-top: 14px; font-family: 'Cairo Display', sans-serif; font-size: 1.7rem; color: var(--gold); }
.pkg-card .price span { font-family:'Tajawal Text',sans-serif; font-weight:700; font-size: 0.5em; color: var(--ink-dim); margin-inline-start: 3px;}
/* margin-bottom (not .btn's margin-top) carries the fixed 16px CTA gap now,
   so margin-top:auto on .btn above only ever ADDS extra space (from row
   stretch) on top of this guaranteed minimum, instead of that minimum
   collapsing to 0 whenever a card happens to be the tallest in its row. */
.price-usd { margin-top: 3px; margin-bottom: 16px; font-size: 0.78rem; font-weight: 600; color: var(--ink-faint); font-family: 'Tajawal Text', sans-serif; }
.pkg-card .btn { margin-top: 16px; }
.pkg-card.selectable { cursor: pointer; }
.pkg-type-tag { display: inline-block; font-size: 0.68rem; font-weight: 700; letter-spacing: 0.03em; color: var(--gold); background: var(--gold-soft); border-radius: 100px; padding: 3px 11px; margin-bottom: 8px; }
/* Font-size/padding tuned tighter than .pkg-type-tag's own recipe -- this
   line carries both the bonus and total figures, and at the narrowest
   supported card width (2-col mobile grid, ~149px content width) that's the
   most text this pill can hold without wrapping to a second line and
   growing the card (verified against every current bonus_coins value in the
   catalog; an unusually large 5-6 digit bonus package can still wrap here,
   which degrades gracefully rather than clipping). */
.pkg-bonus-tag { display: inline-block; margin-top: 6px; font-size: 0.7rem; font-weight: 700; color: var(--gold); background: var(--gold-soft); border-radius: 100px; padding: 3px 8px; }

.pkg-card-custom { grid-column: span 2; text-align: start; }
.pkg-card-custom .custom-pkg-lead { color: var(--ink-dim); font-size: 0.85rem; margin-bottom: 16px; }
.custom-pkg-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.custom-pkg-field label { display: block; font-size: 0.78rem; font-weight: 600; color: var(--ink-dim); margin-bottom: 6px; }
.custom-pkg-field input { width: 100%; border: 1.5px solid var(--border); border-radius: 10px; padding: 10px 12px; font-family: 'Tajawal Text', sans-serif; font-size: 0.95rem; background: var(--paper); color: var(--ink); }
.custom-pkg-field input:focus { outline: none; border-color: var(--teal); }
/* Chromium hides a number input's spin buttons until it's hovered/focused
   by default -- both the diamonds and IQD fields already behaved
   identically, but that made whichever field wasn't currently focused look
   like it had no stepper control at all. Forcing full opacity keeps both
   visible at rest, consistently, without changing any other input site-wide. */
.custom-pkg-field input::-webkit-inner-spin-button,
.custom-pkg-field input::-webkit-outer-spin-button { opacity: 1; }
.pkg-card-custom .price-usd { margin-top: 10px; margin-bottom: 0; }
.pkg-card-custom .help-error { color: var(--danger); font-size: 0.78rem; margin-top: 8px; display: none; }
@media (max-width: 640px) {
  .pkg-card-custom { grid-column: span 2; }
}
.pkg-card.selected { border-color: var(--gold); box-shadow: 0 0 0 3px var(--gold-soft), var(--shadow-lg); }

/* ---------- legal content (terms / privacy / security) ---------- */
.legal-content { max-width: 820px; margin: 0 auto; background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); padding: 36px 40px; }
.legal-content .updated-note { color: var(--ink-faint); font-size: 0.82rem; margin-bottom: 28px; }
.legal-content h2 { font-size: 1.1rem; margin: 30px 0 10px; color: var(--ink); }
.legal-content h2:first-of-type { margin-top: 0; }
.legal-content p { color: var(--ink-dim); font-size: 0.95rem; line-height: 1.9; margin-bottom: 12px; }
.legal-content ul { margin: 0 0 12px; padding-inline-start: 22px; color: var(--ink-dim); font-size: 0.95rem; line-height: 1.9; }
.legal-content ul li { margin-bottom: 6px; }
.legal-content strong { color: var(--ink); }
@media (max-width: 640px) {
  .legal-content { padding: 24px 20px; }
}

/* ---------- steps ---------- */
.steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; }
.step { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); padding: 26px 22px; box-shadow: var(--shadow); }
.step .n { width: 46px; height: 46px; border-radius: 13px; background: linear-gradient(155deg, var(--teal), var(--teal-deep)); color: #fff; font-family: 'Cairo Display', sans-serif; font-size: 1.15rem; display: grid; place-items: center; margin-bottom: 16px; box-shadow: 0 10px 20px -8px rgba(20,184,162,0.6); }
.step h3 { font-size: 1.05rem; margin-bottom: 8px; }
.step p { color: var(--ink-dim); font-size: 0.92rem; }

/* ---------- payments ---------- */
.pay-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
/* Three-tier interaction hierarchy: neutral (unselected) -> hover (clickable
   affordance) -> selected (unmistakable, settled -- no residual lift, so it
   never looks like it's still mid-hover). Rendered as real <button> elements
   (see checkout.html#renderMethods) so focus/keyboard activation come from
   the browser for free instead of hand-rolled keydown handling. */
.pay-card {
  background: var(--card); border: 1.5px solid var(--border); border-radius: 16px;
  padding: 18px; display: flex; align-items: center; gap: 12px; box-shadow: var(--shadow);
  position: relative; width: 100%; margin: 0; font: inherit; color: inherit; text-align: start;
  transition: border-color 0.2s ease, background-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}
.pay-card.active { cursor: pointer; }
.pay-card.active:hover {
  border-color: var(--teal); background: var(--paper-2); transform: translateY(-2px);
  box-shadow: 0 12px 26px -14px rgba(212,175,55,0.4), var(--shadow);
}
.pay-card.active:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }
.pay-card.selected { border-color: var(--teal); background: var(--teal-soft); box-shadow: 0 0 0 3px var(--teal-soft), var(--shadow); }
.pay-card.selected:hover { transform: none; }
.pay-card.soon { opacity: 0.55; filter: grayscale(0.4); }
/* Named distinctly from the pre-existing .pay-check (the static informational
   badge used on payments.html/home.html) -- same-looking name, unrelated
   purpose, and colliding rules previously fought over left/right and size. */
.pay-select-check {
  position: absolute; top: 10px; inset-inline-end: 10px; width: 22px; height: 22px; border-radius: 50%;
  background: var(--teal); color: #fff; display: flex; align-items: center; justify-content: center;
  opacity: 0; transform: scale(0.5); transition: opacity 0.18s ease, transform 0.18s ease; pointer-events: none;
}
.pay-select-check svg { width: 13px; height: 13px; }
.pay-card.selected .pay-select-check { opacity: 1; transform: scale(1); }
.pay-badge { width: 46px; height: 46px; border-radius: 12px; flex: none; display: grid; place-items: center; font-family: 'Cairo Display', sans-serif; font-weight: 800; font-size: 0.95rem; color: #fff; overflow: hidden; }
.pay-badge img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pay-card .name { font-weight: 700; font-size: 0.92rem; }
.pay-card .stat { font-size: 0.74rem; margin-top: 2px; }
.pay-card.active .stat { color: var(--good); font-weight: 700; }
.pay-card.soon .stat { color: var(--ink-faint); font-weight: 700; }
.pay-check { position: absolute; top: 10px; left: 10px; width: 18px; height: 18px; }
.pay-check svg { width: 100%; height: 100%; stroke: var(--good); }
/* AsiaCell/Zain Iraq cards link to their top-up bundle shop instead of being
   purely informational — neutralize the anchor's default look and add a
   trailing chevron so it reads as navigable. */
.pay-card-link { text-decoration: none; color: inherit; transition: transform 0.15s ease, box-shadow 0.15s ease; }
.pay-card-link:hover { transform: translateY(-2px); box-shadow: 0 14px 28px -14px rgba(212,175,55,0.45), var(--shadow); }
.pay-card-arrow { width: 18px; height: 18px; flex: none; stroke: var(--teal-deep); margin-inline-start: auto; }
html[dir="rtl"] .pay-card-arrow { transform: scaleX(-1); }

/* ---------- trust band ----------
   Replaces the old numeric stats band (10,000+ orders / 400+ customers /
   4.9-5 rating): this is a genuinely new site with no verified order,
   customer, or review volume to report, so the section states real,
   qualitative product facts instead of a fabricated hero-metric. Plain,
   no card chrome, sitting directly on the section background per DESIGN.md's
   "Stats" doc -- these are informational, not actionable, so icons use the
   same neutral translucent-white chip language as the footer contact icons
   rather than spending the brand's one actionable color (gold) on four
   decorative marks in a row. */
.trust-band { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-4); }
.trust-item { display: flex; align-items: flex-start; gap: 16px; text-align: start; }
.trust-item-icon {
  width: 44px; height: 44px; border-radius: 12px; flex: none;
  background: rgba(255,255,255,0.06); border: 1px solid var(--border);
  display: grid; place-items: center;
}
.trust-item-icon svg { width: 20px; height: 20px; stroke: var(--ink-dim); }
.trust-item b { display: block; font-family: 'Cairo Display', sans-serif; font-weight: 700; font-size: 0.98rem; color: var(--ink); }
.trust-item span { display: block; font-size: 0.85rem; color: var(--ink-faint); margin-top: 4px; line-height: 1.5; }

/* ---------- testimonial ---------- */
.testi-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; max-width: 1080px; margin: 0 auto; }
@media (max-width: 900px) { .testi-grid { grid-template-columns: 1fr; } }
.testi { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); padding: 30px; box-shadow: var(--shadow); text-align: center; }
.testi .stars { color: var(--gold); font-size: 1.1rem; letter-spacing: 3px; margin-bottom: 16px; }
.testi p.quote { font-size: 0.98rem; color: var(--ink); }
.testi .who { margin-top: 20px; display: flex; align-items: center; justify-content: center; gap: 10px; }
.testi .who .av { width: 40px; height: 40px; border-radius: 50%; background: linear-gradient(155deg,var(--teal),var(--teal-deep)); }
.testi .who b { display: block; font-size: 0.9rem; }
.testi .who span { color: var(--ink-dim); font-size: 0.78rem; }

/* ---------- faq ---------- */
.faq { max-width: 760px; margin: 0 auto; display: flex; flex-direction: column; gap: 12px; }
.faq details { background: var(--card); border: 1px solid var(--border); border-radius: 14px; padding: 18px 20px; box-shadow: var(--shadow); }
.faq summary { cursor: pointer; list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 12px; font-weight: 700; font-size: 0.98rem; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary .chev { transition: transform 0.25s ease; flex: none; }
.faq summary .chev svg { width: 18px; height: 18px; stroke: var(--teal-deep); }
.faq details[open] summary .chev { transform: rotate(180deg); }
.faq .a { color: var(--ink-dim); font-size: 0.92rem; margin-top: 12px; line-height: 1.8; }

/* ---------- cta band ---------- */
.cta-band { background: linear-gradient(135deg, var(--teal-deep), var(--teal) 60%, #23d8bd); border-radius: 28px; padding: 52px 40px; text-align: center; color: #fff; position: relative; overflow: hidden; }
.cta-band h2 { color: #fff; font-size: clamp(1.5rem, 3vw, 2rem); }
.cta-band p { color: rgba(255,255,255,0.88); margin-top: 10px; }
.cta-band .hero-cta { justify-content: center; margin-top: 26px; }
.cta-band .btn-ghost-light { background: rgba(255,255,255,0.16); }

/* ---------- reusable two-column split (contact, checkout, etc.) ---------- */
.split-grid { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: 32px; align-items: start; }
@media (max-width: 900px) {
  .split-grid { grid-template-columns: 1fr; gap: 16px; }
}

/* ---------- cards / forms (checkout, auth) ---------- */
.panel { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); padding: 30px; }
.form-label-bj { font-weight: 700; font-size: 0.88rem; margin-bottom: 6px; display: block; }
.form-control-bj {
  width: 100%; border: 1.5px solid var(--border); border-radius: 12px; padding: 12px 14px;
  font-family: inherit; font-size: 0.96rem; background: var(--paper); color: var(--ink);
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.form-control-bj:focus { outline: none; border-color: var(--teal); box-shadow: 0 0 0 3px var(--teal-soft); }
.field { margin-bottom: 18px; }
.help-text { color: var(--ink-dim); font-size: 0.8rem; margin-top: 6px; }
/* A quiet, honest reassurance line -- what's actually true (a real
   supplier API, real manual review), never an invented certification.
   Plain text on the panel's own background: this sits inside a form, so
   no glass (DESIGN.md "Never-Blur-Data Rule"). */
.trust-line { display: flex; align-items: flex-start; gap: 8px; margin-top: 10px; font-size: 0.82rem; color: var(--ink-dim); line-height: 1.6; }
.trust-line .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--good); margin-top: 6px; flex: none; }
.alert-bj { border-radius: 12px; padding: 12px 16px; font-size: 0.9rem; font-weight: 700; margin-bottom: 18px; display: none; }
.alert-bj.show { display: block; }
.alert-danger-bj { background: rgba(229,72,77,0.1); color: var(--danger); border: 1px solid rgba(229,72,77,0.25); }
.alert-success-bj { background: rgba(26,156,107,0.1); color: var(--good); border: 1px solid rgba(26,156,107,0.25); }

.status-pill { display: inline-flex; align-items: center; gap: 6px; font-size: 0.78rem; font-weight: 700; padding: 5px 12px; border-radius: 100px; }
.status-pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.status-pending_payment { background: rgba(147,161,186,0.16); color: var(--ink-dim); }
.status-awaiting_review { background: var(--warning-soft); color: var(--warning); }
.status-processing { background: var(--info-soft); color: var(--info); }
.status-paid { background: rgba(26,156,107,0.14); color: var(--good); }
.status-completed { background: rgba(18,183,106,0.12); color: var(--good-bright); }
.status-failed, .status-cancelled, .status-expired { background: rgba(229,72,77,0.12); color: var(--danger); }
.status-refund_required { background: rgba(139,92,246,0.14); color: var(--refund); }
.status-test { background: var(--info-soft); color: var(--info); }

/* Admin packages-list bonus column: compact, unambiguous 3-state tag (a
   concrete "+X 💎" manual figure needs no tag of its own -- only the two
   non-numeric states, none vs automatic, need a visual label so they're
   never confused with each other in the table). */
.pkg-bonus-mode-tag { display: inline-flex; align-items: center; font-size: 0.72rem; font-weight: 700; padding: 3px 10px; border-radius: 100px; }
.pkg-bonus-mode-tag--none { background: rgba(147,161,186,0.16); color: var(--ink-dim); }
.pkg-bonus-mode-tag--auto { background: var(--info-soft); color: var(--info); }

/* Transaction diagnostics categories -- reuse the same .status-pill base and
   the same functional-palette colors above (never Gold: a diagnostic states
   a fact about the order, not an invitation to click it, per DESIGN.md's
   status-pill rule). bigoiraq_system_issue reuses status-refund_required's
   violet since it's frequently the same underlying order state. */
.diag-customer_action_required { background: var(--warning-soft); color: var(--warning); }
.diag-payment_provider_issue { background: var(--info-soft); color: var(--info); }
.diag-bigoiraq_system_issue { background: rgba(139,92,246,0.14); color: var(--refund); }
.diag-needs_manual_review { background: rgba(147,161,186,0.16); color: var(--ink-dim); }

.diag-sublabel { display: block; font-size: 0.7rem; font-weight: 600; margin-top: 3px; }
.diag-sublabel.diag-customer_action_required { color: var(--warning); background: none; padding: 0; }
.diag-sublabel.diag-payment_provider_issue { color: var(--info); background: none; padding: 0; }
.diag-sublabel.diag-bigoiraq_system_issue { color: var(--refund); background: none; padding: 0; }
.diag-sublabel.diag-needs_manual_review { color: var(--ink-dim); background: none; padding: 0; }

.diag-stepper { display: flex; flex-wrap: wrap; gap: 4px 10px; margin-top: 8px; }
.diag-step { display: flex; align-items: center; gap: 5px; font-size: 0.72rem; color: var(--ink-dim); }
.diag-step::before { content: ""; width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; background: rgba(147,161,186,0.35); }
.diag-step.diag-step--completed::before { background: var(--good); }
.diag-step.diag-step--waiting::before { background: var(--warning); }
.diag-step.diag-step--failed::before { background: var(--danger); }
.diag-step.diag-step--requires_manual_action::before { background: var(--refund); }
.diag-step.diag-step--not_reached { opacity: 0.4; }

/* ---------- footer ---------- */
footer.site { background: var(--navy); color: rgba(255,255,255,0.65); padding: 64px 0 26px; margin-top: 90px; }
.foot-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1.2fr; gap: 40px; padding-bottom: 40px; border-bottom: 1px solid rgba(255,255,255,0.1); }
.foot-brand p { margin-top: var(--space-2); font-size: 0.88rem; max-width: 32ch; color: rgba(255,255,255,0.5); }
/* Empty (no enabled platforms) collapses to zero height instead of leaving
   a bare margin-top gap with nothing in it -- :empty is reliable here since
   bjApplyFooterContact() only ever fills this via innerHTML, never leaves
   whitespace text nodes. */
.foot-social { display: flex; gap: 8px; margin-top: var(--space-3); }
.foot-social:empty { margin-top: 0; }
.foot-social a { width: 36px; height: 36px; border-radius: 10px; background: rgba(255,255,255,0.08); display: grid; place-items: center; transition: background 0.15s ease; }
.foot-social a:hover { background: rgba(255,255,255,0.16); }
.foot-social a svg { width: 16px; height: 16px; stroke: #fff; }
.foot-col h4 { color: #fff; font-size: 0.95rem; margin-bottom: var(--space-2); }
.foot-col a, .foot-col p { display: block; font-size: 0.88rem; color: rgba(255,255,255,0.55); margin-bottom: var(--space-2); }
.foot-col a:hover { color: var(--gold); }
.foot-col p:last-child, .foot-col a:last-child { margin-bottom: 0; }

/* Contact column: each number reads as an icon+label chip rather than a
   plain text line, with the WhatsApp entry visually distinguished (its own
   brand-green icon box) as the primary contact channel, per DESIGN.md's
   "one primary action stands out" rule applied to a links-only context. */
.foot-contact-list { display: flex; flex-direction: column; gap: var(--space-2); margin-bottom: var(--space-2); }
.foot-col--contact .foot-contact-item {
  display: flex; align-items: center; gap: 10px; margin-bottom: 0; color: rgba(255,255,255,0.85);
}
.foot-contact-item__icon {
  width: 34px; height: 34px; flex: none; border-radius: 10px; display: grid; place-items: center;
  background: rgba(255,255,255,0.08);
}
.foot-contact-item__icon svg { width: 16px; height: 16px; stroke: rgba(255,255,255,0.85); }
.foot-col--contact .foot-contact-item--whatsapp { color: #fff; }
.foot-contact-item--whatsapp .foot-contact-item__icon { background: rgba(37,211,102,0.18); }
.foot-contact-item--whatsapp .foot-contact-item__icon svg { stroke: #25d366; }
.foot-contact-item--whatsapp:hover .foot-contact-item__icon { background: rgba(37,211,102,0.3); }
.foot-contact-item__label { display: block; font-size: 0.72rem; color: rgba(255,255,255,0.5); }
.foot-contact-item__value { display: block; font-size: 0.88rem; font-weight: 700; }

.foot-pay-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: var(--space-3) 0; border-bottom: 1px solid rgba(255,255,255,0.1); }
.foot-pay-label { font-size: 0.78rem; color: rgba(255,255,255,0.5); font-weight: 700; flex: none; }
.foot-pay { display: flex; flex-wrap: wrap; gap: 8px; }
.foot-pay span { background: rgba(255,255,255,0.08); border-radius: 8px; padding: 5px 9px; font-size: 0.68rem; font-weight: 700; white-space: nowrap; }
.foot-bottom { display: flex; align-items: center; justify-content: space-between; padding-top: var(--space-3); font-size: 0.8rem; flex-wrap: wrap; gap: 10px; }
.foot-bottom .jo { display:flex; align-items:center; gap:8px; }
.foot-bottom .flag { width: 22px; height: 15px; border-radius: 3px; overflow:hidden; display:flex; flex-direction:column; flex: none; }
.foot-bottom .flag i { flex:1; display:block; }

/* ---------- whatsapp floating button ---------- */
/* Explicit per-language business rule, not derived from RTL/LTR direction:
   Arabic and Kurdish -> left, English -> right. Deliberately overrides an
   earlier revision of this project that fixed the button at bottom-right for
   every language; that decision is being reversed on purpose here. Uses the
   native <html lang> attribute (set by bjApplyLang() in i18n.js on every
   language change, including a same-page switch with no reload) rather than
   a second language-state mechanism or repeated inline-style JS. */
.wa-float {
  position: fixed; bottom: 22px; right: 22px; z-index: 50;
  width: 56px; height: 56px; border-radius: 50%;
  background: linear-gradient(155deg,#28d16b,#1fa856);
  display: grid; place-items: center;
  box-shadow: 0 14px 28px -10px rgba(31,168,86,0.6);
}
html[lang="ar"] .wa-float,
html[lang="ku"] .wa-float {
  right: auto; left: 22px;
}
.wa-float svg { width: 26px; height: 26px; stroke: #fff; }

/* ---------- responsive ---------- */
/* 1024px, not 1020px: 1024px (iPad landscape, and one of the most common
   tablet-landscape/small-laptop widths) is an explicit required test width,
   and max-width is inclusive -- a 1020px cutoff missed it by 4px, so a
   1024px-wide visitor got the full desktop header (all nav links, language
   select, account name, logout icon, CTA) crammed into the same 1024px this
   tier is meant to simplify, instead of the burger/icon treatment below.
   Verified via Playwright: at 1024px this previously rendered nav.links
   visible / .burger hidden; after this fix both flip to the mobile state. */
@media (max-width: 1024px) {
  nav.links { display: none; }
  .burger { display: flex; }
  #bj-auth-link, #bj-logout-btn { display: none !important; }
  /* Mobile navbar: no language toggle (still in the sidebar menu), CTA
     shrinks to icon-only, and a dedicated account icon appears by the burger.
     All three icon buttons share one exact size/centering rule so nothing
     ever looks off-center or unevenly sized next to the others. 44px, not
     42px: DESIGN.md's "every interactive control gets a 44px minimum tap
     target" rule, applied literally -- these three are the only controls
     left in the mobile navbar, so they're exactly where it matters most. */
  .nav-actions .lang-menu { display: none !important; }
  #bj-nav-cta-label { display: none; }
  #bj-nav-cta,
  #bj-mobile-account-link,
  .burger {
    width: 44px; height: 44px; padding: 0; flex: none;
    display: flex; align-items: center; justify-content: center;
  }
  #bj-nav-cta svg,
  #bj-mobile-account-link svg,
  .burger svg {
    display: block; flex: none;
  }
  #bj-mobile-account-link { display: flex !important; }
  .pkg-scroller { grid-template-columns: repeat(3, 1fr); }
  .steps { grid-template-columns: repeat(2, 1fr); }
  .pay-grid { grid-template-columns: repeat(2, 1fr); }
  .trust-band { grid-template-columns: repeat(2, 1fr); }
  .foot-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 640px) {
  .nav-row { gap: 10px; padding-top: 26px; padding-bottom: 26px; }
  /* The brand wordmark shrinks/truncates before it ever pushes the nav
     icons (CTA/account/burger) toward — or past — the edge. This fits
     correctly on any phone width instead of relying on a pixel budget
     that only works for some screen sizes. */
  .brand { font-size: 1.05rem; gap: 8px; min-width: 0; flex-shrink: 1; }
  .brand .mark { width: 32px; height: 32px; }
  .brand > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
  .brand small { display: none; }
  .nav-actions { flex: none; gap: 8px; }
  section.pad { padding: 60px 0; }
  .pkg-scroller { grid-template-columns: repeat(2, 1fr); }
  .steps { grid-template-columns: 1fr; }
  .pay-grid { grid-template-columns: 1fr; }
  .trust-band { grid-template-columns: 1fr; gap: var(--space-3); }
  /* Root cause of the old "excessive empty space" complaint: footer.site's
     64px/90px desktop padding-top/margin-top and .foot-grid's 40px column
     gap were never reduced for mobile, so a single stacked column carried
     three full desktop-sized 40px gaps between short blocks (4 links, 3
     links, a contact card) that read as dead air on a narrow screen. Scaled
     down one/two steps on the 8px scale rather than blindly shrunk. */
  footer.site { padding: var(--space-6) 0 var(--space-3); margin-top: var(--space-7); }
  .foot-grid { grid-template-columns: 1fr; gap: var(--space-4); padding-bottom: var(--space-4); }
  .foot-pay-row { flex-direction: column; align-items: flex-start; gap: var(--space-2); }
  .foot-bottom { flex-direction: column; align-items: flex-start; }
  /* .hero and .hero-cta mobile rules live with the rest of the hero, above --
     a second, later-cascading .hero padding shorthand here previously
     cancelled that block's padding-top, the same bug class as the nav-row
     fix earlier: the flag's own height pushes the copy down on mobile, and
     a shorthand landing after it in source order silently wins the cascade. */
  .panel { padding: 22px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .live-pill .dot { animation: none; }
  /* The universal selector does not implicitly reach pseudo-elements per the
     CSS spec -- *::before/*::after must be named explicitly, or a
     ::after-only animation (the full-page loader's gleam) keeps running at
     full speed under reduced-motion despite this rule appearing to cover
     "every animation, everywhere". Found and fixed during the loading-system
     visual redesign's audit -- every other animation in this file lives on a
     real element and was already covered; the gleam was the first to live
     purely on a pseudo-element. */
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

.reveal { opacity: 0; transform: translateY(18px); transition: opacity 0.6s ease, transform 0.6s ease; }
.reveal.in { opacity: 1; transform: translateY(0); }

/* =====================================================================
   Admin panel (admin.bigoiraq.com)
   ===================================================================== */
.admin-shell { display: grid; grid-template-columns: 240px 1fr; min-height: 100vh; }
.admin-sidebar { background: var(--navy); color: rgba(255,255,255,0.72); padding: 22px 16px; display: flex; flex-direction: column; gap: 4px; }
.admin-sidebar .brand { margin-bottom: 26px; padding: 0 6px; }
.admin-nav a { display: flex; align-items: center; gap: 10px; padding: 11px 12px; border-radius: 10px; font-size: 0.92rem; font-weight: 700; color: rgba(255,255,255,0.7); }
.admin-nav a svg { width: 17px; height: 17px; flex: none; }
.admin-nav a:hover { background: rgba(255,255,255,0.06); color: #fff; }
/* Active state reads through a gold accent bar, not gold text/background on
   every row — gold stays the rare actionable color (see DESIGN.md) even in
   a 14-item nav list where it would otherwise appear on nearly every screen. */
.admin-nav a.active { background: rgba(255,255,255,0.07); color: #fff; border-inline-start: 3px solid var(--gold); padding-inline-start: 9px; }
.admin-sidebar .spacer { flex: 1; }
.admin-logout { margin-top: auto; }
.admin-main { background: var(--paper); padding-block: 26px 60px; padding-inline: clamp(16px, 4vw, 32px); overflow-x: hidden; }
.admin-topbar {
  display: flex; align-items: center; justify-content: space-between;
  position: sticky; top: 0; z-index: 45; padding: 14px 0; margin-bottom: 24px;
  background: rgba(14,14,16,0.6); -webkit-backdrop-filter: blur(20px) saturate(1.4); backdrop-filter: blur(20px) saturate(1.4);
  border-bottom: 1px solid rgba(255,255,255,0.08); transition: background 200ms ease, box-shadow 200ms ease;
}
.admin-topbar.scrolled { background: rgba(14,14,16,0.9); box-shadow: 0 12px 30px -20px rgba(0,0,0,0.9); }
.admin-topbar h1 { font-size: 1.4rem; }
.admin-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 28px; }
.kpi-card { background: var(--card); border: 1px solid var(--border); border-radius: 16px; padding: 18px 20px; box-shadow: var(--shadow); }
.kpi-card .lbl { color: var(--ink-dim); font-size: 0.8rem; font-weight: 700; }
.kpi-card .val { font-family: 'Cairo Display', sans-serif; font-size: 1.7rem; margin-top: 6px; }
.admin-card { background: var(--card); border: 1px solid var(--border); border-radius: 16px; box-shadow: var(--shadow); padding: 22px; margin-bottom: 22px; }
.admin-card-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; flex-wrap: wrap; gap: 10px; }
.admin-table { width: 100%; border-collapse: collapse; font-size: 0.88rem; }
.admin-table th { text-align: start; color: var(--ink-dim); font-weight: 700; padding: 10px 8px; border-bottom: 1px solid var(--border); white-space: nowrap; }
.admin-table td { padding: 12px 8px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.admin-table tr:last-child td { border-bottom: none; }
.admin-table-wrap { overflow-x: auto; }
/* Skeleton rows (adminSkeletonRows()) drop into the same tbody a real row
   would occupy, matching column count, so the table shape never jumps once
   real data replaces them. */
.admin-table .skeleton-row td { height: 20px; }
.admin-table .skeleton-row .skeleton-text { height: 0.8em; }
.admin-table-error td { color: var(--ink-dim); }
.admin-table-error .btn { margin-inline-start: 10px; }

/* Per-row primary action + overflow menu (Customers table) -- one visible
   gold action plus a kebab for secondary/infrequent actions, instead of a
   row of competing buttons. .row-menu-panel is positioned via JS-computed
   fixed coordinates, not absolute-within-.row-menu -- see the comment at
   its toggle handler for why (.admin-table-wrap's overflow-x:auto forces
   overflow-y to auto too, which would clip an absolutely-positioned panel
   for rows near the bottom of a long table). */
.row-actions { display: flex; align-items: center; gap: 8px; }
.row-menu-btn {
  width: 32px; height: 32px; flex: none; display: grid; place-items: center; border-radius: 8px;
  background: transparent; border: 1.5px solid var(--border); color: var(--ink-dim); cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.row-menu-btn:hover, .row-menu-btn[aria-expanded="true"] { background: var(--paper-2); border-color: var(--border-strong); color: var(--ink); }
.row-menu-panel {
  position: fixed; z-index: 300; min-width: 190px;
  background: var(--card); border: 1px solid var(--border); border-radius: 12px; box-shadow: var(--shadow-lg);
  padding: 6px; display: flex; flex-direction: column; gap: 2px;
}
.row-menu-item {
  display: block; width: 100%; text-align: start; background: transparent; border: none; border-radius: 8px;
  padding: 9px 10px; font-family: inherit; font-size: 0.85rem; font-weight: 700; color: var(--ink); cursor: pointer;
  min-height: 38px;
}
.row-menu-item:hover { background: var(--paper-2); }
.row-menu-item--danger { color: var(--danger); }
.row-menu-item--danger:hover { background: rgba(229,72,77,0.1); }
.btn-xs { padding: 6px 12px; font-size: 0.78rem; border-radius: 8px; }
/* Email Notifications (الإعدادات → إشعارات البريد). Structure mirrors
   priority, not a shelf of same-weight cards: status (is it on) stands
   alone and reads at a glance; recipients/sender/subject/body live inside
   one configuration card, internally sectioned; preview/test are grouped
   as a distinct "try it" card; logs sit last, as history. */
.en-page-head { margin-bottom: var(--space-3); }
.en-page-head h2 { font-size: 1.15rem; margin-bottom: 4px; }

.en-status-card { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.en-status-card__info h3 { font-size: 1rem; margin-bottom: 4px; }

/* A real switch (track + thumb), not a bare checkbox -- state is also
   spelled out in text next to it so it never depends on color alone. */
.en-toggle { display: flex; align-items: center; gap: 10px; cursor: pointer; flex: none; }
.en-toggle input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.en-toggle__track {
  width: 44px; height: 26px; border-radius: 100px; background: var(--border-strong);
  position: relative; transition: background 0.18s ease; flex: none;
}
.en-toggle__thumb {
  position: absolute; top: 3px; inset-inline-start: 3px; width: 20px; height: 20px; border-radius: 50%;
  background: var(--ink-faint); transition: transform 0.18s ease, background 0.18s ease;
}
.en-toggle input:checked ~ .en-toggle__track { background: rgba(18,183,106,0.35); }
.en-toggle input:checked ~ .en-toggle__track .en-toggle__thumb { transform: translateX(18px); background: var(--good-bright); }
html[dir="rtl"] .en-toggle input:checked ~ .en-toggle__track .en-toggle__thumb { transform: translateX(-18px); }
.en-toggle input:focus-visible ~ .en-toggle__track { outline: 2px solid var(--gold); outline-offset: 2px; }
.en-toggle__label { font-size: 0.88rem; font-weight: 700; min-width: 42px; }

.en-unsaved-badge { background: var(--warning-soft); color: var(--warning); font-size: 0.78rem; font-weight: 700; padding: 5px 12px; border-radius: 100px; }

.en-config-grid { display: grid; grid-template-columns: 1fr 260px; gap: 28px; align-items: start; margin-top: 16px; }
.en-config-main { display: flex; flex-direction: column; gap: 22px; }
.en-subsection label.form-label-bj { margin-bottom: 4px; }
.en-subsection > .help-text { margin-bottom: 8px; }
.en-body-editor { font-family: monospace; font-size: 0.82rem; direction: ltr; }

.en-recipients { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; min-height: 32px; }
.en-recipients-empty { margin: 0; }
.en-chip {
  display: inline-flex; align-items: center; gap: 6px; background: var(--paper-2); border: 1px solid var(--border);
  border-radius: 100px; padding: 5px 6px 5px 12px; font-size: 0.85rem; color: var(--ink);
}
html[dir="rtl"] .en-chip { padding: 5px 12px 5px 6px; }
.en-chip__remove {
  background: rgba(255,255,255,0.06); border: none; border-radius: 50%; width: 18px; height: 18px; flex: none;
  color: var(--ink-dim); font-size: 0.95rem; line-height: 1; cursor: pointer; display: grid; place-items: center;
}
.en-chip__remove:hover { background: rgba(229,72,77,0.18); color: var(--danger); }
.en-recipient-add { display: flex; gap: 8px; }
.en-recipient-add .form-control-bj { flex: 1; }
.en-field-error { color: var(--danger); font-size: 0.8rem; margin-top: 6px; }
.en-field-error--ok { color: var(--good-bright); }

.en-config-side {
  background: var(--paper-2); border: 1px solid var(--border); border-radius: 10px; padding: 14px;
  position: sticky; top: 80px;
}
.en-config-side h4 { font-size: 0.88rem; margin-bottom: 4px; }
.en-config-side > .help-text { margin-bottom: 10px; }
.en-var-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 7px 0; border-bottom: 1px solid var(--border); }
.en-var-row:last-child { border-bottom: none; }
.en-var-row code { font-size: 0.78rem; color: var(--teal-deep); direction: ltr; }
.en-var-row .label { font-size: 0.72rem; color: var(--ink-dim); display: block; margin-top: 2px; }
.en-var-copy { background: transparent; border: 1px solid var(--border); border-radius: 6px; padding: 3px 8px; font-size: 0.7rem; cursor: pointer; flex: none; }
.en-var-copy:hover { background: var(--paper); }

.en-save-row { display: flex; align-items: center; gap: 12px; margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--border); flex-wrap: wrap; }
.en-save-feedback { font-size: 0.85rem; color: var(--ink-dim); }
.en-save-feedback--ok { color: var(--good-bright); }
.en-save-feedback--error { color: var(--danger); }

.en-tools-card { display: grid; grid-template-columns: 1fr 1px 1fr; gap: 24px; align-items: start; }
.en-tools-card__col h4 { font-size: 0.95rem; margin-bottom: 4px; }
.en-tools-card__col > .help-text { margin-bottom: 12px; }
.en-tools-card__divider { background: var(--border); align-self: stretch; }
.en-test-row { display: flex; gap: 8px; }
.en-test-row .form-control-bj { flex: 1; }

.en-preview-tag { font-size: 0.72rem; font-weight: 700; color: var(--warning); background: var(--warning-soft); padding: 3px 10px; border-radius: 100px; margin-inline-start: 8px; }
.en-preview-frame { width: 100%; min-height: 420px; border: 1px solid var(--border); border-radius: 10px; background: #fff; }

.en-log-error { max-width: 220px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 0.78rem; color: var(--ink-dim); cursor: default; }

.en-empty-state { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 6px; padding: 40px 20px; color: var(--ink-dim); }
.en-empty-state svg { width: 32px; height: 32px; stroke: var(--ink-faint); margin-bottom: 6px; }
.en-empty-state p { font-weight: 700; color: var(--ink); margin: 0; }
.en-empty-state .help-text { max-width: 36ch; }

@media (max-width: 900px) {
  .en-config-grid { grid-template-columns: 1fr; }
  .en-config-side { position: static; }
  .en-tools-card { grid-template-columns: 1fr; }
  .en-tools-card__divider { display: none; }
}

/* Contact & Social settings (الإعدادات → التواصل والدعم) -- one row per
   platform: label, URL input, enabled toggle. Wraps to a stacked layout
   below 640px so the toggle never competes for space with a long URL on a
   narrow admin-sidebar-drawer viewport. */
.cs-social-row {
  display: grid; grid-template-columns: 110px 1fr auto; align-items: center; gap: 12px;
  padding: 10px 0; border-bottom: 1px solid var(--border);
}
.cs-social-row:last-child { border-bottom: none; }
.cs-social-row__label { font-weight: 700; font-size: 0.88rem; }
.cs-social-row__toggle { display: flex; align-items: center; gap: 6px; font-size: 0.8rem; color: var(--ink-dim); white-space: nowrap; cursor: pointer; }
@media (max-width: 640px) {
  .cs-social-row { grid-template-columns: 1fr; gap: 6px; }
}
.filters-row { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 16px; }
.filters-row select, .filters-row input { border: 1.5px solid var(--border); border-radius: 10px; padding: 8px 12px; font-family: inherit; font-size: 0.86rem; background: var(--paper); color: var(--ink); }
.admin-login-wrap { min-height: 100vh; display: grid; place-items: center; background: linear-gradient(160deg, var(--navy), var(--navy-2)); padding: 24px; }
.badge-dot { display: inline-flex; align-items: center; gap: 6px; font-size: 0.72rem; font-weight: 700; padding: 3px 10px; border-radius: 100px; }
.admin-burger {
  display: none; width: 38px; height: 38px; border-radius: 10px; flex: none;
  background: var(--card); border: 1.5px solid var(--border); align-items: center; justify-content: center;
}
.admin-burger svg { width: 18px; height: 18px; stroke: var(--ink); }
.admin-sidebar-overlay { display: none; }
@media (max-width: 900px) {
  .admin-shell { grid-template-columns: 1fr; }
  .admin-burger { display: flex; }
  .admin-topbar h1 { font-size: 1.15rem; }
  .admin-main { padding-block: 18px 40px; }
  .admin-kpis { grid-template-columns: 1fr 1fr; gap: 12px; }
  .filters-row select, .filters-row input { flex: 1 1 100%; }
  .admin-sidebar {
    position: fixed; top: 0; right: 0; height: 100vh; height: 100dvh; width: min(280px, 82vw);
    transform: translateX(100%); transition: transform 0.3s ease; z-index: 210;
    overflow-y: auto; box-shadow: -20px 0 60px rgba(0,0,0,0.4);
  }
  .admin-sidebar.open { transform: translateX(0); }
  .admin-sidebar-overlay {
    display: block; position: fixed; inset: 0; background: rgba(6,13,30,0.6); z-index: 200;
    opacity: 0; pointer-events: none; transition: opacity 0.25s ease;
  }
  .admin-sidebar-overlay.open { opacity: 1; pointer-events: auto; }
}
@media (max-width: 480px) {
  .admin-kpis { grid-template-columns: 1fr; }
}

/* Orders tables (dashboard "recent orders" + the full Orders view) collapse
   into stacked cards at phone width instead of a horizontally-scrolling
   table -- scoped to these two tables by id, not .admin-table generally, so
   every other admin table (packages, staff, tiers, ...) keeps its existing
   scroll fallback untouched. Approve/decline still only happen from inside
   the order-details modal after the reviewer sees the proof image -- these
   cards carry no shortcut around that. */
.order-type-badge { display: inline-flex; align-items: center; font-size: 0.72rem; font-weight: 700; padding: 3px 10px; border-radius: 100px; white-space: nowrap; }
.order-type-badge--diamond { background: var(--info-soft); color: var(--info); }
.order-type-badge--topup { background: var(--gold-soft); color: var(--gold); }
.order-card { display: none; flex-direction: column; gap: 8px; padding: 4px 2px; }
.order-card__top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.order-card__id { font-family: 'Cairo Display', sans-serif; font-weight: 700; font-size: 0.85rem; color: var(--ink-faint); }
.order-card__meta { font-size: 0.8rem; color: var(--ink-muted); }
.order-card__row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.order-card__amount { font-family: 'Cairo Display', sans-serif; font-weight: 700; font-size: 0.98rem; color: var(--ink); }
.order-card__actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 2px; }
#recent-orders-table tr.row-mobile-card, #orders-table tr.row-mobile-card { display: none; }
@media (max-width: 640px) {
  #recent-orders-table thead, #orders-table thead,
  #recent-orders-table tr.row-desktop, #orders-table tr.row-desktop { display: none; }
  #recent-orders-table tr.row-mobile-card, #orders-table tr.row-mobile-card { display: table-row; }
  #recent-orders-table tr.row-mobile-card td, #orders-table tr.row-mobile-card td { padding: 14px 4px; border-bottom: 1px solid var(--border); }
  #recent-orders-table .order-card, #orders-table .order-card { display: flex; }
}

/* Sidebar nav badges (💎 Diamond Orders / 💰 Wallet Transactions pending-
   review counts) -- pushed to the far end of the nav row via margin-inline-
   start:auto so it reads correctly in both RTL and LTR without a direction
   check, small enough not to read as spam next to a 14-item nav list. */
.nav-badge {
  margin-inline-start: auto; flex: none; min-width: 20px; height: 20px; padding: 0 6px;
  border-radius: 100px; background: var(--gold); color: #1a1a1a; font-size: 0.72rem; font-weight: 800;
  display: flex; align-items: center; justify-content: center; font-family: 'Cairo Display', sans-serif;
}
.nav-badge[hidden] { display: none; }

/* Admin language selector -- a custom dropdown reusing the exact visual/
   behavioral language of .row-menu (see dashboard.html's row-actions menus)
   instead of a native <select>, since the customer site's own native-select
   switcher is precisely the "raw browser dropdown" look this was meant to
   move away from for the admin panel. */
.lang-menu { position: relative; }
.lang-menu-btn {
  display: flex; align-items: center; gap: 7px; padding: 8px 12px; border-radius: 10px;
  background: var(--paper-2); border: 1.5px solid var(--border); color: var(--ink); cursor: pointer;
  font-family: inherit; font-size: 0.85rem; font-weight: 700; transition: background 0.15s ease, border-color 0.15s ease;
}
.lang-menu-btn:hover { border-color: var(--border-strong); }
.lang-menu-btn:focus-visible, .lang-menu-btn[aria-expanded="true"] { outline: 2px solid var(--gold); outline-offset: 2px; }
.lang-menu-btn svg { flex: none; opacity: 0.6; transition: transform 0.15s ease; }
.lang-menu-btn[aria-expanded="true"] svg { transform: rotate(180deg); }
.lang-menu-panel {
  position: fixed; z-index: 300; min-width: 170px;
  background: var(--card); border: 1px solid var(--border); border-radius: 12px; box-shadow: var(--shadow-lg);
  padding: 6px; display: flex; flex-direction: column; gap: 2px;
}
.lang-menu-panel[hidden] { display: none; }
.lang-menu-item {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: start; background: transparent;
  border: none; border-radius: 8px; padding: 9px 10px; font-family: inherit; font-size: 0.85rem; font-weight: 700;
  color: var(--ink); cursor: pointer; min-height: 38px;
}
.lang-menu-item:hover { background: var(--paper-2); }
.lang-menu-item.is-active { color: var(--gold); }
.lang-menu-item__flag { flex: none; font-size: 1rem; width: 1.2em; text-align: center; }
.lang-menu-item__check { flex: none; margin-inline-start: auto; opacity: 0; }
.lang-menu-item.is-active .lang-menu-item__check { opacity: 1; }
@media (max-width: 480px) {
  .lang-menu-btn { padding: 8px 9px; gap: 5px; font-size: 0.78rem; }
}
