/* ==========================================================================
   Default theme — CORE sheet. FUNCTIONAL CSS — if it breaks, the app breaks:
     · CSS reset + base body
     · responsive grid (.row / .col-*)
     · AJAX loading overlay
     · new / mass-order field show / hide / mask rules (below)
   layout.twig loads this AFTER style.css (last) so these rules always win.
   WARNING: to restyle the look, edit style.css + colors/<scheme>.css — not this file.
   Colours come from colors/<scheme>.css.
   Developed by Bilal & the HQ Team.
   ========================================================================== */

/* ---------- Base ---------- */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
body {
  font-family:
    "Helvetica Neue",
    Arial,
    system-ui,
    -apple-system,
    "Segoe UI",
    sans-serif;
  background: var(--c-bg);
  color: var(--c-text);
  font-size: 14px;
  line-height: 1.5;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  -webkit-font-smoothing: antialiased;
}
img {
  max-width: 100%;
}
a {
  color: var(--c-primary);
  text-decoration: none;
}
a:hover {
  color: var(--c-primary-dark);
}

/* ---------- Grid: centered rows + responsive columns ----------
   Use like Bootstrap:  <div class="row"><div class="col-12 col-md-8 col-lg-5">…
   Change the col-* classes to resize a block — no per-page CSS needed. */
.row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  width: 100%;
  max-width: 1140px;
  margin: 0 auto;
}
/* For wide tables (orders, services). Wider than .row's 1140 so the columns get
   room, but still capped — edge to edge on a big monitor was too much. Below
   1600 there is nothing to cap, so those screens are already full width. */
.row-wide {
  max-width: 1600px;
}
[class*="col-"] {
  width: 100%;
}
.col-1 {
  width: 8.3333%;
}
.col-2 {
  width: 16.6667%;
}
.col-3 {
  width: 25%;
}
.col-4 {
  width: 33.3333%;
}
.col-5 {
  width: 41.6667%;
}
.col-6 {
  width: 50%;
}
.col-7 {
  width: 58.3333%;
}
.col-8 {
  width: 66.6667%;
}
.col-9 {
  width: 75%;
}
.col-10 {
  width: 83.3333%;
}
.col-11 {
  width: 91.6667%;
}
.col-12 {
  width: 100%;
}
@media (min-width: 576px) {
  .col-sm-1 {
    width: 8.3333%;
  }
  .col-sm-2 {
    width: 16.6667%;
  }
  .col-sm-3 {
    width: 25%;
  }
  .col-sm-4 {
    width: 33.3333%;
  }
  .col-sm-5 {
    width: 41.6667%;
  }
  .col-sm-6 {
    width: 50%;
  }
  .col-sm-7 {
    width: 58.3333%;
  }
  .col-sm-8 {
    width: 66.6667%;
  }
  .col-sm-9 {
    width: 75%;
  }
  .col-sm-10 {
    width: 83.3333%;
  }
  .col-sm-11 {
    width: 91.6667%;
  }
  .col-sm-12 {
    width: 100%;
  }
}
@media (min-width: 768px) {
  .col-md-1 {
    width: 8.3333%;
  }
  .col-md-2 {
    width: 16.6667%;
  }
  .col-md-3 {
    width: 25%;
  }
  .col-md-4 {
    width: 33.3333%;
  }
  .col-md-5 {
    width: 41.6667%;
  }
  .col-md-6 {
    width: 50%;
  }
  .col-md-7 {
    width: 58.3333%;
  }
  .col-md-8 {
    width: 66.6667%;
  }
  .col-md-9 {
    width: 75%;
  }
  .col-md-10 {
    width: 83.3333%;
  }
  .col-md-11 {
    width: 91.6667%;
  }
  .col-md-12 {
    width: 100%;
  }
}
@media (min-width: 992px) {
  .col-lg-1 {
    width: 8.3333%;
  }
  .col-lg-2 {
    width: 16.6667%;
  }
  .col-lg-3 {
    width: 25%;
  }
  .col-lg-4 {
    width: 33.3333%;
  }
  .col-lg-5 {
    width: 41.6667%;
  }
  .col-lg-6 {
    width: 50%;
  }
  .col-lg-7 {
    width: 58.3333%;
  }
  .col-lg-8 {
    width: 66.6667%;
  }
  .col-lg-9 {
    width: 75%;
  }
  .col-lg-10 {
    width: 83.3333%;
  }
  .col-lg-11 {
    width: 91.6667%;
  }
  .col-lg-12 {
    width: 100%;
  }
}

/* ---------- Loading overlay (toggled by core JS: #page-overlay.active) ---------- */
#page-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: none;
  align-items: center;
  justify-content: center;
  background: var(--c-overlay);
}
#page-overlay.active {
  display: flex;
}
.spinner {
  width: 42px;
  height: 42px;
  border: 4px solid var(--c-border);
  border-top-color: var(--c-primary);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* ========================================================================== *
   PAGE-SPECIFIC FUNCTIONAL CSS (core ke sath LOCKED — sirf look nahi).
   Ye rules page JS ke ishaare par form INPUTS ko show/hide/mask karti hain;
   edit hui to form toot jata hai — is liye yahan (core) mein, style.css mein
   nahi. core.css, style.css ke BAAD load hoti hai taake ye hamesha editable
   design layer par jeet jayen (aur admin inhe todh na sake).
 * ========================================================================== */

/* ---------- New Order — field show/hide (.d-none) + platform picker + search ---------- */
/* utility the order JS toggles to show/hide fields */
.d-none {
  display: none !important;
}

/* ---- Platform filter cards (above the card, same width as it) ----
   auto-fit grid: every card is the SAME width and as many fit per line as the
   screen allows (all in one line → 4,4 → 3,3 → 2,2 …). */
.platform-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 6px;
  padding-bottom: 13px;
  margin-bottom: 13px;
  border-bottom: 1px solid var(--c-border); /* divider between the filter and the form */
}
.platform-card {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  height: 38px;
  padding: 0 10px;
  font-size: 13px;
  color: var(--c-muted); /* same height as .form-input */
  background: var(--c-input);
  border: 1px solid var(--c-border);
  border-radius: var(
    --c-radius
  ); /* sits inside the card, so use the input bg */
  -webkit-tap-highlight-color: transparent;
}
.platform-card:hover {
  background: var(--c-active);
  color: var(--c-text);
}
.platform-card.is-active {
  background: var(--c-primary);
  border-color: var(--c-primary);
  color: var(--c-on-primary);
}
.platform-card i {
  font-size: 14px;
}

/* description box + charge box are .form-static; these just tweak the text */
/* Two rows tall even when empty. .form-static's 38px is one row — exactly an
   input's height — so an empty description read as another box to fill in.
   Scaled off the font: 2 lines x 1.5 line-height, + the 16px padding and 2px
   border .form-static adds (box-sizing is border-box). Only .desc-box, not
   .form-static: the charge box and the child-panel price are one-liners. */
.desc-box {
  color: var(--c-muted);
  font-size: 13px;
  white-space: normal;
  min-height: calc(2 * 1.5em + 18px);
}
.qty-hint {
  display: block;
  margin-top: 6px;
  font-size: 12px;
  color: var(--c-muted);
}
.order-charge {
  font-weight: 700;
}

/* two-column grid (subscriptions / drip-feed) */
.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 14px;
}
.drip-fields {
  margin-top: 8px;
}
.order-drip .form-check {
  margin-bottom: 6px;
}

/* ---- Service search ---- */
.order-search-wrap {
  position: relative;
}
.order-search-icon {
  position: absolute;
  left: 12px;
  top: 12px;
  color: var(--c-muted);
  font-size: 14px;
  pointer-events: none;
}
.order-search-input {
  padding-left: 34px;
}
.order-search-dropdown {
  position: absolute;
  z-index: 30;
  left: 0;
  right: 0;
  top: calc(100% + 4px);
  max-height: 320px;
  overflow-y: auto;
  background: var(--c-bg);
  border: 1px solid var(--c-border);
  border-radius: var(--c-radius);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.08);
}
/* flex-start keeps the icon on the first line when a long name wraps */
.order-search-item {
  display: flex;
  align-items: flex-start;
  gap: 4px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--c-border);
  color: var(--c-text);
  font-size: 13px;
  line-height: 1.45;
}
.order-search-item i {
  flex: 0 0 auto;
  width: 14px;
  margin-top: 3px;
  text-align: center;
  color: var(--c-muted);
}
.order-search-item:last-child {
  border-bottom: 0;
}
.order-search-item:hover {
  background: var(--c-active);
}
.order-search-item.is-empty {
  color: var(--c-muted);
}

@media (max-width: 640px) {
  .form-grid {
    grid-template-columns: 1fr;
    gap: 0;
  }
}

/* ---------- Mass Order — transparent-text links mirror + service picker ---------- */
/* ---------- Service picker ---------- */
.mass-search-wrap {
  position: relative;
}

.mass-search-dropdown {
  position: absolute;
  z-index: 30;
  left: 0;
  right: 0;
  top: calc(100% + 4px);
  max-height: 320px;
  overflow-y: auto;
  background: var(--c-bg);
  border: 1px solid var(--c-border);
  border-radius: var(--c-radius);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.08);
}
.mass-search-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--c-border);
  color: var(--c-text);
  font-size: 13px;
  line-height: 1.45;
  cursor: pointer;
}
.mass-search-item:last-child {
  border-bottom: 0;
}
.mass-search-item:hover {
  background: var(--c-active);
}
.mass-search-item-name {
  flex: 1;
  min-width: 0;
  word-break: break-word;
}
.mass-search-item-price {
  flex: none;
  color: var(--c-muted);
  font-size: 12px;
  white-space: nowrap;
}
.mass-search-empty {
  padding: 12px;
  color: var(--c-muted);
  font-size: 13px;
}

/* ---------- The picked service ---------- */
.mass-picked {
  margin: 0 0 13px;
  padding: 10px 12px;
  border: 1px solid var(--c-border);
  border-radius: var(--c-radius);
  background: var(--c-card);
}
.mass-picked-name {
  font-size: 13px;
  font-weight: 700;
  color: var(--c-text);
  line-height: 1.4;
  word-break: break-word;
}
.mass-picked-meta {
  margin-top: 3px;
  font-size: 12px;
  color: var(--c-muted);
}

/* ---------- Links box, with a colour per line ----------
   A textarea paints every character one colour, so the real box is made
   transparent (caret still visible) and a mirror underneath draws the same text
   with a colour per line. Both MUST share these metrics — they come straight from
   textarea.form-input in style.css — or the two layers drift apart.
   nowrap + horizontal scroll: one link stays on one line, so a line's colour
   always lines up with the line the user sees. */
.mass-links-wrap {
  position: relative;
}

.mass-links-mirror,
.mass-links {
  font-family: inherit;
  font-size: 14px;
  line-height: 1.5;
  padding: 9px 12px;
  border: 1px solid var(--c-border);
  border-radius: var(--c-radius);
  white-space: pre;
  overflow-wrap: normal;
  word-break: normal;
  tab-size: 4;
}

.mass-links-mirror {
  position: absolute;
  inset: 0;
  margin: 0;
  overflow: hidden; /* JS keeps it scrolled with the textarea */
  pointer-events: none;
  background: var(--c-input);
  color: var(--c-text);
  border-color: transparent; /* the textarea draws the visible border/focus */
}

/* the real box on top: invisible text, visible caret and placeholder */
.mass-links {
  /* display:block is load-bearing, not tidiness. A textarea is inline-block by
     default, so it sits on the text baseline and leaves a few px of descender gap
     under itself inside .mass-links-wrap. The mirror is inset:0 against that
     wrapper, so it came out 2-3px taller than the textarea and the two layers
     drifted apart. block removes the gap: wrapper height == textarea height. */
  display: block;
  position: relative;
  background: transparent;
  overflow-x: auto;
  color: transparent;
  -webkit-text-fill-color: transparent;
  caret-color: var(--c-text);
}
.mass-links::placeholder {
  color: var(--c-muted);
  -webkit-text-fill-color: var(--c-muted);
}

.mass-links-ok {
  color: #0a4ea3;
} /* valid link — FIXED blue (jaan-boojh kar theme --c-primary nahi; theme color koi bhi ho, valid link hamesha blue rahe) */
.mass-links-bad {
  color: var(--c-danger);
} /* invalid, or a repeat — both block the batch */

/* ---------- Running total, just above the button ----------
   Takes the theme's own accent (--c-primary), so it follows whatever colour
   scheme the panel is set to instead of hard-coding one. Bigger than a status
   .badge because this is the number the user decides on. */
.mass-total-wrap {
  margin-bottom: 10px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.mass-total-badge {
  padding: 7px 16px;
  font-size: 14px;
  text-transform: none;
  color: var(--c-primary);
  background: var(--c-primary-soft);
  border: 1px solid var(--c-primary);
}

/* Sits next to the total, in the same shape, so the two read as one line: what it
   costs, and why you cannot place it. The amount short is deliberately NOT spelled
   out — "not enough balance" is the whole message, and the balance is one glance
   away in the stat card. Same red the theme already uses for a dead status badge. */
.mass-low-badge {
  padding: 7px 16px;
  font-size: 14px;
  text-transform: none;
  color: var(--c-danger);
  background: var(--c-danger-bg);
  border: 1px solid var(--c-danger-border);
}

/* a hint that is reporting a problem (invalid links, quantity out of range) */
.mass-hint-bad {
  color: var(--c-danger);
}

/* ---------- Broadcast popup (admin announcements) — centered modal + type icon ----------
   JS engine: assets/user/js/actions.js (window.SMM_BROADCASTS + localStorage schedule).
   Colours theme vars se aate — icon type ke hisaab se rang leta, baqi modal theme surface.
   Functional isliye core.css mein (reliable), par rang scheme ke saath khud badalte. */
.bc-overlay {
  position: fixed;
  inset: 0;
  z-index: 3000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 18px;
  background: rgba(0, 0, 0, 0.5);
  opacity: 0;
  transition: opacity 0.2s;
}
.bc-overlay.is-open {
  opacity: 1;
}
.bc-modal {
  position: relative;
  width: 100%;
  max-width: 340px;
  padding: 26px 22px 24px;
  text-align: center;
  background: var(--c-bg);
  border-radius: var(--c-radius);
  box-shadow: 0 14px 44px rgba(0, 0, 0, 0.3);
  transform: translateY(8px) scale(0.98);
  transition: transform 0.2s;
}
.bc-overlay.is-open .bc-modal {
  transform: none;
}
.bc-x {
  position: absolute;
  top: 8px;
  right: 10px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  font-size: 22px;
  line-height: 1;
  color: var(--c-muted);
}
.bc-x:hover {
  color: var(--c-text);
}
.bc-count {
  position: absolute;
  top: 13px;
  left: 15px;
  font-size: 11px;
  font-weight: 700;
  color: var(--c-muted);
}
.bc-icon {
  width: 54px;
  height: 54px;
  margin: 4px auto 14px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 26px;
  font-weight: 700;
  color: #fff;
  background: var(--c-primary);
}
.bc-icon.bc-success {
  background: var(--c-success);
}
.bc-icon.bc-info {
  background: var(--c-info);
}
.bc-icon.bc-warning {
  background: var(--c-warning);
}
.bc-icon.bc-error {
  background: var(--c-danger);
}
.bc-icon.bc-question {
  background: var(--c-primary);
}
.bc-title {
  margin: 0 0 8px;
  font-size: 18px;
  font-weight: 700;
  color: var(--c-text);
  word-break: break-word;
}
.bc-text {
  margin: 0 0 18px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--c-muted);
  word-break: break-word;
}
.bc-text:last-child {
  margin-bottom: 0;
}
.bc-btn {
  display: inline-block;
  padding: 9px 20px;
  border: 0;
  border-radius: var(--c-radius);
  background: var(--c-primary);
  color: var(--c-on-primary);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}
.bc-btn:hover {
  background: var(--c-primary-dark);
  color: var(--c-on-primary); /* global a:hover text ko primary-dark karta = background jaisa = gaib; yahan roka */
}

/* =====================================================================================
   Broadcast popup — keep the card on screen for long messages
   The .bc-modal had no height cap, so a long announcement grew past the viewport and
   ran off the screen. Cap the card to the screen height (minus the overlay's 18px
   padding on each side) and let the message body (.bc-text) scroll INSIDE it instead;
   the close button, icon, title and action button stay put. Appended last in core.css
   so it wins over the .bc-modal rule above and an admin's style.css cannot undo it.
   ===================================================================================== */
.bc-modal{
  max-height: calc(100vh - 36px);
  max-height: calc(100dvh - 36px);
  display: flex;
  flex-direction: column;
  align-items: center;
}
.bc-title,
.bc-text{ width: 100%; }
.bc-text{
  flex: 0 1 auto;         /* may shrink when the card hits its cap; never grows */
  min-height: 0;          /* allow it to shrink below content so overflow can scroll */
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* Description box: wrap ANY long unbroken string (e.g. stray backslash/slash runs from
   a provider's escaped description) so it never overflows the box or the screen.
   Appended last so it wins over the .desc-box rule above. */
.desc-box{
  overflow-wrap: anywhere;
  word-break: break-word;
}
