/* ==========================================================================
   HesabPay × GSM Theme
   One variable set. Light is the default; dark is an override on
   html[data-theme="dark"]. Nothing hardcodes a colour, which is why the theme
   now switches cleanly instead of half-switching.
   ========================================================================== */

@import url('https://cdn.jsdelivr.net/gh/rastikerdar/vazirmatn@v33.003/Vazirmatn-font-face.css');

:root {
  --ui:   'Vazirmatn', 'Segoe UI', Tahoma, sans-serif;
  /* Vazirmatn sits before the generic on purpose. Font matching is per
     CHARACTER, so digits still resolve to a true monospace and only Persian
     letters fall through to Vazirmatn - which is the point: none of the four
     mono families above carry Arabic script, so "افغانی" inside a mono element
     was landing on whatever the OS offered last, unjoined and stretched. */
  --mono: ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Consolas, 'Vazirmatn', monospace;

  --bg:        #eef1f6;
  --bg-glow:   rgba(23, 178, 106, .10);
  --card:      #ffffff;
  --card-2:    #f5f7fa;
  --line:      #e4e8ef;
  --line-2:    #eef1f6;

  --txt:       #17202f;
  --txt-2:     #5c6779;
  --txt-3:     #949daa;

  --accent:    #17b26a;
  --accent-2:  #0e9256;
  --accent-sf: rgba(23, 178, 106, .12);

  --danger:    #d92d20;
  --danger-sf: rgba(217, 45, 32, .10);
  --warn:      #b54708;
  --warn-sf:   rgba(247, 144, 9, .12);
  --info-sf:   rgba(41, 112, 255, .09);
  --info-bd:   rgba(41, 112, 255, .25);

  --shadow:    0 18px 44px rgba(20, 30, 50, .10);
  --shadow-sm: 0 2px 8px rgba(20, 30, 50, .06);
  --radius:    18px;
}

html[data-theme="dark"] {
  --bg:        #10161f;
  --bg-glow:   rgba(23, 178, 106, .13);
  --card:      #1a2230;
  --card-2:    #212b3b;
  --line:      #2b3648;
  --line-2:    #232e3e;

  --txt:       #e8ecf3;
  --txt-2:     #9aa4b4;
  --txt-3:     #6f7a8a;

  --accent:    #22c77c;
  --accent-2:  #34d98f;
  --accent-sf: rgba(34, 199, 124, .14);

  --danger:    #f97066;
  --danger-sf: rgba(249, 112, 102, .12);
  --warn:      #fdb022;
  --warn-sf:   rgba(253, 176, 34, .12);
  --info-sf:   rgba(84, 145, 255, .12);
  --info-bd:   rgba(84, 145, 255, .28);

  --shadow:    0 18px 44px rgba(0, 0, 0, .40);
  --shadow-sm: 0 2px 8px rgba(0, 0, 0, .25);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  padding: 26px 16px 40px;
  font-family: var(--ui);
  background: var(--bg);
  color: var(--txt);
  -webkit-font-smoothing: antialiased;
  position: relative;
  transition: background-color .2s ease, color .2s ease;
}

body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background: radial-gradient(900px 520px at 50% -10%, var(--bg-glow), transparent 62%);
}

.wrap {
  position: relative;
  z-index: 1;
  max-width: 460px;
  margin: 0 auto;
}
.wrap.admin { max-width: 1180px; }

/* ── masthead ───────────────────────────────────────────────────────────── */
.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 18px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 9px;
  font-weight: 800;
  font-size: 16px;
  color: var(--txt);
}
.brand .dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-sf);
}

.mast-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}

/* The round masthead button. .theme-btn used to carry these rules alone; the ؟
   is the same object, so the look lives here and .theme-btn only adds its
   moon/sun glyph. */
.icon-btn {
  width: 36px;
  height: 36px;
  flex: 0 0 auto;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--txt-2);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--ui);
  font-size: 15px;
  font-weight: 700;
  line-height: 1;
  padding: 0;
  transition: border-color .15s ease, color .15s ease, transform .12s ease;
}
.icon-btn:hover { border-color: var(--accent); color: var(--accent-2); }
.icon-btn:active { transform: scale(.94); }
.icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

#help-btn { font-size: 16px; }

.theme-btn::before { content: '\1F319'; }             /* moon: click for dark */
html[data-theme="dark"] .theme-btn::before { content: '\2600'; }  /* sun: back to light */

/* ── the ticket ─────────────────────────────────────────────────────────── */
.ticket {
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
  background: var(--card);
  border: 1px solid var(--line);
}

.stub { padding: 22px; }

.stub--bottom {
  border-top: 1px dashed var(--line);
  background: var(--card-2);
  position: relative;
}
/* the punched notches of a paper ticket */
.stub--bottom::before,
.stub--bottom::after {
  content: '';
  position: absolute;
  top: -11px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--bg);
  border: 1px solid var(--line);
}
.stub--bottom::before { right: -12px; }
.stub--bottom::after  { left:  -12px; }

.eyebrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--txt-3);
  text-transform: none;
}
.eyebrow b { color: var(--accent-2); font-weight: 800; }

/* ── fields ─────────────────────────────────────────────────────────────── */
.field label,
.amount-label {
  display: block;
  font-size: 13px;
  font-weight: 700;
  color: var(--txt-2);
  margin-bottom: 8px;
}

/* email + its status badge.
   The page is RTL but the address is LTR, so the badge is pinned to the
   PHYSICAL right and the input reserves that space. It cannot overlap. */
.input-check { position: relative; display: block; }

.input-check input {
  width: 100%;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  color: var(--txt);
  font-family: var(--ui);
  font-size: 15px;
  outline: 0;
  direction: ltr;
  text-align: left;
  padding: 13px 14px;
  padding-right: 48px;             /* the badge lives here */
  transition: border-color .15s ease, box-shadow .15s ease;
}
.input-check input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-sf);
}
.input-check input::placeholder { color: var(--txt-3); }

/* The badge is centred with margin-top, NOT transform: translateY(-50%).
   That is the whole fix. The old rule centred with a transform and then handed
   .busy an `animation: spin` whose `transform: rotate()` REPLACED it - so the
   moment the spinner started it dropped 11px out of the field, span there
   off-centre, and snapped back when the answer arrived. A fixed 22px box does
   not need a transform to centre, so transform is left free for the animations. */
.check-mark {
  position: absolute;
  right: 14px;                     /* physical: never flips with RTL */
  left: auto;
  top: 50%;
  margin-top: -11px;               /* half of height - the centring */
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  color: #fff;
  opacity: 0;
  pointer-events: none;
  transition: opacity .15s ease, background-color .15s ease;
}

/* ok / bad pop in. An animation, not a transition: it always plays from
   scale(.3) no matter what transform the spinner left behind, and its last
   frame equals the resting state, so nothing jumps when it ends. */
.check-mark.ok,
.check-mark.bad {
  opacity: 1;
  animation: mark-pop .26s cubic-bezier(.2, .9, .3, 1.35);
}
.check-mark.ok  { background: var(--accent); }
.check-mark.bad { background: var(--danger); }

/* The tick is DRAWN, not typed. '✓' (U+2713) is not in Vazirmatn, so it was
   falling back to whatever font on the machine happened to carry it - a
   different weight, size and baseline for every visitor. Two borders and a
   rotate are identical everywhere and stay crisp at any zoom. */
.check-mark.ok::before {
  content: '';
  width: 5px;
  height: 9px;
  margin-top: -2px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.check-mark.bad::before {
  content: '!';
  font-family: var(--ui);
  font-size: 13px;
  font-weight: 800;
}

.check-mark.busy {
  opacity: 1;
  background: transparent;
  border: 2px solid var(--line);
  border-top-color: var(--accent);
  animation: spin .6s linear infinite;
}

@keyframes mark-pop {
  0%   { transform: scale(.3); opacity: 0; }
  60%  { transform: scale(1.12); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

/* Someone who has asked for less motion gets the state, not the show. */
@media (prefers-reduced-motion: reduce) {
  .check-mark.ok,
  .check-mark.bad { animation: none; }
  .check-mark.busy { animation-duration: 1.6s; }
}

.hint {
  margin: 8px 0 0;
  font-size: 12.5px;
  line-height: 1.85;
  color: var(--txt-3);
}
.hint--ok  { color: var(--accent-2); }
.hint--bad { color: var(--danger); }
.hint a { color: inherit; font-weight: 700; }

/* amount */
.amount {
  display: flex;
  align-items: baseline;
  gap: 10px;
  border-bottom: 2px solid var(--line);
  padding-bottom: 8px;
}
.amount input {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--txt);
  font-family: var(--mono);
  font-size: 40px;
  font-weight: 700;
  padding: 2px 0;
  direction: ltr;
  text-align: left;
}
.amount input::placeholder { color: var(--txt-3); opacity: .5; }
.amount .unit {
  font-size: 14px;
  font-weight: 700;
  color: var(--txt-3);
  white-space: nowrap;
}

.field-error {
  margin: 8px 0 0;
  font-size: 12.5px;
  color: var(--danger);
  min-height: 0;
  display: none;
}
.field-error.on { display: block; }

/* chips.
   A grid, not flex-wrap. With `flex: 1 1 auto; min-width: 56px` the five chips
   needed ~320px and a 375px phone gives the row ~299px - so `100` wrapped to a
   second line and, being flex:1 with nothing beside it, stretched to the full
   width as one large green bar. Five equal columns cannot wrap, cannot stretch,
   and stay even at every width. */
.chips {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
  margin-top: 16px;
}
.chip {
  min-width: 0;
  padding: 9px 4px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: var(--card-2);
  color: var(--txt-2);
  font-family: var(--mono);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: all .13s ease;
}
.chip:hover { border-color: var(--accent); color: var(--accent-2); }
.chip.on {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

/* ── the rate ticker ────────────────────────────────────────────────────── */
.ticker {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 13px 15px;
  margin-bottom: 16px;
}
.ticker-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.ticker-label {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  font-weight: 600;
  color: var(--txt-2);
}
.ticker-value {
  /* UI font, not mono: this element holds "67 افغانی" - a number AND a Persian
     word. tabular-nums gives the digits the same steady column mono was here
     for, without asking a monospace family to shape Arabic. */
  font-family: var(--ui);
  font-size: 19px;
  font-weight: 700;
  color: var(--txt);
  font-variant-numeric: tabular-nums;
  direction: ltr;
}
.ticker-meta {
  margin-top: 6px;
  font-size: 11.5px;
  color: var(--txt-3);
  line-height: 1.7;
}

.pulse {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  flex: 0 0 auto;
}
.pulse.tick { animation: ping 1s cubic-bezier(0, 0, .2, 1); }

@keyframes ping {
  0%   { box-shadow: 0 0 0 0 var(--accent-sf); }
  70%  { box-shadow: 0 0 0 9px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ── the breakdown ──────────────────────────────────────────────────────── */
.rows { margin: 0; }
.row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--line-2);
}
.row:last-child { border-bottom: 0; }
.row .k { font-size: 13px; color: var(--txt-2); }
.row .v {
  /* holds "335.00 افغانی" - see .ticker-value above for why this is not mono */
  font-family: var(--ui);
  font-size: 14px;
  font-weight: 600;
  color: var(--txt);
  font-variant-numeric: tabular-nums;
  text-align: left;
  direction: rtl;
}
.row .v.big { font-size: 19px; font-weight: 800; }

.row--total {
  border-bottom: 0;
  border-top: 2px solid var(--line);
  padding-top: 13px;
  margin-top: 3px;
}
.row--total .k { font-weight: 800; color: var(--txt); font-size: 14px; }

.credit-note {
  margin: 13px 0 16px;
  font-size: 12.5px;
  line-height: 1.9;
  color: var(--txt-2);
  text-align: center;
  min-height: 20px;
}

/* ── buttons ────────────────────────────────────────────────────────────── */
.btn {
  width: 100%;
  border: 0;
  border-radius: 13px;
  padding: 15px 18px;
  background: var(--accent);
  color: #fff;
  font-family: var(--ui);
  font-size: 15.5px;
  font-weight: 800;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  box-shadow: 0 8px 20px var(--accent-sf);
  transition: filter .15s ease, transform .1s ease, opacity .15s ease;
}
.btn:hover:not(:disabled) { filter: brightness(1.06); }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { opacity: .45; cursor: not-allowed; box-shadow: none; }

.btn--ghost {
  background: transparent;
  color: var(--txt-2);
  border: 1.5px solid var(--line);
  box-shadow: none;
}
.btn--ghost:hover { border-color: var(--accent); color: var(--accent-2); }

.btn-icon { width: 18px; height: 18px; flex: 0 0 auto; }

.spinner {
  display: none;
  width: 17px;
  height: 17px;
  border: 2px solid rgba(255, 255, 255, .35);
  border-top-color: #fff;
  border-radius: 50%;
  animation: spin .7s linear infinite;
}
.is-busy .spinner { display: block; }
.is-busy .btn-icon { display: none; }

.actions { display: flex; gap: 10px; }
.actions .btn { flex: 1; }

/* ── alerts ─────────────────────────────────────────────────────────────── */
.alert {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 13px 15px;
  border-radius: 13px;
  font-size: 13px;
  line-height: 1.9;
  margin-bottom: 14px;
  border: 1px solid transparent;
}
.alert--error { background: var(--danger-sf); border-color: var(--danger); color: var(--danger); }
.alert--warn  { background: var(--warn-sf);   border-color: var(--warn);   color: var(--warn); }
.alert--info  { background: var(--info-sf);   border-color: var(--info-bd); color: var(--txt-2); }
.alert a { color: inherit; font-weight: 800; }

/* ── trust row ──────────────────────────────────────────────────────────── */
.trust {
  display: flex;
  justify-content: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 16px;
  font-size: 11px;
  color: var(--txt-3);
}
.trust span { display: flex; align-items: center; gap: 5px; }
.trust svg { width: 13px; height: 13px; }

.foot {
  margin-top: 18px;
  text-align: center;
  font-size: 11.5px;
  line-height: 2;
  color: var(--txt-3);
}
.foot a { color: var(--accent-2); }

/* ── the fee guide, in a dialog ──────────────────────────────────────────── */
/* <dialog> rather than a hand-rolled overlay: the browser gives Esc-to-close,
   a focus trap, an inert page behind and a ::backdrop, all of which a div would
   have to reimplement badly. Note there is no bare `display` here - the UA hides
   a closed dialog with display:none, so styling display on .modal itself would
   make it permanently visible. It goes on [open]. */
.modal {
  width: min(430px, calc(100vw - 24px));
  max-height: calc(100vh - 48px);
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--card);
  color: var(--txt);
  box-shadow: var(--shadow);
  overflow: hidden;
}
@supports (height: 100dvh) {
  .modal { max-height: calc(100dvh - 48px); }
}
.modal[open] {
  display: flex;
  flex-direction: column;
  position: fixed;
  inset: 0;
  margin: auto;                    /* centres for showModal() and the fallback alike */
  animation: modal-in .19s cubic-bezier(.2, .9, .3, 1.1);
}
.modal::backdrop {
  background: rgba(12, 18, 30, .55);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}
@keyframes modal-in { from { opacity: 0; transform: translateY(10px) scale(.98); } }

.modal-head {
  display: flex;
  align-items: center;
  gap: 9px;
  flex: 0 0 auto;
  padding: 14px 16px;
  border-bottom: 1px dashed var(--line);
}
.modal-head h2 {
  margin: 0;
  font-size: 13.5px;
  font-weight: 800;
  color: var(--txt);
}
.modal-x {
  margin-inline-start: auto;       /* RTL-safe */
  width: 30px;
  height: 30px;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--card-2);
  color: var(--txt-3);
  cursor: pointer;
  transition: color .14s ease, border-color .14s ease, transform .12s ease;
}
.modal-x svg { width: 14px; height: 14px; }
.modal-x:hover { color: var(--danger); border-color: var(--danger); }
.modal-x:active { transform: scale(.92); }

/* the one place a scrollbar is welcome: a long guide inside its own box, not
   the payment form underneath it */
.modal-body {
  flex: 1 1 auto;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 4px 16px 16px;
  overscroll-behavior: contain;    /* don't hand the scroll back to the page */
}

.help-ico { width: 16px; height: 16px; flex: 0 0 auto; color: var(--accent); }

.help-lead {
  margin: 11px 0 4px;
  font-size: 12.5px;
  line-height: 1.95;
  color: var(--txt-2);
}
.help-lead b { color: var(--txt); font-weight: 700; }

.fee {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 11px 0;
  border-bottom: 1px solid var(--line-2);
}
.fee:last-of-type { border-bottom: 0; }
.fee-main { flex: 1 1 auto; min-width: 0; }
.fee-name { font-size: 12.5px; font-weight: 700; color: var(--txt); }
.fee-sub {
  margin: 4px 0 0;
  font-size: 11.5px;
  line-height: 1.8;
  color: var(--txt-3);
}
.fee-pct {
  flex: 0 0 auto;
  font-family: var(--ui);          /* holds "6.34٪" - ٪ is Arabic script too */
  font-size: 13.5px;
  font-weight: 800;
  color: var(--accent-2);
  background: var(--accent-sf);
  border-radius: 8px;
  padding: 4px 9px;
  font-variant-numeric: tabular-nums;
}
.fee-pct.muted { color: var(--txt-2); background: var(--line-2); }

.help-note {
  margin: 12px 0 0;
  padding: 10px 12px;
  border-radius: 10px;
  background: var(--card-2);
  border: 1px solid var(--line-2);
  font-size: 11.5px;
  line-height: 1.95;
  color: var(--txt-3);
}

/* honeypot: invisible to people, irresistible to bots.
   NOT left:-9999px, which is what this was. That line is harmless on an LTR
   page, which is why it is copy-pasted everywhere - but this page is dir="rtl",
   and in RTL the LEFT is the scrollable direction. Parking a field 9999px to
   the left therefore made the document ~10,000px wide and handed every customer
   a horizontal scrollbar. (It also escaped .ticket's overflow:hidden, because
   its containing block is body - the nearest positioned ancestor - not the
   ticket.) And since that bar eats ~15px off the bottom of a min-height:100vh
   body, it produced a vertical scrollbar as well. Both bars, one line.
   Clipping to nothing in place is direction-agnostic, costs no layout, and
   still leaves a real, focusable, fillable field for a bot to walk into. */
.hp {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  border: 0 !important;
  overflow: hidden !important;
  clip: rect(0 0 0 0) !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
  opacity: 0 !important;
  pointer-events: none !important;
}

/* ── receipts ───────────────────────────────────────────────────────────── */
.result-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
}
.result-title { margin: 0 0 6px; font-size: 19px; font-weight: 800; color: var(--txt); }
.result-sub   { margin: 0; font-size: 13px; line-height: 1.95; color: var(--txt-2); }

.stamp {
  flex: 0 0 auto;
  text-align: center;
  border: 2px solid var(--accent);
  color: var(--accent-2);
  border-radius: 10px;
  padding: 7px 11px;
  transform: rotate(-5deg);
}
.stamp .big   { display: block; font-size: 13px; font-weight: 900; }
.stamp .small { display: block; font-size: 9px; margin-top: 2px; opacity: .8; }
.stamp--fail    { border-color: var(--danger); color: var(--danger); }
.stamp--pending { border-color: var(--warn);   color: var(--warn); }

.checking {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px dashed var(--line);
  font-size: 12.5px;
  color: var(--txt-2);
}
.checking .spinner {
  display: block;
  border-color: var(--line);
  border-top-color: var(--accent);
}

/* ── login / info page ──────────────────────────────────────────────────── */
.lock-badge {
  width: 64px;
  height: 64px;
  margin: 0 auto;
  border-radius: 20px;
  background: var(--accent-sf);
  color: var(--accent-2);
  display: flex;
  align-items: center;
  justify-content: center;
}
.lock-badge svg { width: 30px; height: 30px; }

/* ── admin ──────────────────────────────────────────────────────────────── */
.admin-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 18px;
  flex-wrap: wrap;
}

.env {
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .04em;
  padding: 5px 10px;
  border-radius: 20px;
  border: 1px solid var(--line);
  color: var(--txt-3);
  background: var(--card);
}
.env.live { color: var(--accent-2); border-color: var(--accent); }
.env.test { color: var(--warn); border-color: var(--warn); }

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
  margin-bottom: 16px;
}
.stat {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 14px 16px;
  box-shadow: var(--shadow-sm);
}
.stat .k { font-size: 11.5px; color: var(--txt-3); }
.stat .v {
  font-family: var(--mono);
  font-size: 21px;
  font-weight: 700;
  margin-top: 5px;
  color: var(--txt);
  direction: ltr;
  text-align: right;
}

.panel {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 16px;
  margin-bottom: 16px;
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.panel h2 {
  margin: 0;
  padding: 14px 18px;
  font-size: 14px;
  font-weight: 800;
  color: var(--txt);
  border-bottom: 1px solid var(--line);
  background: var(--card-2);
}

.scroll { overflow-x: auto; }

table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
th {
  text-align: right;
  padding: 10px 12px;
  font-size: 11px;
  font-weight: 700;
  color: var(--txt-3);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
  background: var(--card-2);
}
td {
  padding: 11px 12px;
  border-bottom: 1px solid var(--line-2);
  color: var(--txt-2);
  white-space: nowrap;
  vertical-align: middle;
}
tr:last-child td { border-bottom: 0; }
.mono { font-family: var(--mono); direction: ltr; text-align: left; font-size: 11.5px; }

.tag {
  display: inline-block;
  padding: 3px 9px;
  border-radius: 20px;
  font-size: 10.5px;
  font-weight: 700;
  border: 1px solid;
}
.tag.paid    { color: var(--accent-2); border-color: var(--accent); background: var(--accent-sf); }
.tag.pending { color: var(--warn);     border-color: var(--warn);   background: var(--warn-sf); }
.tag.failed,
.tag.expired { color: var(--danger);   border-color: var(--danger); background: var(--danger-sf); }
.tag.flag    { color: var(--warn);     border-color: var(--warn);   background: var(--warn-sf); margin-right: 4px; }

.inp {
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--txt);
  font-family: var(--ui);
  font-size: 13px;
  outline: 0;
}
.inp:focus { border-color: var(--accent); }

.switch {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--txt-2);
  cursor: pointer;
}
.switch input { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }

.rate-now {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.rate-big {
  font-family: var(--mono);
  font-size: 30px;
  font-weight: 700;
  direction: ltr;
  color: var(--txt);
}
.rate-big small { font-size: 12px; color: var(--txt-3); font-weight: 400; }
.rate-src { font-size: 12px; color: var(--txt-3); margin-top: 4px; line-height: 1.9; }
.rate-src a { color: var(--accent-2); }
.rate-tax {
  font-size: 13px;
  color: var(--txt-2);
  background: var(--card-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 9px 14px;
}

.login {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 26px;
  display: flex;
  flex-direction: column;
  gap: 11px;
  box-shadow: var(--shadow);
}
.login h1 { margin: 0 0 6px; font-size: 17px; font-weight: 800; text-align: center; color: var(--txt); }
.login input {
  padding: 12px 14px;
  border-radius: 11px;
  border: 1.5px solid var(--line);
  background: var(--card);
  color: var(--txt);
  font-family: var(--ui);
  font-size: 14px;
  outline: 0;
}
.login input:focus { border-color: var(--accent); }

@media print {
  body { background: #fff; padding: 0; }
  .btn, .actions, .theme-btn, .checking, .trust { display: none !important; }
  .ticket { box-shadow: none; border: 1px solid #ccc; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   OVERRIDES
   ---------------------------------------------------------------------------
   This block used to claim everything above it was untouched "byte for byte".
   That is no longer true and pretending otherwise would send the next reader
   looking in the wrong place: the honeypot, the check-mark, the chips grid and
   the two mono-font rules were all fixed IN PLACE above, because they were
   wrong there. Only genuine per-viewport overrides belong down here.
   ═══════════════════════════════════════════════════════════════════════════ */

/* the admin panel gained a few wrappers */
.brand-txt { font: inherit; color: inherit; }
.pad       { padding: 18px; }

.toolbar {
  display: flex;
  gap: 9px;
  flex-wrap: wrap;
  align-items: center;
  padding: 14px 16px;
}
.toolbar .btn { width: auto; padding: 10px 22px; }

/* ── getting the pay button above the fold ───────────────────────────────
   Measured in Chromium, 375x667 (iPhone SE), with the tallest realistic state
   on screen: 100 credit, a verified email (two-line hint) and a stale rate
   (two-line ticker note). The page came to 909px against a 667px screen and
   the button sat below the fold - you had to scroll past the thing you came
   to press.

   These rules key on a SHORT screen or a PHONE-WIDTH one. A 390x844 iPhone is
   not short, so a height-only query left it at full desktop spacing and it
   scrolled 154px for no reason; tighter spacing is simply correct on a handset.
   Nothing here touches a colour, a radius, a weight or a font - it is padding,
   margins and two font sizes.

   Below 780px of height the page still scrolls: a form with an email field, an
   amount, a rate, a breakdown and a footer does not fit in 667px, and the
   honest fix is not to hide half of it. What matters is that the button is
   reachable without scrolling, and it now is on every size tested.
   ────────────────────────────────────────────────────────────────────────── */
@media (max-height: 780px), (max-width: 460px) {
  body            { padding: 12px 12px 18px; }
  .masthead       { margin-bottom: 10px; }
  .stub           { padding: 14px 16px; }

  .field          { margin-top: 10px !important; }
  .hint           { margin-top: 5px; line-height: 1.55; font-size: 12px; }
  .amount-label   { margin-top: 12px !important; margin-bottom: 4px; }
  .amount input   { font-size: 32px; }
  .chips          { margin-top: 9px; gap: 6px; }
  .chip           { padding: 8px 3px; }

  .ticker         { padding: 9px 12px; margin-bottom: 9px; }
  .ticker-meta    { margin-top: 4px; line-height: 1.55; }
  .row            { padding: 6px 0; }
  .credit-note    { margin: 7px 0 9px; min-height: 0; line-height: 1.55; }
  .trust          { margin-top: 9px; }
  .foot           { margin-top: 10px; line-height: 1.6; }
}

/* Very short — landscape, or a small phone with the keyboard open. Give up on
   fitting and let it scroll rather than clip the button off the bottom. */
@media (max-height: 560px) {
  body { padding-bottom: 24px; }
}

/* Any phone. The three trust badges want ~328px at their normal size and no
   phone gives that row more than ~334px, so on a 390px handset they wrapped to
   two lines while a 375px one - caught by the narrower rule below - did not.
   Same page, different number of lines, for no reason a customer could see.
   Text width depends on the font that actually loads, so the sizes here are a
   best effort, not a guarantee. row-gap IS the guarantee: if they still wrap on
   some device the second line costs 3px instead of 8px and the layout is fine
   either way. Never bet a layout on a glyph width. */
@media (max-width: 460px) {
  .trust      { gap: 6px; row-gap: 3px; font-size: 10px; }
  .trust span { gap: 4px; }
  .trust svg  { width: 12px; height: 12px; }
}

/* Narrow, regardless of height. A 360px Android gives the chip row ~296px;
   five columns and a 6px gap keep each chip at ~53px, which "100" fits into
   at 13px. Nothing here exists to save height - it is purely about width. */
@media (max-width: 380px) {
  .stub        { padding: 14px 14px; }
  .chips       { gap: 6px; }
  .chip        { font-size: 13px; padding: 8px 2px; }
  .ticker-meta { font-size: 11px; }
}

/* iOS Safari reports 100vh taller than the visible page, so a viewport-height
   layout hides its own footer behind the browser chrome. dvh is the honest one. */
@supports (height: 100dvh) {
  body { min-height: 100dvh; }
}