/* Generated by `python manage.py bundlecss` - do not edit.

   Source files, in cascade order:
     fonts.css
     tokens.css
     components.css
     nav.css
     layouts.css
     marketing.css
     integrations.css
     reports.css

   Edit those and re-run the command. base.html serves this only when
   DEBUG is off; in development it links the sources directly. */


/* ===== fonts.css ===== */

/* Inter, self-hosted.

   Served from our own domain rather than fonts.googleapis.com: that was
   a render-blocking request to a third party on the one page that has to
   be fast on a phone in a shop. A variable font, so the whole 400-800
   range we use is one file per script instead of five.

   unicode-range is what keeps it cheap: a page of Uzbek Latin never
   fetches the Cyrillic file, and a Russian page never fetches anything
   it does not draw with.

   Regenerate with tools/_fetch_inter.py if the weights ever change. */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("../fonts/inter-cyrillic-ext.251d36f2b5a6.woff2") format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("../fonts/inter-cyrillic.de93fdc85e3d.woff2") format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("../fonts/inter-latin-ext.1ad231aac0a8.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("../fonts/inter-latin.260c81a4759b.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}


/* ===== tokens.css ===== */

/* TapCon design tokens. Every colour, radius and shadow used anywhere
   comes from here — components.css never hardcodes a value. */
:root {
  /* brand */
  --primary: #2563eb;
  --primary-hover: #1d4ed8;
  /* Lightened a shade in Phase 7 so --primary on it clears 4.5:1 (it was
     4.48 — the business initial in the pay-page avatar, and the "waiting"
     badge, both sit on this). */
  --primary-soft: #edf2fe;
  /* Mid blue for chart bars. --primary-soft sits almost on top of --bg, so a
     bar filled with it is invisible against its own track; --primary is loud
     enough that fourteen of them fight the figures above the chart. */
  --primary-mid: #93b4f8;
  --navy: #1b2a41;
  --navy-soft: #334867;

  /* surfaces */
  --bg: #f4f7fb;
  --card: #ffffff;
  --border: #e3e9f2;
  --border-strong: #cbd6e6;

  /* text */
  --text: #1b2a41;
  --text-muted: #5b6b83;
  /* Darkened in Phase 7. At #8794a8 this failed WCAG AA (2.9:1), and it is
     what the "soum" suffix beside the amount and the "Secure payments
     powered by TapCon" line are drawn in — the quietest text on the page is
     still text a customer reads while deciding to pay.

     Measured against both surfaces it lands on: 5.3:1 on a white card and
     4.9:1 on the page background. The second is the one that nearly caught
     us — the trust line sits on --bg, not on white. */
  --text-faint: #5f6c83;
  --text-on-primary: #ffffff;

  /* status
     These are the colours of the words that tell a seller whether they were
     paid, so they are picked by measurement, not by eye. Each one is checked
     twice: as text on its own pale tint (the badges and alerts) and as a
     background under white text (the toggle, the notification pill, the big
     result mark). The pale tint is always the harder of the two.

     #16a34a on --success-soft was 2.95:1 — "Paid" was the least readable
     word on the dashboard. Now 5.59:1, and 6.25:1 under white text. */
  --success: #166f35;
  --success-soft: #e7f6ec;
  /* Darkened in Phase 7: #d97706 on --warning-soft was 2.9:1, and this is
     the colour of the "Sinov" badge that tells a customer no real money will
     move. A warning nobody can read is not a warning. Now 4.75:1. */
  --warning: #a35a04;
  --warning-soft: #fdf3e3;
  /* #dc2626 on --danger-soft was 4.17:1 — under the line, and this is the
     word on a failed payment. Now 5.59:1, and 6.47:1 under white text. */
  --danger: #b91c1c;
  --danger-soft: #fdeaea;

  /* provider brand colours — used only on their own buttons */
  --click: #00a3e0;
  --payme: #00cfc1;
  --uzum: #7000ff;
  --paynet: #0a2f6b;

  /* radius */
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-pill: 999px;

  /* shadow */
  --shadow-sm: 0 1px 3px rgba(27, 42, 65, 0.06);
  --shadow: 0 2px 12px rgba(27, 42, 65, 0.08);
  --shadow-lg: 0 8px 28px rgba(27, 42, 65, 0.12);

  /* spacing scale */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 48px;
  --s-8: 64px;

  /* typography */
  --font: "Inter", -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  --fs-xs: 12px;
  --fs-sm: 14px;
  --fs-base: 16px;
  --fs-lg: 18px;
  --fs-xl: 22px;
  --fs-2xl: 28px;
  --fs-3xl: 36px;

  /* layout */
  --pay-width: 480px;
  --page-width: 1140px;
  --tap-target: 52px;
  /* The merchant top bar. The sidebar sticks below it and sizes itself
     against it, so the three of them must agree on one number. */
  --topbar-h: 64px;
}


/* ===== components.css ===== */

/* TapCon shared components. Reused by marketing, merchant and pay layouts. */

/* --- reset & base ---------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--fs-base);
  line-height: 1.55;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4 { margin: 0 0 var(--s-3); line-height: 1.25; font-weight: 700; }
h1 { font-size: var(--fs-3xl); }
h2 { font-size: var(--fs-2xl); }
h3 { font-size: var(--fs-xl); }
p { margin: 0 0 var(--s-4); }
a { color: var(--primary); text-decoration: none; }
a:hover { text-decoration: underline; }
img { max-width: 100%; height: auto; }
.muted { color: var(--text-muted); }
.small { font-size: var(--fs-sm); }
.center { text-align: center; }

/* --- layout helpers -------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--page-width);
  margin: 0 auto;
  padding: 0 var(--s-4);
}
.stack > * + * { margin-top: var(--s-4); }
/* Both wrap: a row of buttons or badges that cannot wrap pushes the whole
   document wider than the phone and the page starts scrolling sideways. */
.row { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
.row-between {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-3); flex-wrap: wrap;
}

/* --- card ------------------------------------------------------------ */
.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  padding: var(--s-5);
}


/* --- buttons --------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: var(--tap-target);
  padding: 0 var(--s-5);
  border: 1px solid transparent;
  border-radius: var(--r-md);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease, transform .05s ease;
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }
/* The focus ring was --primary-soft, which is 1.06:1 against white — a ring
   a keyboard user cannot see is not a ring. --primary is 4.7:1 against the
   page and well past the 3:1 a non-text indicator needs. */
.btn:focus-visible { outline: 3px solid var(--primary); outline-offset: 2px; }
.btn[disabled] { opacity: .55; cursor: not-allowed; }

.btn-primary { background: var(--primary); color: var(--text-on-primary); }
.btn-primary:hover { background: var(--primary-hover); }

.btn-ghost { background: transparent; color: var(--primary); border-color: var(--border-strong); }
.btn-ghost:hover { background: var(--primary-soft); }

.btn-block { width: 100%; }

/* --- provider row button (pay page) ---------------------------------- */
.provider-btn {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  width: 100%;
  min-height: var(--tap-target);
  padding: var(--s-3) var(--s-4);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  color: var(--text);
  font-weight: 600;
  cursor: pointer;
  text-align: left;
  /* Rendered as a <button>, so undo the browser's own button styling. */
  font-family: inherit;
  font-size: inherit;
}
.provider-btn:hover { border-color: var(--primary); background: var(--primary-soft); text-decoration: none; }
.provider-btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.provider-btn .logo { width: 32px; height: 32px; flex: none; border-radius: var(--r-sm); }
.provider-btn .chevron { margin-left: auto; color: var(--text-faint); }

/* --- forms ----------------------------------------------------------- */
.field { display: block; margin-bottom: var(--s-4); }
.field > label {
  display: block;
  margin-bottom: var(--s-2);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text-muted);
}
.input {
  width: 100%;
  min-height: var(--tap-target);
  padding: 0 var(--s-4);
  font: inherit;
  color: var(--text);
  background: var(--card);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
}
.input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-soft); }
.input.is-invalid { border-color: var(--danger); }
.field-error { margin-top: var(--s-2); font-size: var(--fs-sm); color: var(--danger); }

/* Amount input with its UZS suffix.
   The suffix is centred on .amount-wrap, not on .amount-field: the field also
   holds the label and the limits line, so centring on it drops the suffix
   below the box. */
.amount-field .amount-wrap { position: relative; }
.amount-field .input {
  font-size: var(--fs-2xl);
  font-weight: 700;
  height: 68px;
  padding-right: 88px;
  text-align: right;
}
/* Chrome and Firefox put stepper arrows on number inputs, which collide with
   the suffix and invite mis-taps on a phone. */
.amount-field .input::-webkit-outer-spin-button,
.amount-field .input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.amount-field .input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
/* The pay page renders the widget directly rather than through the shared
   field partial, so the invalid state is carried by the wrapper. */
.amount-field.has-error .input { border-color: var(--danger); }
.amount-field.has-error .input:focus {
  box-shadow: 0 0 0 3px var(--danger-soft);
}
.amount-field .amount-suffix {
  position: absolute;
  right: var(--s-4);
  top: 50%;
  transform: translateY(-50%);
  font-weight: 600;
  color: var(--text-faint);
  pointer-events: none;
}

/* --- toggle switch --------------------------------------------------- */
.toggle { position: relative; display: inline-block; width: 46px; height: 26px; flex: none; }
.toggle input { opacity: 0; width: 0; height: 0; }
.toggle .track {
  position: absolute; inset: 0;
  background: var(--border-strong);
  border-radius: var(--r-pill);
  transition: background .15s ease;
  cursor: pointer;
}
.toggle .track::before {
  content: ""; position: absolute;
  width: 20px; height: 20px; left: 3px; top: 3px;
  background: #fff; border-radius: 50%;
  transition: transform .15s ease;
}
.toggle input:checked + .track { background: var(--success); }
.toggle input:checked + .track::before { transform: translateX(20px); }

/* --- badges ---------------------------------------------------------- */
.badge {
  display: inline-block;
  padding: 2px 10px;
  border-radius: var(--r-pill);
  font-size: var(--fs-xs);
  font-weight: 600;
}
.badge-success { background: var(--success-soft); color: var(--success); }
.badge-warning { background: var(--warning-soft); color: var(--warning); }
.badge-danger  { background: var(--danger-soft);  color: var(--danger); }
.badge-muted   { background: var(--bg);           color: var(--text-muted); }
/* A payment still in flight. It is neither good news nor bad yet, so it gets
   the neutral brand colour rather than borrowing success or warning. */
.badge-info    { background: var(--primary-soft); color: var(--primary); }

/* --- standalone links are targets, not words -------------------------- */
/* A link that sits alone on its line — "Forgot your password?", "See all",
   the support number on the pay page — is something a thumb has to hit, so
   it needs a hit area, not just a hit word. At 12–14px these were 17–22px
   tall, well under the 24px WCAG 2.2 asks for and nowhere near the 44px a
   fingertip actually covers.
   The padding grows the box and the equal negative margin puts the text back
   exactly where it was, so nothing on any page moves. Links inside a run of
   prose are left alone: enlarging those would overlap the lines above and
   below, and a word inside a sentence is exempt from the rule anyway. */
.pay-column p > a:only-child,
.pay-footer a,
.row-between > a.small,
.link-button {
  display: inline-block;
  padding: 14px 6px;
  margin: -14px -6px;
}

/* --- toast / messages ------------------------------------------------ */
.toast {
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: var(--card);
  box-shadow: var(--shadow-sm);
  margin-bottom: var(--s-3);
}
.toast-success { background: var(--success-soft); border-color: var(--success); }
.toast-error   { background: var(--danger-soft);  border-color: var(--danger); }
.toasts { margin-bottom: var(--s-4); }
.toasts:empty { display: none; }

/* --- language switcher ----------------------------------------------- */
.lang-switch { display: inline-flex; gap: var(--s-1); background: var(--card);
  border: 1px solid var(--border); border-radius: var(--r-pill); padding: 3px; }
.lang-switch a,
.lang-switch button {
  /* 44px tall, not 30. Three small pills side by side are exactly the kind of
     target a thumb misses, and the person reaching for them is by definition
     someone who cannot read the current page. */
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 4px 16px;
  border: none;
  background: transparent;
  border-radius: var(--r-pill);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text-muted);
  cursor: pointer;
}
.lang-switch a:hover,
.lang-switch button:hover { background: var(--bg); text-decoration: none; }
.lang-switch a.active,
.lang-switch button.active { background: var(--primary); color: var(--text-on-primary); }

/* --- trust / support block ------------------------------------------- */
.trust {
  display: flex; align-items: center; justify-content: center; gap: var(--s-2);
  color: var(--text-faint); font-size: var(--fs-sm);
}
/* Reserved for the pay page's support block in Phase 4 — not dead code. */
.support-block {
  border-top: 1px solid var(--border);
  padding-top: var(--s-4);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}


/* ===== nav.css ===== */

/* Navigation: marketing header, mobile drawer, notification bell.
   Both the drawer and the bell are checkbox-driven, so they work with
   JavaScript off. */

/* --- header shell ----------------------------------------------------- */
.site-header {
  background: var(--card);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 40;
}
.nav-bar {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  min-height: 68px;
}
.site-logo {
  font-weight: 800;
  font-size: var(--fs-lg);
  color: var(--navy);
  letter-spacing: -.02em;
  white-space: nowrap;
}
.site-logo:hover { text-decoration: none; }
.site-logo span { color: var(--primary); }

.site-nav {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  margin-left: auto;
}
.site-nav > a {
  color: var(--text-muted);
  font-weight: 500;
  font-size: var(--fs-sm);
  white-space: nowrap;
}
.site-nav > a:hover { color: var(--primary); text-decoration: none; }
.site-nav > a.active { color: var(--primary); font-weight: 600; }
.site-nav .nav-cta { color: var(--text-on-primary); min-height: 40px; padding: 0 var(--s-4); }
.site-nav .nav-cta:hover { color: var(--text-on-primary); }
.nav-divider { width: 1px; height: 24px; background: var(--border); }

/* The bell lives here on every width; the burger joins it on mobile. */
.nav-actions { display: flex; align-items: center; gap: var(--s-3); }

/* Keep the toggles focusable for keyboard users instead of display:none. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.nav-toggle:focus-visible ~ .container .nav-burger,
.bell-toggle:focus-visible + .bell-button {
  /* Visible, not decorative: --primary-soft here was 1.06:1 against the bar
     it sits on. */
  outline: 3px solid var(--primary);
  outline-offset: 2px;
  border-color: var(--primary);
}

/* --- burger ----------------------------------------------------------- */
.nav-burger {
  display: none;
  width: 44px;
  height: 44px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  cursor: pointer;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 5px;
  background: var(--card);
}
.nav-burger span {
  display: block;
  width: 20px;
  height: 2px;
  border-radius: 2px;
  background: var(--navy);
  transition: transform .2s ease, opacity .2s ease;
}
.nav-toggle:checked ~ .container .nav-burger span:nth-child(1),
.side-toggle:checked ~ .merchant-topbar .nav-burger span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle:checked ~ .container .nav-burger span:nth-child(2),
.side-toggle:checked ~ .merchant-topbar .nav-burger span:nth-child(2) { opacity: 0; }
.nav-toggle:checked ~ .container .nav-burger span:nth-child(3),
.side-toggle:checked ~ .merchant-topbar .nav-burger span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* --- scrim: tap anywhere outside an open drawer to close it ------------ */
/* Layering, because getting this wrong dims the menu itself and swallows
   every tap on it:  page  <  scrim (35)  <  header bar (41)  <  drawer (45). */
.drawer-scrim {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(27, 42, 65, .35);
  z-index: 35;
  cursor: default;
}
.nav-toggle:checked ~ .drawer-scrim,
.side-toggle:checked ~ .drawer-scrim { display: block; }

/* A drawer left open on a phone must not dim a desktop window after resize. */
@media (min-width: 901px) {
  .drawer-scrim { display: none !important; }
}

/* --- mobile drawer ---------------------------------------------------- */
@media (max-width: 900px) {
  .nav-burger { display: flex; }
  .nav-actions { margin-left: auto; }

  /* Above the scrim, so the logo, bell and burger stay tappable while open. */
  .nav-bar { position: relative; z-index: 41; }

  .site-nav {
    position: absolute;
    z-index: 45;
    left: 0;
    right: 0;
    top: 100%;
    margin-left: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--card);
    border-bottom: 1px solid var(--border);
    box-shadow: var(--shadow-lg);
    padding: var(--s-2) var(--s-4) var(--s-4);

    /* Collapsed by default; the checkbox opens it. */
    max-height: 0;
    overflow: hidden;
    visibility: hidden;
    transition: max-height .25s ease, visibility .25s;
  }
  .nav-toggle:checked ~ .container .site-nav {
    max-height: 80vh;
    overflow-y: auto;
    visibility: visible;
  }

  .site-nav > a {
    padding: var(--s-3) var(--s-2);
    font-size: var(--fs-base);
    border-bottom: 1px solid var(--border);
  }
  .site-nav .nav-cta {
    margin-top: var(--s-3);
    min-height: var(--tap-target);
    border-bottom: none;
    justify-content: center;
  }
  .nav-divider { display: none; }
  .site-nav .lang-switch { margin-top: var(--s-4); align-self: flex-start; }
}

/* --- notification bell ------------------------------------------------ */
.bell { position: relative; }
.bell-button {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  color: var(--text-muted);
  background: var(--card);
  cursor: pointer;
}
.bell-button:hover { color: var(--primary); border-color: var(--primary); }
.bell-count {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: var(--r-pill);
  background: var(--danger);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}

.bell-panel {
  display: none;
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  width: min(340px, calc(100vw - 32px));
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  z-index: 50;
  overflow: hidden;
}
.bell-toggle:checked ~ .bell-panel { display: block; }

.bell-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border-bottom: 1px solid var(--border);
}
.bell-read { margin: 0; flex: none; }
.bell-head > strong { white-space: nowrap; }
.link-button {
  border: none;
  background: none;
  padding: 0;
  font: inherit;
  font-size: var(--fs-sm);
  color: var(--primary);
  cursor: pointer;
}
.link-button:hover { text-decoration: underline; }

.bell-list { list-style: none; margin: 0; padding: 0; max-height: 340px; overflow-y: auto; }
.bell-item {
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-sm);
}
.bell-item.unread { background: var(--primary-soft); }

/* The whole row is a submit button, so clicking the message marks it read. */
.notif-row {
  display: flex;
  gap: var(--s-3);
  width: 100%;
  padding: var(--s-3) var(--s-4);
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.notif-row:hover { background: rgba(37, 99, 235, .07); }
.notif-row:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
.notif-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.notif-text strong { font-weight: 600; }
.notif-body { overflow-wrap: anywhere; }
.bell-item .dot { width: 8px; height: 8px; border-radius: 50%; margin-top: 6px; flex: none; }
.dot-info { background: var(--primary); }
.dot-success { background: var(--success); }
.dot-warning { background: var(--warning); }
.bell-empty { padding: var(--s-5) var(--s-4); text-align: center; }
.faint { color: var(--text-faint); }
.bell-all {
  display: block;
  padding: var(--s-3);
  text-align: center;
  font-size: var(--fs-sm);
  font-weight: 600;
  background: var(--bg);
}
.bell-all:hover { text-decoration: none; background: var(--primary-soft); }


/* ===== layouts.css ===== */

/* Layout shells: marketing page, merchant portal, pay and auth columns.
   Navigation itself lives in nav.css. */

/* --- marketing -------------------------------------------------------- */
.site-main { min-height: 60vh; padding: var(--s-7) 0; }

.site-footer {
  background: var(--navy);
  color: #b9c6d8;
  padding: var(--s-6) 0 var(--s-5);
  font-size: var(--fs-sm);
  margin-top: var(--s-7);
}
/* Footer links are a stacked list of separate destinations, so each one is a
   target a thumb has to land on without catching its neighbour. At 14px the
   link box was 22px tall with 8px between — under the 24px WCAG 2.2 asks for,
   and close enough together to mis-tap. Padding rather than a negative margin
   here: growing the gap between them is the point, not a side effect. */
.site-footer a {
  color: #dbe5f2;
  display: block;
  padding: 12px 0;
  margin-bottom: 0;
}
.site-footer h4 { color: #fff; font-size: var(--fs-sm); margin-bottom: var(--s-3); }
.footer-logo { color: #fff; margin-bottom: var(--s-3); }
.footer-logo span { color: #7ea6f5; }
.footer-grid {
  display: grid;
  grid-template-columns: 1.5fr 1fr 1fr 1fr;
  gap: var(--s-5);
}
.footer-bottom {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-top: var(--s-6);
  padding-top: var(--s-4);
  border-top: 1px solid rgba(255, 255, 255, .12);
}
/* The phone number and Telegram link sit inside a line of text, so they keep
   flowing with it — but they are still things a thumb aims at, so the box
   grows around the words without moving them. */
.footer-bottom a {
  display: inline-block;
  margin: -13px 0;
  padding: 13px 4px;
}

@media (max-width: 760px) {
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .site-main { padding: var(--s-5) 0; }
}

/* --- merchant portal --------------------------------------------------- */
.merchant-shell { min-height: 100vh; display: flex; flex-direction: column; }

.merchant-topbar {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-height: var(--topbar-h);
  padding: 0 var(--s-5);
  background: var(--card);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 40;
}
.merchant-topbar .nav-actions { margin-left: auto; }

.merchant-body { display: flex; flex: 1; min-height: 0; }

.merchant-sidebar {
  width: 248px;
  flex: none;
  background: var(--card);
  border-right: 1px solid var(--border);
  padding: var(--s-5) var(--s-4);
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
.merchant-sidebar a {
  display: block;
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-md);
  color: var(--text-muted);
  font-weight: 600;
  font-size: var(--fs-sm);
}
.merchant-sidebar a:hover { background: var(--bg); text-decoration: none; }
.merchant-sidebar a.active { background: var(--primary-soft); color: var(--primary); }
.merchant-sidebar .spacer { margin-top: auto; }

.merchant-main { flex: 1; padding: var(--s-5); min-width: 0; }

.settings-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: var(--s-5);
  align-items: start;
  max-width: 960px;
}
.settings-grid h3 { margin-bottom: var(--s-4); }

/* Mobile: the sidebar collapses into a drawer under the top bar. */
@media (max-width: 900px) {
  .merchant-sidebar {
    position: fixed;
    top: var(--topbar-h);
    bottom: 0;
    left: 0;
    width: min(280px, 82vw);
    z-index: 45;
    box-shadow: var(--shadow-lg);
    transform: translateX(-100%);
    transition: transform .25s ease;
    overflow-y: auto;
  }
  .side-toggle:checked ~ .merchant-body .merchant-sidebar { transform: translateX(0); }
  .merchant-main { padding: var(--s-4); }
}

@media (min-width: 901px) {
  /* The burger is a mobile control only. */
  .merchant-topbar .nav-burger { display: none; }

  /* The sidebar stays put while the page scrolls. Without this it is an
     ordinary flex child, so on a long page — the integrations page with a
     provider open, say — the navigation and Sign out scroll off the top and
     the seller has to scroll back up to go anywhere.

     `align-self: flex-start` is the part that makes it work: flex children
     stretch to the row's height by default, and a sticky element with no
     spare height inside its container has nothing to stick to. */
  .merchant-sidebar {
    position: sticky;
    top: var(--topbar-h);
    align-self: flex-start;
    height: calc(100vh - var(--topbar-h));
    overflow-y: auto;
    /* Its own scrollbar, if the menu ever outgrows a short window. */
    overscroll-behavior: contain;
  }
}

/* --- pay page and auth column ------------------------------------------ */
.pay-shell {
  min-height: 100vh;
  display: flex; flex-direction: column; align-items: center;
  padding: var(--s-5) var(--s-4) var(--s-6);
}
.pay-column { width: 100%; max-width: var(--pay-width); }

/* One card holds the whole payment, so it reads as a single object being
   filled in rather than a stack of loose parts on a background. */
.pay-card { padding: var(--s-6) var(--s-5) var(--s-5); }

.pay-business { text-align: center; margin-bottom: var(--s-6); }
.pay-business .avatar {
  width: 56px; height: 56px; margin: 0 auto var(--s-3);
  border-radius: var(--r-lg); background: var(--primary-soft);
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; color: var(--primary); font-size: var(--fs-lg);
}
.pay-business .avatar-img { object-fit: cover; }
.pay-name {
  margin: 0;
  font-size: var(--fs-xl);
  font-weight: 700;
  line-height: 1.25;
  /* A long business name must wrap, not push the card wide. */
  overflow-wrap: anywhere;
}
.pay-welcome { margin: var(--s-2) 0 0; }

.pay-notice { text-align: center; padding: var(--s-4) 0 var(--s-2); }
.pay-notice h2 { margin: 0 0 var(--s-2); font-size: var(--fs-lg); }
.pay-notice p { margin: 0; }

.pay-footer { margin-top: var(--s-5); text-align: center; }

/* --- pay page: amount, provider choice, result ------------------------ */
.pay-form { display: block; }
.amount-limits { margin-top: var(--s-2); }
.pay-choose {
  margin: var(--s-5) 0 var(--s-3);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text-muted);
}
.pay-testnote {
  margin: var(--s-4) 0 0;
  text-align: center;
  color: var(--warning);
}

/* The provider list is a list: hairline-separated rows of equal height, not
   six floating slabs. The logo sits left, the chevron right, and nothing
   competes with the amount above it. */
.pay-providers {
  display: flex; flex-direction: column;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  overflow: hidden;
}
.pay-providers .provider-btn {
  gap: var(--s-3);
  min-height: 60px;
  border: 0;
  border-radius: 0;
  border-bottom: 1px solid var(--border);
  background: var(--card);
}
.pay-providers .provider-btn:last-child { border-bottom: 0; }
.pay-providers .provider-btn:hover,
.pay-providers .provider-btn:focus-visible { background: var(--primary-soft); }
.pay-providers .provider-btn:active { background: var(--bg); }
.provider-name { font-weight: 700; font-size: var(--fs-base); }
.provider-btn .chevron {
  margin-left: auto;
  display: flex; align-items: center;
  color: var(--text-faint);
}
/* Provider logos have wildly different aspect ratios — Paynet is four times
   wider than it is tall, the card mark is square. Fix the height and let the
   width follow, or the wide ones shrink to nothing inside a square box. */
.provider-mark {
  width: auto; height: 28px;
  max-width: 104px;
  object-fit: contain; object-position: left center;
  flex: none;
}
/* An icon mark sits next to its name, so it gets the width of an icon. */
.provider-mark + .provider-name { margin-left: calc(var(--s-1) * -1); }
.provider-btn .badge { margin-left: var(--s-2); }

/* Flex-wrap rather than inline text, so a long phone number breaks onto its
   own line cleanly instead of dragging "Telegram" down with it. */
.support-block {
  display: flex; flex-wrap: wrap;
  align-items: center; justify-content: center;
  gap: var(--s-1) var(--s-3);
}
.support-block a {
  font-weight: 600;
  white-space: nowrap;
  /* These are the links a customer taps when a payment has just failed, and
     they were 22px tall. Padded to a real target without changing how the
     line looks — the extra height is transparent. */
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--s-1);
}

.result-card { padding: var(--s-6) var(--s-5); }
/* The outcome is this page's heading, so it is an h1 — but it keeps the size
   it had as an h3. It sits above the amount, which is what the eye should
   land on first; a heading scaled to match its level would fight it. */
.result-heading {
  font-size: var(--fs-lg);
  font-weight: 700;
  margin-bottom: var(--s-2);
}
.result-mark {
  width: 64px; height: 64px; margin: 0 auto var(--s-4);
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
}
.result-ok { background: var(--success-soft); color: var(--success); }
.result-off { background: var(--bg); color: var(--text-faint); }
.result-wait { background: var(--primary-soft); color: var(--primary); }
.result-amount {
  margin: var(--s-3) 0 0;
  font-size: var(--fs-2xl);
  font-weight: 800;
}
.result-amount .unit { font-size: var(--fs-base); font-weight: 600; color: var(--text-faint); }
.result-actions {
  display: flex; gap: var(--s-3); justify-content: center;
  margin-top: var(--s-5); flex-wrap: wrap;
}

.spinner {
  width: 28px; height: 28px;
  border: 3px solid var(--primary-soft);
  border-top-color: var(--primary);
  border-radius: 50%;
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
/* Someone who asked for less motion gets a still ring, not a spinning one. */
@media (prefers-reduced-motion: reduce) {
  .spinner { animation: none; }
}


/* ===== marketing.css ===== */

/* Marketing page sections. */

.hero {
  display: grid;
  grid-template-columns: 1.1fr .9fr;
  gap: var(--s-7);
  align-items: center;
  padding: var(--s-6) 0 var(--s-7);
}
.hero h1 { font-size: clamp(30px, 5vw, 44px); letter-spacing: -.02em; }
.hero .lead { font-size: var(--fs-lg); color: var(--text-muted); max-width: 46ch; }
.hero-actions { display: flex; flex-wrap: wrap; gap: var(--s-3); margin-top: var(--s-5); }

/* Image frame for the card artwork. Reserves the space before the file
   loads so the hero never jumps, and centres whatever is dropped in. */
.card-frame {
  margin: 0 0 0 auto;
  max-width: 460px;
  width: 100%;
  aspect-ratio: 1.586;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--card);
  border: 1px solid #000000;
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.card-frame img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  display: block;
}

.section { padding: var(--s-7) 0; }
.section-head { max-width: 62ch; margin-bottom: var(--s-6); }
.section-head h2 { letter-spacing: -.01em; }
.section-head p { color: var(--text-muted); margin: 0; }

/* --- the four steps --------------------------------------------------- */
.steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s-5); }
.step { position: relative; }
.step .num {
  width: 40px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-pill);
  background: var(--primary); color: #fff;
  font-weight: 800; margin-bottom: var(--s-3);
  flex: none;
}
.step h3 { font-size: var(--fs-lg); margin-bottom: var(--s-2); }
.step p { color: var(--text-muted); font-size: var(--fs-sm); margin: 0; }

/* Connecting line between the steps on wide screens. */
@media (min-width: 901px) {
  .step:not(:last-child)::after {
    content: "";
    position: absolute;
    top: 20px;
    left: 52px;
    right: calc(var(--s-5) * -1 + 12px);
    height: 2px;
    background: var(--border-strong);
  }
}

/* --- provider logo slots ---------------------------------------------- */
.provider-strip {
  display: flex; flex-wrap: wrap; gap: var(--s-4);
  align-items: center; justify-content: center;
  padding: var(--s-5) 0;
  list-style: none;
  margin: 0;
}
.provider-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 140px;
  height: 56px;
  padding: var(--s-2) var(--s-3);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
}
.provider-logo img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  display: block;
}

.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s-5); }
.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s-5); }

.benefit h3 { font-size: var(--fs-lg); }
.benefit p { color: var(--text-muted); font-size: var(--fs-sm); margin: 0; }

.price-card { text-align: center; }
.price-amount {
  font-size: clamp(32px, 6vw, 44px);
  font-weight: 800;
  color: var(--navy);
  letter-spacing: -.02em;
}
.price-amount .unit { font-size: var(--fs-base); font-weight: 600; color: var(--text-muted); }
.price-list { list-style: none; padding: 0; margin: var(--s-4) 0 0; text-align: left; }
.price-list li {
  padding: var(--s-2) 0 var(--s-2) var(--s-5);
  position: relative;
  font-size: var(--fs-sm);
  color: var(--text-muted);
}
.price-list li::before {
  content: "✓";
  position: absolute; left: 0;
  color: var(--success); font-weight: 700;
}

.cta-band {
  background: var(--navy);
  color: #fff;
  border-radius: var(--r-lg);
  padding: var(--s-7) var(--s-6);
  text-align: center;
}
.cta-band h2 { color: #fff; }
.cta-band p { color: #b9c6d8; max-width: 52ch; margin: 0 auto var(--s-5); }

.faq-item {
  border-bottom: 1px solid var(--border);
  padding: var(--s-4) 0;
}
.faq-item:last-child { border-bottom: none; }
.faq-item summary {
  cursor: pointer;
  font-weight: 600;
  list-style: none;
  display: flex;
  justify-content: space-between;
  gap: var(--s-4);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after { content: "+"; color: var(--primary); font-size: var(--fs-xl); line-height: 1; }
.faq-item[open] summary::after { content: "−"; }
.faq-item p { margin: var(--s-3) 0 0; color: var(--text-muted); font-size: var(--fs-sm); }

.prose { max-width: 68ch; }
.prose h2 { margin-top: var(--s-6); font-size: var(--fs-xl); }
.prose li { margin-bottom: var(--s-2); color: var(--text-muted); }

.contact-methods { display: flex; flex-direction: column; gap: var(--s-3); }
.contact-method {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-4);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  font-weight: 600;
}
.contact-method:hover { border-color: var(--primary); text-decoration: none; background: var(--primary-soft); }

@media (max-width: 900px) {
  .hero { grid-template-columns: 1fr; gap: var(--s-5); padding: var(--s-5) 0; }
  .card-frame { margin: 0 auto; }
  .grid-3, .grid-2 { grid-template-columns: 1fr; }
  .section { padding: var(--s-6) 0; }

  /* On a phone the four steps become a vertical timeline: number on the
     left, text beside it, a line joining them. Stacking number-above-text
     left the column looking loose and disconnected. */
  .steps {
    display: block;
    padding-left: 4px;
  }
  .step {
    display: grid;
    grid-template-columns: 40px 1fr;
    column-gap: var(--s-4);
    padding-bottom: var(--s-5);
  }
  .step:last-child { padding-bottom: 0; }
  .step .num { grid-row: 1 / span 2; margin-bottom: 0; }
  .step h3 { margin: 8px 0 var(--s-1); font-size: var(--fs-base); }
  .step p { grid-column: 2; }

  /* The joining line runs from under one number down to the next. */
  .step:not(:last-child)::before {
    content: "";
    position: absolute;
    left: 19px;
    top: 44px;
    bottom: 8px;
    width: 2px;
    background: var(--border-strong);
  }

  .provider-logo { width: 128px; height: 52px; }
}

@media (max-width: 560px) {
  .cta-band { padding: var(--s-5) var(--s-4); }
  .provider-strip { gap: var(--s-3); }
  .provider-logo { width: calc(50% - var(--s-3)); }
}


/* ===== integrations.css ===== */

/* Integrations page and payment-page settings.
   The accordion is a plain <details>, matching the FAQ — no JavaScript. */

.integrations-summary {
  display: flex;
  align-items: center;
  gap: var(--s-6);
  flex-wrap: wrap;
  margin-bottom: var(--s-5);
  max-width: 860px;
}
.summary-count {
  font-size: var(--fs-3xl);
  font-weight: 800;
  color: var(--primary);
  line-height: 1;
}
.summary-count span { font-size: var(--fs-lg); color: var(--text-faint); }

.integration-list {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  max-width: 860px;
}

.integration {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.integration > summary {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-4) var(--s-5);
  cursor: pointer;
  list-style: none;
  min-height: var(--tap-target);
}
.integration > summary::-webkit-details-marker { display: none; }
.integration > summary:hover { background: var(--bg); }

.integration-logo {
  height: 28px;
  width: auto;
  max-width: 120px;
  object-fit: contain;
  display: block;
  flex: none;
}
.integration-name { font-weight: 700; font-size: var(--fs-lg); }

/* The badge sits hard right, the chevron after it. */
.integration > summary .badge { margin-left: auto; }
.integration-chevron {
  color: var(--text-faint);
  font-size: var(--fs-xl);
  line-height: 1;
  transition: transform .15s ease;
}
.integration[open] > summary .integration-chevron { transform: rotate(90deg); }

.integration-body {
  padding: var(--s-5);
  border-top: 1px solid var(--border);
  background: var(--bg);
}
.integration-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-top: var(--s-4);
  padding-top: var(--s-4);
  border-top: 1px solid var(--border);
}
.integration-actions form { margin: 0; }

/* --- payment page settings -------------------------------------------- */
.paypage-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-5);
  align-items: start;
  max-width: 1000px;
}
.paypage-preview {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--bg);
  height: 520px;
}
.paypage-preview iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

@media (max-width: 900px) {
  .paypage-grid { grid-template-columns: 1fr; }
  .integration > summary { padding: var(--s-3) var(--s-4); gap: var(--s-3); }
  .integration-logo { height: 24px; max-width: 92px; }
  .integration-body { padding: var(--s-4); }
}


/* ===== reports.css ===== */

/* Phase 6: the seller's dashboard and transactions ledger.
   Kept out of layouts.css because none of it is a shell — these are the
   components two pages are built from. */

/* --- headline figures --------------------------------------------------- */

.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--s-4);
  margin-bottom: var(--s-5);
}

.stat { display: flex; flex-direction: column; gap: var(--s-2); }

.stat-label {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text-muted);
}

.stat-value {
  font-size: var(--fs-2xl);
  font-weight: 800;
  line-height: 1.1;
  /* Tabular figures, so a row of amounts lines up on the decimal instead of
     jittering as the digits change. */
  font-variant-numeric: tabular-nums;
}
.stat-value span {
  font-size: var(--fs-base);
  font-weight: 600;
  color: var(--text-faint);
}

/* The number the page exists to answer. Everything else on this row is
   context for it, so it gets the weight and the colour. */
.stat-lead { border: 1px solid var(--primary-soft); }
.stat-lead .stat-value { font-size: var(--fs-3xl); color: var(--primary); }

/* --- the 14-day bars ---------------------------------------------------- */

.bars {
  display: flex;
  align-items: flex-end;
  gap: var(--s-2);
  /* Enough height to tell a tall day from a short one, not so much that the
     card dominates a page whose point is the numbers above it. */
  height: 140px;
}

.bar-col {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  height: 100%;
}

.bar-track {
  flex: 1;
  display: flex;
  align-items: flex-end;
  background: var(--bg);
  border-radius: var(--r-sm);
  overflow: hidden;
}

.bar-fill {
  width: 100%;
  background: var(--primary-mid);
  border-radius: var(--r-sm);
  /* A day with nothing still gets a visible baseline: a column drawn at zero
     height reads as missing data rather than as a quiet day. */
  min-height: 3px;
}

.bar-today .bar-fill { background: var(--primary); }

.bar-label {
  font-size: var(--fs-xs);
  color: var(--text-faint);
  text-align: center;
  white-space: nowrap;
}
.bar-today .bar-label { color: var(--primary); font-weight: 600; }

/* Fourteen labels do not fit across a phone. The bars still do, so the
   labels go rather than the chart. */
@media (max-width: 640px) {
  .bar-label { display: none; }
  .bars { height: 110px; }
}

/* --- the dashboard's lower half ----------------------------------------- */

.dash-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: var(--s-4);
  align-items: start;
  margin-top: var(--s-5);
}

.mini-table { width: 100%; border-collapse: collapse; }
/* Cells need horizontal padding, not just vertical. With none, a column whose
   text fills its width touches the next one and the row reads as one word:
   "Multicard42 000" on a phone, where the columns are narrowest. The first
   and last cells stay flush with the card's own edges. */
.mini-table td {
  padding: var(--s-3) var(--s-2);
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
.mini-table td:first-child { padding-left: 0; }
.mini-table td:last-child { padding-right: 0; }
.mini-table tr:last-child td { border-bottom: none; }

/* The recent-payments table carries four columns — date, method, amount and a
   status badge — in a card that is 343px wide on a phone. It did not fit: the
   row spilled about 7px past the card's edge, which showed up as a clipped
   badge on the longest status word ("Muvaffaqiyatsiz").
   Below 600px it becomes two lines, the same shape as the full transactions
   table, so the two pages read alike. The three-column tables beside it fit
   as they are and are left alone. */
@media (max-width: 600px) {
  .recent-table, .recent-table tbody { display: block; }
  .recent-table tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline;
    gap: var(--s-1) var(--s-3);
    padding: var(--s-3) 0;
    border-bottom: 1px solid var(--border);
  }
  .recent-table tr:last-child { border-bottom: none; }
  .recent-table td { display: block; padding: 0; border: none; }
  .recent-table td:nth-child(1) { grid-area: 1 / 1; }
  .recent-table td:nth-child(3) { grid-area: 1 / 2; }
  .recent-table td:nth-child(2) { grid-area: 2 / 1; }
  .recent-table td:nth-child(4) { grid-area: 2 / 2; justify-self: end; }
}

/* Scoped to the two tables that have money columns. A bare `.num` also
   matches the numbered step circles on the landing page — harmless today,
   because those are flex-centred, but a global class reaching into unrelated
   markup is a trap for whoever changes one of them next. */
.mini-table .num,
.txn-table .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* --- transactions: filters ---------------------------------------------- */

.txn-filters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--s-4);
  align-items: end;
  margin-bottom: var(--s-4);
}
.txn-filters .field { margin-bottom: 0; }

/* The toggle and the buttons get a full-width row rather than a grid cell:
   two buttons do not fit in a 180px column, and left in the grid they stacked
   and pulled the whole bar out of line. */
.txn-filter-bottom {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  flex-wrap: wrap;
}

.checkbox {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  cursor: pointer;
  /* The whole label is the target, not just the 13px box. */
  min-height: var(--tap-target);
  font-weight: 500;
}
.checkbox input { width: 18px; height: 18px; accent-color: var(--primary); }

.txn-filter-actions { display: flex; gap: var(--s-2); flex-wrap: wrap; }

/* --- transactions: the summary bar -------------------------------------- */

.txn-summary {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  flex-wrap: wrap;
  margin-bottom: var(--s-4);
}
.txn-summary .summary-count { font-variant-numeric: tabular-nums; }
.txn-summary-side { margin-left: auto; }
.txn-export { margin-left: var(--s-2); }

/* A sandbox view sums money that does not exist. It must not look like the
   card that shows real takings. */
.txn-summary-sandbox {
  background: var(--warning-soft);
  border: 1px solid var(--warning);
}

/* --- transactions: the table -------------------------------------------- */

/* A table that cannot shrink pushes the document wider than the phone, and
   then the whole page scrolls sideways. It scrolls inside its own box. */
.table-wrap { overflow-x: auto; padding: 0; }

.txn-table { width: 100%; border-collapse: collapse; min-width: 520px; }
.txn-table th {
  text-align: left;
  padding: var(--s-3) var(--s-4);
  font-size: var(--fs-sm);
  color: var(--text-muted);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.txn-table th.num { text-align: right; }
.txn-table td {
  padding: var(--s-3) var(--s-4);
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
.txn-table tr:last-child td { border-bottom: none; }

.txn-date { font-weight: 600; }
.txn-time { margin-left: var(--s-2); }
.txn-ref {
  display: block;
  font-size: var(--fs-xs);
  /* The reference is what a customer quotes in a support message, so it has
     to be readable character by character — monospace, and `muted` rather
     than `faint`, which at 12px on white is below the contrast a seller can
     comfortably read a random string from. */
  color: var(--text-muted);
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
}

/* On a phone the four columns need 520px and the screen has 343. The table
   scrolled inside its own box, which kept the page from scrolling sideways —
   but it also put the amount and the status, the two things a seller opens
   this page to read, off the right-hand edge, behind a sideways scroll with
   nothing on screen to suggest it was there.
   So below 600px the row stops being a row: date and amount share the first
   line, method and status the second, and nothing is hidden. The table markup
   is unchanged, because it is still a table — this is only how it is drawn
   when there is no room to draw it as one. */
@media (max-width: 600px) {
  .table-wrap { overflow-x: visible; }
  .txn-table { min-width: 0; }
  .txn-table thead { display: none; }
  .txn-table, .txn-table tbody { display: block; }
  .txn-table tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline;
    gap: var(--s-1) var(--s-3);
    padding: var(--s-3) var(--s-4);
    border-bottom: 1px solid var(--border);
  }
  .txn-table td { display: block; padding: 0; border: none; }
  .txn-table td:nth-child(1) { grid-area: 1 / 1; min-width: 0; }
  .txn-table td:nth-child(3) { grid-area: 1 / 2; }
  .txn-table td:nth-child(2) { grid-area: 2 / 1; color: var(--text-muted); }
  .txn-table td:nth-child(4) { grid-area: 2 / 2; justify-self: end; }
  /* A long reference must wrap rather than push the amount off the edge. */
  .txn-ref { overflow-wrap: anywhere; }
}

.txn-note {
  margin-top: var(--s-3);
  /* Reads as a footnote to the table above it, not as a warning. */
  max-width: 68ch;
}

.pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-4);
  flex-wrap: wrap;
  margin-top: var(--s-4);
}

/* --- error pages -------------------------------------------------------- */

.error-page { max-width: 520px; margin: var(--s-7) auto; }
.error-code {
  font-size: var(--fs-3xl);
  font-weight: 800;
  /* Faint on purpose: the number is for us, the sentence is for the reader. */
  color: var(--border-strong);
  line-height: 1;
  margin-bottom: var(--s-4);
}
.error-page h1 { font-size: var(--fs-xl); margin-bottom: var(--s-2); }

.empty-state { text-align: center; padding: var(--s-7) var(--s-5); }
.empty-state h3 { margin-bottom: var(--s-2); }
.empty-state p { margin-bottom: var(--s-4); }
