:root {
  /* The two fixed bars the case screen has to fit between. Stated here so
     the height maths appears once rather than in every calc that needs it. */
  --aj-header-h: 56px;
  --aj-tabbar-h: 56px;
  --aj-black: #000000;
  --aj-gold: #ffc700;
  --aj-gold-dark: #d4a600;
  --aj-bg: #f7f6f2;
  --aj-border: #e2ddce;
  --aj-red: #c0392b;
  --aj-green: #1e8449;
  --aj-text: #1a1a1a;
}

* { box-sizing: border-box; }
[x-cloak] { display: none !important; }

body {
  font-family: -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  background: var(--aj-bg);
  color: var(--aj-text);
  margin: 0;
}

/* ---- app splash ----
   Shown once on the way in and out, echoing the public site's opening without
   its 2.4s runtime or its product chooser. Entirely CSS: the overlay must
   clear itself even if no script ever runs, because it covers the login field.
   visibility:hidden at the end of the animation (with `forwards`) is what
   stops it swallowing taps once it has faded. */
.aj-appsplash {
  position: fixed; inset: 0; z-index: 100;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: radial-gradient(circle at 50% 42%, #17191d 0%, #0b0d10 62%);
  /* Leaves once the progress bar has filled. */
  animation: ajapp-out 300ms ease-in 1250ms forwards;
}

.aj-appsplash-stage { position: relative; display: flex; align-items: center; justify-content: center; }

/* Two rings pulsing out of the mark, the second half a beat behind. */
.aj-appsplash-ring {
  position: absolute; width: 150px; height: 150px; border-radius: 50%;
  border: 1.5px solid rgba(255, 198, 26, 0.5);
  animation: ajapp-ring 1.8s ease-out infinite;
}
.aj-appsplash-ring-late { animation-delay: 0.6s; }

.aj-appsplash-arc {
  position: absolute; width: 132px; height: 132px; border-radius: 50%;
  border: 3px solid transparent; border-top-color: var(--aj-gold);
  border-right-color: rgba(255, 198, 26, 0.35);
  animation: ajapp-spin 1.1s linear infinite;
}

.aj-appsplash-logo {
  width: 112px; height: 112px; border-radius: 26px; background: #111418;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 20px 50px -18px rgba(255, 198, 26, 0.4);
  animation: ajapp-pop 800ms cubic-bezier(0.2, 0.9, 0.3, 1.4) both;
}
.aj-appsplash-logo img { width: 74px; height: 74px; object-fit: contain; }

.aj-appsplash-word {
  margin-top: 34px; font-size: 24px; font-weight: 700; letter-spacing: -0.3px; color: #fff;
  animation: ajapp-fadeup 600ms ease 250ms both;
}
.aj-appsplash-word span { color: var(--aj-gold); }
.aj-appsplash-tagline {
  margin-top: 8px; font-size: 13.5px; font-weight: 500; letter-spacing: 0.4px;
  color: rgba(255, 255, 255, 0.5);
  animation: ajapp-fadeup 600ms ease 380ms both;
}

.aj-appsplash-track {
  margin-top: 30px; width: 190px; height: 4px; border-radius: 2px;
  background: rgba(255, 255, 255, 0.1); overflow: hidden;
}
.aj-appsplash-bar {
  display: block; height: 100%; width: 0; border-radius: 2px; background: var(--aj-gold);
  animation: ajapp-bar 1150ms ease forwards;
}

@keyframes ajapp-spin { to { transform: rotate(360deg); } }
@keyframes ajapp-pop { 0% { transform: scale(0.7); opacity: 0; } 55% { transform: scale(1.06); opacity: 1; } 100% { transform: scale(1); opacity: 1; } }
@keyframes ajapp-fadeup { from { transform: translateY(12px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
@keyframes ajapp-bar { from { width: 0; } to { width: 100%; } }
@keyframes ajapp-ring { 0% { transform: scale(0.6); opacity: 0.5; } 100% { transform: scale(1.6); opacity: 0; } }
@keyframes ajapp-out { to { opacity: 0; visibility: hidden; } }

/* A splash is decoration; for anyone who asked not to be moved, hold the mark
   still and leave sooner. The exit still runs -- it is what uncovers the app. */
@media (prefers-reduced-motion: reduce) {
  .aj-appsplash { animation: ajapp-out 1ms linear 400ms forwards; }
  .aj-appsplash-ring, .aj-appsplash-arc, .aj-appsplash-logo,
  .aj-appsplash-word, .aj-appsplash-tagline, .aj-appsplash-bar { animation: none; }
  .aj-appsplash-bar { width: 100%; }
}

/* ---- install gate ----
   The gate is CSS-driven off an attribute set in <head>, not toggled by a
   script after load: the POS must never flash into view first, and it must
   stay hidden even if no JavaScript runs at all. */
/* One block, and `display` appears in exactly one place. An earlier version
   declared the default here and the layout in a second .aj-installgate block
   further down: same selector, same specificity, so the later `display: flex`
   won and the gate covered the POS permanently -- including inside the
   installed app, where there is no install prompt to offer. Anything that
   sets display on this class outside the [data-needs-install] rule below is
   the same bug again. */
.aj-installgate {
  display: none;
  position: fixed; inset: 0; z-index: 200;
  align-items: center; justify-content: center;
  padding: 24px calc(20px + env(safe-area-inset-right, 0px)) calc(24px + env(safe-area-inset-bottom, 0px)) calc(20px + env(safe-area-inset-left, 0px));
  background: radial-gradient(circle at 50% 38%, #17191d 0%, #0b0d10 66%);
  overflow-y: auto;
}

html[data-needs-install] .aj-header,
html[data-needs-install] .aj-main,
html[data-needs-install] .aj-tabbar { display: none !important; }

html[data-needs-install] .aj-installgate { display: flex; animation: ajgate-in 260ms ease both; }

@keyframes ajgate-in { from { opacity: 0; } to { opacity: 1; } }
.aj-installgate-inner { width: 100%; max-width: 380px; text-align: center; color: #fff; }
.aj-installgate-mark {
  width: 84px; height: 84px; border-radius: 21px; display: block; margin: 0 auto 18px;
  box-shadow: 0 18px 44px -16px rgba(255, 198, 26, 0.45);
}
.aj-installgate-title { font-size: 1.35rem; font-weight: 800; margin: 0 0 10px; color: #fff; }
.aj-installgate-lead { font-size: 0.92rem; line-height: 1.5; color: rgba(255, 255, 255, 0.66); margin: 0 0 22px; }
.aj-installgate-actions .aj-btn { margin-top: 0; }
.aj-installgate-hint { font-size: 0.85rem; line-height: 1.5; color: rgba(255, 255, 255, 0.8); margin: 0; }
.aj-installgate-hint strong { color: var(--aj-gold); }

.aj-installgate-steps {
  text-align: left; margin: 0; padding-left: 1.2rem;
  font-size: 0.9rem; line-height: 1.7; color: rgba(255, 255, 255, 0.8);
}
.aj-installgate-steps strong { color: var(--aj-gold); }

.aj-installgate-note {
  margin-top: 14px; padding-top: 14px;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  color: rgba(255, 255, 255, 0.6);
}

/* ---- offline screen ---- */
.aj-offline { text-align: center; }
.aj-offline-mark { width: 64px; height: 64px; border-radius: 16px; display: block; margin: 0 auto 14px; }
.aj-offline-title { font-size: 1.15rem; font-weight: 800; margin: 0 0 8px; }
.aj-offline-lead { font-size: 0.9rem; color: #6b6656; margin: 0 0 4px; }

/* ---- app bar ----
   Leading action / centred title / trailing action, at a fixed height that
   does not change between screens -- the thing that makes a set of pages feel
   like one app rather than a site. It never scrolls: it is a flex sibling of
   .aj-main, which is the only scroll container. */
.aj-header {
  flex: 0 0 auto;
  background: var(--aj-black);
  color: #fff;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 8px;
  padding-top: env(safe-area-inset-top, 0px);
  min-height: 56px;
  border-bottom: 2px solid var(--aj-gold);
  box-shadow: 0 2px 12px -8px rgba(0, 0, 0, 0.8);
}

/* Equal-width flanks keep the title optically centred no matter how much sits
   on either side of it. */
.aj-header-left, .aj-header-right { display: flex; align-items: center; gap: 4px; flex: 1 1 0; min-width: 44px; }
.aj-header-right { justify-content: flex-end; }

.aj-header-title {
  flex: 0 1 auto; margin: 0; text-align: center;
  font-size: 1rem; font-weight: 800; letter-spacing: 0.01em; color: #fff;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.aj-header-logo { height: 32px; width: 32px; border-radius: 9px; display: block; object-fit: cover; }
.aj-header-brand { display: flex; align-items: center; }

/* 44px is the smallest reliably tappable target on a phone. */
.aj-header-icon {
  width: 44px; height: 44px; border-radius: 50%; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: none; color: #fff; cursor: pointer; text-decoration: none;
  transition: background 0.15s, color 0.15s;
}
.aj-header-icon:hover, .aj-header-icon:active { background: rgba(255, 255, 255, 0.14); color: var(--aj-gold); }
.aj-header-icon svg {
  width: 21px; height: 21px;
  fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}

.aj-header form { display: flex; }
.aj-header-user { font-size: 0.82rem; color: #cfcabb; max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aj-header-nav { display: flex; align-items: center; gap: 2px; }
.aj-header-nav a { color: #fff; text-decoration: none; font-weight: 600; font-size: 0.88rem; padding: 7px 10px; border-radius: 8px; }
.aj-header-nav a:hover { background: rgba(255, 255, 255, 0.14); color: var(--aj-gold); }
.aj-header-login { color: #fff; text-decoration: none; font-weight: 600; font-size: 0.9rem; padding: 0 8px; }
.aj-header-login:hover { color: var(--aj-gold); }

.aj-container { max-width: 900px; margin: 0 auto; padding: 1.5rem; }
.aj-container.narrow { max-width: 480px; }

/* ---- app shell ----
   The page is a fixed-height column: header and tab bar hold still and only
   .aj-main scrolls, so the chrome never slides away mid-transaction the way a
   plain long web page does. dvh (not vh) so the mobile URL bar collapsing
   doesn't leave the tab bar floating over the fold. */
html, body { height: 100%; }
body { display: flex; flex-direction: column; min-height: 100dvh; }
.aj-main { flex: 1 1 auto; overflow-y: auto; -webkit-overflow-scrolling: touch; }

.aj-tabbar { display: none; }

@media (max-width: 768px) {
  /* The tab bar takes over from the header's link row, which would otherwise
     wrap onto two lines and eat the top of every screen. The username goes
     too -- the app bar keeps one action, and identity is not urgent here. */
  .aj-header-nav, .aj-header-user { display: none; }

  .aj-tabbar {
    display: flex;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
    background: #fff; border-top: 1px solid var(--aj-border);
    padding-bottom: env(safe-area-inset-bottom, 0px);
    box-shadow: 0 -2px 12px -6px rgba(0, 0, 0, 0.25);
  }
  .aj-tab {
    flex: 1 1 0; min-width: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
    padding: 8px 4px 7px; min-height: 56px;
    color: #8a8577; text-decoration: none; font-size: 0.66rem; font-weight: 700;
    letter-spacing: 0.02em; text-align: center;
  }
  .aj-tab span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .aj-tab svg {
    width: 22px; height: 22px; flex: 0 0 auto;
    fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
  }
  .aj-tab.active { color: var(--aj-text); }
  .aj-tab.active svg { stroke: var(--aj-gold-dark); }

  /* Clear the bar so the last control on a screen is never sitting under it. */
  .aj-main { padding-bottom: calc(56px + env(safe-area-inset-bottom, 0px)); }
  .aj-container { padding: 1rem; }
}

.aj-card {
  background: #fff;
  border: 1px solid var(--aj-border);
  border-radius: 10px;
  padding: 1.5rem;
  margin-bottom: 1.25rem;
}

/* ---- login: full-screen app splash instead of a bare card under a nav bar ---- */
.aj-auth-shell {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.75rem;
  padding: 2rem 0;
}
.aj-auth-brand { display: flex; flex-direction: column; align-items: center; gap: 0.3rem; text-align: center; }
.aj-auth-logo { height: 84px; width: 84px; border-radius: 20px; box-shadow: 0 8px 24px -8px rgba(0,0,0,0.35); }
.aj-auth-brand-name { font-size: 1.35rem; font-weight: 800; letter-spacing: 0.02em; color: var(--aj-text); }
.aj-auth-brand-tagline { font-size: 0.85rem; color: #6b6656; }
.aj-auth-card { width: 100%; margin-bottom: 0; }
.aj-auth-card .aj-form input { padding: 0.75rem 0.8rem; font-size: 1.05rem; }
.aj-auth-card .aj-btn { min-height: 50px; font-size: 1.05rem; }

.aj-title { font-size: 1.4rem; margin: 0 0 1rem; }

.aj-form label { display: block; font-weight: 600; margin: 0.75rem 0 0.25rem; font-size: 0.9rem; }
.aj-form input, .aj-form select, .aj-form textarea {
  width: 100%; padding: 0.55rem; border: 1px solid var(--aj-border); border-radius: 6px; font-size: 1rem;
}

/* ---- multi-step form wizard (new transfer) ---- */
.aj-step-indicator { display: flex; align-items: center; justify-content: center; gap: 6px; margin-bottom: 1.25rem; }
.aj-step-dot {
  width: 28px; height: 28px; border-radius: 50%; flex-shrink: 0;
  background: #f0f1f3; color: #9aa0a7; border: 2px solid #e4e6e9;
  display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 0.85rem;
}
.aj-step-dot.active { background: var(--aj-gold); color: var(--aj-black); border-color: var(--aj-gold); }
.aj-step-dot.done { background: var(--aj-black); color: #fff; border-color: var(--aj-black); }
.aj-step-line { width: 32px; height: 2px; background: #e4e6e9; }
.aj-step-line.done { background: var(--aj-black); }

/* Compact amount step: a selectable card per DOP/HTG option, and the
   breakdown itself in a card, instead of the bordered <table> dump --
   dense enough to fit on screen without scrolling, even with the
   on-screen keyboard open. */
.aj-visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }

.aj-amount-type-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 0.5rem 0 1rem; }
.aj-amount-type-card {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  padding: 14px 10px; margin: 0; border: 2px solid var(--aj-border); border-radius: 10px;
  background: #fff; cursor: pointer; text-align: center; transition: border-color 0.15s, background 0.15s;
}
.aj-amount-type-card.selected { border-color: var(--aj-gold); background: #fff8e6; }
.aj-amount-type-icon { font-size: 1.4rem; line-height: 1; }
.aj-amount-type-label { font-size: 0.78rem; font-weight: 700; color: var(--aj-text); }

.aj-breakdown-card { background: var(--aj-bg); border: 1px solid var(--aj-border); border-radius: 12px; padding: 14px 16px; margin-top: 0.5rem; }
.aj-breakdown-row { display: flex; justify-content: space-between; padding: 0.2rem 0; }
.aj-breakdown-secondary { font-size: 0.8rem; color: #6b6656; }
.aj-breakdown-divider { border-top: 1px dashed var(--aj-border); margin: 0.4rem 0; }
.aj-breakdown-highlight { font-size: 0.95rem; font-weight: 700; color: var(--aj-text); }
.aj-breakdown-placeholder { color: #9aa0a7; font-size: 0.85rem; margin: 0; text-align: center; }

.aj-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; margin-top: 1.25rem; padding: 0.65rem 1.4rem;
  background: var(--aj-black); color: #fff; border: 2px solid var(--aj-black); border-radius: 6px;
  font-size: 1rem; font-weight: 600; cursor: pointer; text-decoration: none;
  transition: background 0.15s, color 0.15s;
}
.aj-btn:hover:not(:disabled), .aj-btn:active:not(:disabled) { background: var(--aj-gold); border-color: var(--aj-gold); color: var(--aj-black); }
.aj-btn.secondary { background: #fff; border-color: var(--aj-border); color: var(--aj-text); }
.aj-btn.secondary:hover:not(:disabled), .aj-btn.secondary:active:not(:disabled) { background: var(--aj-bg); border-color: var(--aj-text); color: var(--aj-text); }
.aj-btn.danger { background: var(--aj-red); border-color: var(--aj-red); }
.aj-btn.danger:hover:not(:disabled), .aj-btn.danger:active:not(:disabled) { background: #a5311f; border-color: #a5311f; color: #fff; }
.aj-btn.success { background: var(--aj-green); border-color: var(--aj-green); }
.aj-btn.success:hover:not(:disabled), .aj-btn.success:active:not(:disabled) { background: #166638; border-color: #166638; color: #fff; }
.aj-btn:disabled { background: #d9d5c8; border-color: #d9d5c8; color: #8a8577; cursor: not-allowed; }

.aj-error { color: var(--aj-red); background: #fdecea; border: 1px solid #f5c6cb; padding: 0.6rem 0.9rem; border-radius: 6px; margin-bottom: 1rem; }
.aj-notice { color: #8a6d00; background: #fff8e1; border: 1px solid #ffe08a; padding: 0.6rem 0.9rem; border-radius: 6px; margin-bottom: 1rem; }

.aj-table { width: 100%; border-collapse: collapse; }
.aj-table th, .aj-table td { text-align: left; padding: 0.55rem 0.6rem; border-bottom: 1px solid var(--aj-border); font-size: 0.92rem; }
.aj-table th { background: #eef1f5; }

.aj-badge { padding: 0.15rem 0.55rem; border-radius: 999px; font-size: 0.78rem; font-weight: 600; }
.badge-QUEUED { background: #f1efe6; color: #6b6656; }
.badge-CALLING { background: #fff3cd; color: #8a6d00; }
.badge-CONFIRMED { background: #d6f5df; color: var(--aj-green); }
.badge-CANCELLED { background: #fde2e0; color: var(--aj-red); }
/* Added late: every screen renders a status badge as badge-{{ status }},
   so an escalated case came out unstyled -- the one state that most
   wants a colour was the only one without one. */
.badge-ESCALATED { background: #ffe8cc; color: #8a4b00; }

/* ---- six-box verification code entry (_otp_code_input.html) ---- */
.aj-otp-boxes { display: flex; align-items: center; justify-content: center; gap: 8px; margin: 1.25rem 0 0.25rem; }
.aj-otp-boxes input {
  width: 46px; height: 58px; padding: 0; flex: 0 0 auto;
  border: 2px solid var(--aj-border); border-radius: 12px; background: #fff;
  font-size: 1.6rem; font-weight: 700; text-align: center; color: var(--aj-text);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.aj-otp-boxes input:focus {
  outline: none; border-color: var(--aj-gold); box-shadow: 0 0 0 3px rgba(255, 199, 0, 0.25);
}
.aj-otp-sep { width: 10px; height: 2px; background: var(--aj-border); border-radius: 2px; flex: 0 0 auto; }
.aj-otp-submit { width: 100%; }

/* Thumb-sized on a phone, without letting six boxes wrap onto a second line. */
@media (max-width: 380px) {
  .aj-otp-boxes { gap: 5px; }
  .aj-otp-boxes input { width: 40px; height: 52px; font-size: 1.4rem; border-radius: 10px; }
}

.aj-otp-display {
  font-size: 2.2rem; letter-spacing: 0.4rem; font-weight: 700;
  text-align: center; padding: 1rem; background: #fff8e1; border: 1px dashed var(--aj-gold); border-radius: 8px;
}

.aj-stub-banner {
  background: #fff3cd; border: 1px solid #ffe08a; color: #8a6d00;
  padding: 0.5rem 0.8rem; border-radius: 6px; font-size: 0.85rem; margin-bottom: 1rem;
}

/* ---- receipt ---- */
.aj-receipt-header { text-align: center; }
.aj-receipt-logo { display: block; height: 64px; width: auto; margin: 0 auto 0.4rem; }
.aj-receipt-brand { font-weight: 800; font-size: 1.15rem; letter-spacing: 0.04em; color: var(--aj-text); }
.aj-receipt-tagline { font-size: 0.78rem; color: #6b6656; margin-top: 0.15rem; }
.aj-receipt-hint { text-align: center; margin: 0.6rem 0 0; }

.aj-receipt-divider { border: none; border-top: 1px dashed var(--aj-border); margin: 0.85rem 0; }

.aj-receipt-tracking { text-align: center; }
.aj-receipt-label {
  display: block; font-size: 0.7rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.06em; color: #6b6656;
}
.aj-receipt-tracking-value { display: block; font-weight: 700; font-size: 1.05rem; letter-spacing: 0.02em; margin-top: 0.2rem; }

.aj-receipt-qr-wrap { text-align: center; margin: 0.7rem 0 0.2rem; }
.aj-receipt-qr { width: 150px; height: 150px; }

.aj-receipt-section-title {
  font-weight: 700; font-size: 0.75rem; text-transform: uppercase;
  letter-spacing: 0.05em; color: #6b6656; margin: 0.7rem 0 0.4rem;
}

.aj-receipt-row { display: flex; justify-content: space-between; gap: 0.75rem; font-size: 0.88rem; padding: 0.2rem 0; }
.aj-receipt-row span:first-child { color: #6b6656; }
.aj-receipt-row span:last-child { text-align: right; font-weight: 600; }
.aj-receipt-paid-total span:first-child { font-weight: 700; color: var(--aj-text); }
.aj-receipt-paid-total span:last-child { font-weight: 800; font-size: 1rem; }

.aj-receipt-total-row { display: flex; justify-content: space-between; align-items: baseline; padding: 0.2rem 0; }
.aj-receipt-total-row span:first-child { font-weight: 700; font-size: 0.92rem; text-transform: uppercase; letter-spacing: 0.03em; }
.aj-receipt-total-value { font-weight: 800; font-size: 1.6rem; color: var(--aj-text); }

.aj-receipt-meta { font-size: 0.78rem; color: #6b6656; }
.aj-receipt-meta span:last-child { font-weight: 600; color: #6b6656; }

.aj-receipt-footer { text-align: center; margin-top: 1rem; }
.aj-receipt-footer p { margin: 0.35rem 0; font-size: 0.85rem; }
.aj-receipt-track-link { font-size: 0.75rem; }
.aj-receipt-track-link a { word-break: break-all; }

.aj-receipt-actions { margin-top: 1.4rem; text-align: center; }

/* ---- agent panel: stat tiles + transfer cards ---- */
/* Grid auto-wraps instead of ever needing horizontal scroll to see a tile. */
.aj-stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px;
  margin: 1rem 0 1.25rem;
}
.aj-stat-tile {
  background: #fff;
  border: 1px solid var(--aj-border);
  border-left: 4px solid var(--aj-gold);
  border-radius: 10px;
  padding: 14px 16px;
}
.aj-stat-label { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: #6b6656; }
.aj-stat-value { font-size: 1.6rem; font-weight: 800; margin-top: 4px; color: var(--aj-text); }
.aj-stat-sub { font-size: 0.72rem; color: #6b6656; margin-top: 2px; }

/* The limit tile is the one stat that is also a control -- it taps through to
   the deposit form that clears it. Hover recolours only the three plain edges,
   so the left accent keeps signalling headroom rather than turning gold. */
a.aj-stat-tile { display: block; color: inherit; text-decoration: none; transition: border-color 0.15s, box-shadow 0.15s; }
a.aj-stat-tile:hover, a.aj-stat-tile:active {
  border-top-color: var(--aj-gold); border-right-color: var(--aj-gold); border-bottom-color: var(--aj-gold);
  box-shadow: 0 2px 10px -4px rgba(0,0,0,0.15);
}
.aj-stat-tile-limit { border-left-color: var(--aj-green); }
.aj-stat-tile-limit.warn { border-left-color: var(--aj-gold-dark); }
.aj-stat-tile-limit.paused { border-left-color: var(--aj-red); }
/* Smaller than a plain stat value: the bar underneath does the reading at a
   glance, so the figure is the supporting detail rather than the headline. */
.aj-stat-tile-limit .aj-stat-value { font-size: 1.15rem; }
.aj-stat-unit { font-size: 0.75rem; font-weight: 700; color: #6b6656; }

.aj-new-transfer-btn { display: flex; width: 100%; justify-content: center; margin-top: 0; }

.aj-section-header { display: flex; justify-content: space-between; align-items: baseline; margin: 1.5rem 0 0.75rem; gap: 12px; }
.aj-section-title { font-size: 1rem; font-weight: 700; margin: 1.5rem 0 0.75rem; color: var(--aj-text); }
.aj-section-header .aj-section-title { margin: 0; }
.aj-section-link { font-size: 0.85rem; font-weight: 700; color: #a8790a; text-decoration: none; white-space: nowrap; }
.aj-section-link:hover, .aj-section-link:active { color: var(--aj-gold-dark); }

.aj-transfer-cards { display: flex; flex-direction: column; gap: 10px; }
.aj-transfer-card {
  display: block; background: #fff; border: 1px solid var(--aj-border); border-radius: 10px;
  padding: 14px 16px; color: inherit; text-decoration: none; transition: border-color 0.15s, box-shadow 0.15s;
}
.aj-transfer-card:hover, .aj-transfer-card:active { border-color: var(--aj-gold); box-shadow: 0 2px 10px -4px rgba(0,0,0,0.15); }

.aj-transfer-card-top { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.aj-transfer-card-tracking { font-weight: 700; font-size: 0.92rem; }
.aj-transfer-card-beneficiary { font-size: 1rem; font-weight: 600; margin-top: 6px; }
.aj-transfer-card-meta { font-size: 0.8rem; color: #6b6656; margin-top: 2px; display: flex; gap: 6px; }
.aj-transfer-card-amounts { display: flex; gap: 24px; margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--aj-border); }
.aj-transfer-card-amount-label { display: block; font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.03em; color: #9aa0a7; font-weight: 700; }
.aj-transfer-card-amount-value { display: block; font-size: 0.95rem; font-weight: 700; margin-top: 2px; }

.aj-pagination { display: flex; gap: 8px; margin-top: 1.25rem; }
.aj-pagination a, .aj-pagination span {
  padding: 8px 14px; border: 1px solid var(--aj-border); border-radius: 8px;
  font-size: 14px; font-weight: 600; color: #3a3f46; text-decoration: none;
}
.aj-pagination .current { background: var(--aj-black); color: #fff; border-color: var(--aj-black); }

.aj-back-btn { margin-top: 1.5rem; }

.aj-empty-state { text-align: center; padding: 32px 16px; color: #9aa0a7; }

.aj-landing { display: flex; gap: 1.5rem; justify-content: center; margin-top: 3rem; flex-wrap: wrap; }
.aj-module-card {
  width: 220px; padding: 2rem 1rem; text-align: center; border-radius: 12px; border: 1px solid var(--aj-border);
  background: #fff; text-decoration: none; color: inherit; transition: transform 0.15s, box-shadow 0.15s;
}
.aj-module-card.active { border-color: var(--aj-gold); border-width: 2px; box-shadow: 0 4px 14px rgba(255,199,0,0.25); }
.aj-module-card.active:hover { transform: translateY(-2px); box-shadow: 0 6px 18px rgba(255,199,0,0.35); }
.aj-module-card.inactive { opacity: 0.5; cursor: not-allowed; }
.aj-module-card .icon { font-size: 2.5rem; display: block; margin-bottom: 0.75rem; }

/* ---- Android/POS responsive pass ---- */
/* This module is used on a vendor's Android device at the point of sale, not
   a desktop, so below 640px forms stay single-column with large tap targets,
   and the transfer-list table becomes a stacked card per row (a plain <table>
   just clips/scrolls on a phone-width screen). The app bar is a fixed-height
   row that never wraps, so it needs nothing here. */
@media (max-width: 640px) {
  .aj-container { padding: 1rem; }
  .aj-card { padding: 1.1rem; }

  .aj-btn { display: flex; width: 100%; margin-top: 1rem; }
  .aj-card form + form { margin-top: 0.75rem; }

  .aj-otp-display { font-size: 1.8rem; letter-spacing: 0.25rem; }

  .aj-table-responsive thead { display: none; }
  .aj-table-responsive, .aj-table-responsive tbody, .aj-table-responsive tr, .aj-table-responsive td {
    display: block; width: 100%;
  }
  .aj-table-responsive tr {
    border: 1px solid var(--aj-border); border-radius: 8px; margin-bottom: 0.75rem; padding: 0.4rem 0.75rem;
  }
  .aj-table-responsive td {
    display: flex; justify-content: space-between; align-items: center; gap: 1rem;
    border-bottom: 1px solid var(--aj-bg); padding: 0.5rem 0; text-align: right;
  }
  .aj-table-responsive td:last-child { border-bottom: none; }
  .aj-table-responsive td::before {
    content: attr(data-label); font-weight: 600; color: #6b6656; text-align: left;
  }
}

@media print {
  .aj-header, .aj-tabbar, .no-print { display: none !important; }
  body { background: #fff; }

  /* The receipt prints on a 58mm thermal POS printer. Without an explicit
     @page size the browser falls back to whatever page size is picked in
     the print dialog (A4/Letter/etc), and the on-screen receipt card's
     sizing (built for a browser window, not a narrow paper strip) prints
     far too large. */
  @page { size: 58mm auto; margin: 2mm; }

  .aj-container, .aj-container.narrow { max-width: 100%; padding: 0; margin: 0; }
  .aj-card { border: none; border-radius: 0; padding: 0; margin: 0; }
  .aj-title { font-size: 1rem; margin: 0 0 0.4rem; }
  .aj-table th, .aj-table td { font-size: 0.7rem; padding: 0.2rem 0.3rem; }
  p { font-size: 0.75rem; margin: 0.3rem 0; word-break: break-all; }

  .aj-receipt-logo { height: 42px !important; margin-bottom: 0.25rem !important; }
  .aj-receipt-brand { font-size: 0.95rem; }
  .aj-receipt-tagline { font-size: 0.62rem; }
  .aj-receipt-divider { margin: 0.5rem 0; }
  .aj-receipt-label { font-size: 0.6rem; }
  .aj-receipt-tracking-value { font-size: 0.82rem; }
  /* Sized generously relative to the 58mm page (~204px usable width after
     margins) -- a shrunken QR is the single biggest cause of a code that
     scans fine on screen but fails once printed on thermal paper. */
  .aj-receipt-qr { width: 160px; height: 160px; }
  .aj-receipt-section-title { font-size: 0.62rem; margin: 0.45rem 0 0.25rem; }
  .aj-receipt-row { font-size: 0.68rem; padding: 0.12rem 0; }
  .aj-receipt-paid-total span:last-child { font-size: 0.78rem; }
  .aj-receipt-total-row span:first-child { font-size: 0.72rem; }
  .aj-receipt-total-value { font-size: 1.15rem; }
  .aj-receipt-meta { font-size: 0.6rem; }
  .aj-receipt-footer p { font-size: 0.65rem; }
  .aj-receipt-track-link { font-size: 0.58rem; }
}

/* ---- in-screen tabs ----
   Two errands on one screen without stacking them into a long scroll. */
.aj-tabs { display: flex; gap: 4px; margin: 1rem 0 0.9rem; border-bottom: 1px solid var(--aj-border); }
.aj-tab-btn {
  flex: 1 1 0; min-height: 44px; padding: 0.6rem 0.5rem;
  background: none; border: none; border-bottom: 3px solid transparent; margin-bottom: -1px;
  font: inherit; font-size: 0.9rem; font-weight: 700; color: #8a8577; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
}
.aj-tab-btn.active { color: var(--aj-text); border-bottom-color: var(--aj-gold); }
.aj-tab-count {
  background: var(--aj-bg); border: 1px solid var(--aj-border); border-radius: 999px;
  padding: 0 6px; font-size: 0.7rem; font-weight: 700; color: #6b6656;
}

.aj-btn-block { width: 100%; }

/* ---- central case screen ---- */
.aj-central-filters { display: flex; gap: 6px; margin-bottom: 0.9rem; }
.aj-central-filters input, .aj-central-filters select {
  flex: 1 1 0; min-width: 0; padding: 0.5rem; border: 1px solid var(--aj-border);
  border-radius: 8px; font-size: 0.9rem;
}
.aj-central-filters .aj-btn { margin-top: 0; flex: 0 0 auto; }

.aj-ct-rows { border-top: 1px solid var(--aj-border); }
.aj-ct-rows > div {
  display: flex; justify-content: space-between; gap: 12px; align-items: baseline;
  padding: 9px 0; border-bottom: 1px solid var(--aj-border); font-size: 0.9rem;
}
.aj-ct-rows span:first-child { color: #6b6656; flex: 0 0 auto; }
.aj-ct-rows span:last-child { font-weight: 700; text-align: right; }
/* The number the operator reads aloud: monospace so a transposed digit shows. */
.aj-ct-account { font-family: monospace; font-size: 1rem; letter-spacing: 0.03em; }
.aj-ct-amount { font-size: 1.05rem; }

.aj-ct-call { padding: 9px 0; border-bottom: 1px solid var(--aj-border); }
.aj-ct-call:last-child { border-bottom: none; }
.aj-ct-call-meta { display: block; font-size: 0.75rem; color: #6b6656; margin-top: 4px; }
.aj-ct-call-note { font-size: 0.82rem; margin-top: 4px; }

.aj-check { display: flex; align-items: center; gap: 9px; font-size: 0.9rem; font-weight: 600; padding: 6px 0; }
.aj-check input { width: 20px; height: 20px; flex: 0 0 auto; }

/* A case already in this operator's hands, in the queue list. */
.aj-badge-mine { background: #fff3cd; color: #8a6d00; }

/* ---- station lock refusal ---- */
.aj-stationlock { text-align: center; }
.aj-stationlock-icon { font-size: 2rem; }
.aj-stationlock-title { font-size: 1.15rem; font-weight: 800; margin: 8px 0; }
.aj-stationlock-lead { font-size: 0.92rem; color: #6b6656; margin: 0 0 16px; }
.aj-stationlock-rows { text-align: left; border-top: 1px solid var(--aj-border); margin-bottom: 14px; }
.aj-stationlock-rows > div {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 8px 0; border-bottom: 1px solid var(--aj-border); font-size: 0.85rem;
}
.aj-stationlock-rows span:first-child { color: #6b6656; }
.aj-stationlock-rows span:last-child { font-weight: 700; font-family: monospace; }
.aj-stationlock-note { font-size: 0.8rem; color: #8a6d00; margin: 0 0 4px; }

/* ---- finance screen ----
   One hue (the brand gold, darkened so it reads against white) because there
   is one series; text stays in ink tokens throughout, so identity never rests
   on colour alone. Chrome is deliberately recessive -- no gridlines, no axis
   rules, the bars carry the shape and the labels carry the numbers. */
.aj-fin-hero { display: flex; align-items: center; gap: 18px; margin: 0.5rem 0 1.5rem; }

.aj-fin-ring { position: relative; flex: 0 0 auto; width: 128px; height: 128px; }
.aj-fin-ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.aj-fin-ring circle { fill: none; stroke-width: 10; }
.aj-fin-ring-track { stroke: #ece7d8; }
.aj-fin-ring-fill { stroke: var(--aj-gold-dark); stroke-linecap: round; transition: stroke-dashoffset 0.5s ease; }

.aj-fin-ring-centre {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
}
/* Hero figure: the number the screen leads with. */
.aj-fin-hero-value { font-size: 1.7rem; font-weight: 800; line-height: 1; color: var(--aj-text); }
.aj-fin-hero-unit { font-size: 0.68rem; font-weight: 700; letter-spacing: 0.06em; color: #8a8577; }

.aj-fin-hero-meta { flex: 1 1 auto; min-width: 0; }
.aj-fin-hero-label { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: #6b6656; }
.aj-fin-compare { font-size: 0.82rem; color: #6b6656; margin-top: 4px; }
.aj-fin-cycle {
  display: flex; flex-direction: column; gap: 2px;
  margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--aj-border);
}
.aj-fin-cycle-label { font-size: 0.7rem; color: #8a8577; }
.aj-fin-cycle-value { font-size: 1rem; font-weight: 800; color: var(--aj-text); }

/* Bars: thin, 4px rounded data-ends anchored to the baseline, 2px gaps. */
.aj-fin-bars {
  display: flex; align-items: flex-end; gap: 2px;
  background: #fff; border: 1px solid var(--aj-border); border-radius: 10px;
  padding: 12px 10px; margin-bottom: 1.5rem;
}
.aj-fin-bar { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 6px; }
.aj-fin-bar-value { font-size: 0.62rem; font-weight: 700; color: #6b6656; height: 0.9rem; }
.aj-fin-bar-track { width: 100%; height: 92px; display: flex; align-items: flex-end; }
.aj-fin-bar-fill {
  width: 100%; background: var(--aj-gold-dark);
  border-radius: 4px 4px 0 0; min-height: 0;
}
/* A day with no sales is a flat rule, not a missing bar -- absence is data. */
.aj-fin-bar-fill.empty { height: 2px !important; background: var(--aj-border); border-radius: 2px; }
.aj-fin-bar-label {
  font-size: 0.6rem; font-weight: 700; color: #8a8577; text-align: center;
  text-transform: uppercase; letter-spacing: 0.02em; line-height: 1.25;
}
.aj-fin-bar-label span { display: block; font-size: 0.7rem; color: var(--aj-text); }

.aj-fin-count {
  background: var(--aj-bg); border: 1px solid var(--aj-border); border-radius: 999px;
  padding: 1px 9px; font-size: 0.75rem; font-weight: 700; color: #6b6656;
}

.aj-fin-sort { display: flex; gap: 6px; margin-bottom: 0.9rem; }
.aj-fin-sort-btn {
  flex: 1 1 0; text-align: center; padding: 8px 6px; min-height: 40px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--aj-border); border-radius: 8px; background: #fff;
  font-size: 0.8rem; font-weight: 700; color: #6b6656; text-decoration: none;
}
.aj-fin-sort-btn.active { border-color: var(--aj-gold); background: #fffaeb; color: var(--aj-text); }

.aj-fin-earned { color: #a8790a; }

/* The commission card on the deposits screen is a link into all of this. */
a.aj-cycle { display: block; text-decoration: none; color: inherit; transition: border-color 0.15s, box-shadow 0.15s; }
a.aj-cycle:hover, a.aj-cycle:active { border-color: var(--aj-gold); box-shadow: 0 2px 10px -4px rgba(0, 0, 0, 0.15); }

/* ---- accumulated commission for the current cycle ---- */
.aj-cycle {
  background: #fff; border: 1px solid var(--aj-border); border-left: 4px solid var(--aj-gold);
  border-radius: 10px; padding: 12px 14px; margin-bottom: 1.25rem;
}
.aj-cycle-row { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.aj-cycle-label { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: #6b6656; }
.aj-cycle-value { font-size: 1.25rem; font-weight: 800; color: var(--aj-text); }
.aj-cycle-note { font-size: 0.75rem; color: #6b6656; margin: 6px 0 0; }

/* ---- deposit history as cards ---- */
.aj-deposit-cards { display: flex; flex-direction: column; gap: 10px; }
.aj-deposit-card { background: #fff; border: 1px solid var(--aj-border); border-radius: 10px; padding: 12px 14px; }
.aj-deposit-card-top { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.aj-deposit-amount { font-weight: 800; font-size: 1rem; }
.aj-deposit-meta { font-size: 0.78rem; color: #6b6656; margin-top: 4px; }
.aj-deposit-note { font-size: 0.8rem; color: #8a6d00; margin-top: 6px; }
.aj-deposit-proof {
  display: inline-block; margin-top: 8px; font-size: 0.8rem; font-weight: 700;
  color: #a8790a; text-decoration: none;
}
.aj-deposit-proof:hover, .aj-deposit-proof:active { color: var(--aj-gold-dark); text-decoration: underline; }
.aj-deposit-noproof { margin-top: 8px; font-size: 0.8rem; font-weight: 700; color: var(--aj-red); }

/* ---- file upload ----
   A native file input renders an OS button nothing can style, so the input is
   stretched transparent over a zone we draw ourselves. Not display:none and a
   styled <label>: a hidden input cannot receive the browser's "please fill
   this in" bubble, and this field is required. */
.aj-upload {
  position: relative; margin-top: 0.25rem;
  border: 2px dashed var(--aj-border); border-radius: 12px; background: var(--aj-bg);
  transition: border-color 0.15s, background 0.15s;
}
.aj-upload:hover { border-color: var(--aj-gold); }
.aj-upload:focus-within { border-color: var(--aj-gold); box-shadow: 0 0 0 3px rgba(255, 199, 0, 0.25); }
.aj-upload.has-file { border-style: solid; border-color: var(--aj-green); background: #f3fbf6; }

.aj-upload input[type='file'] {
  position: absolute; inset: 0; z-index: 2;
  width: 100%; height: 100%; margin: 0; padding: 0; border: 0;
  opacity: 0; cursor: pointer;
}

.aj-upload-empty { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 22px 14px; text-align: center; }
.aj-upload-empty svg {
  width: 26px; height: 26px;
  fill: none; stroke: #8a8577; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.aj-upload-title { font-size: 0.9rem; font-weight: 700; color: var(--aj-text); }
.aj-upload-hint { font-size: 0.75rem; color: #6b6656; }

.aj-upload-filled { display: flex; align-items: center; gap: 12px; padding: 12px 14px; }
.aj-upload-thumb { width: 48px; height: 48px; border-radius: 8px; object-fit: cover; flex: 0 0 auto; display: block; }
.aj-upload-pdf {
  width: 48px; height: 48px; border-radius: 8px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  background: var(--aj-red); color: #fff; font-size: 0.72rem; font-weight: 800; letter-spacing: 0.04em;
}
.aj-upload-meta { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.aj-upload-name { font-size: 0.85rem; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aj-upload-check {
  width: 20px; height: 20px; flex: 0 0 auto;
  fill: none; stroke: var(--aj-green); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round;
}

/* ---- vendor credit limit & deposits ---- */
.aj-limit-card { padding: 1.1rem 1.25rem; }
.aj-limit-header { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; margin-bottom: 0.75rem; }
.aj-limit-title { font-weight: 700; font-size: 1rem; margin-right: 0.5rem; }
.aj-level-badge { background: var(--aj-gold); color: var(--aj-black); }

.aj-limit-bar { height: 10px; border-radius: 999px; background: #eceade; overflow: hidden; }
.aj-limit-bar-sm { height: 6px; margin-top: 8px; }
.aj-limit-bar-fill { height: 100%; background: var(--aj-green); border-radius: 999px; transition: width 0.3s; }
.aj-limit-bar-fill.warn { background: var(--aj-gold-dark); }
.aj-limit-bar-fill.full { background: var(--aj-red); }

.aj-limit-figures { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; margin-top: 0.75rem; }
.aj-limit-figure-label { display: block; font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: #6b6656; }
.aj-limit-figure-value { display: block; font-weight: 700; font-size: 0.95rem; margin-top: 0.15rem; }
.aj-limit-pending { font-size: 0.8rem; color: #8a6d00; margin: 0.75rem 0 0; }
.aj-limit-btn { margin-top: 1rem; width: 100%; }

.aj-breakdown-limit { margin: 0.6rem 0 0; font-size: 0.85rem; }

.badge-PENDING { background: #fff3cd; color: #8a6d00; }
.badge-REJECTED { background: #fde2e0; color: var(--aj-red); }

.aj-deposit-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; padding: 0.75rem 0; border-bottom: 1px solid var(--aj-border); }
.aj-deposit-row:last-child { border-bottom: none; }
.aj-deposit-summary { flex: 1 1 260px; }
.aj-deposit-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.aj-deposit-actions .aj-btn { margin-top: 0; }
.aj-reject-form { display: flex; align-items: center; gap: 0.5rem; }
.aj-reject-form input { padding: 0.5rem; border: 1px solid var(--aj-border); border-radius: 6px; font-size: 0.9rem; }

.aj-inline-form { display: flex; align-items: center; gap: 0.4rem; }
.aj-inline-form select { padding: 0.4rem; border: 1px solid var(--aj-border); border-radius: 6px; font-size: 0.9rem; }
.aj-inline-form .aj-btn { margin-top: 0; min-height: 34px; padding: 0.35rem 0.8rem; font-size: 0.85rem; }

@media (max-width: 520px) {
  .aj-limit-figures { grid-template-columns: 1fr; }
  .aj-limit-figures > div { display: flex; justify-content: space-between; align-items: baseline; }
  .aj-limit-figure-value { margin-top: 0; }
}

.aj-stat-tile-commission { border-left: 3px solid var(--aj-gold); }

/* ---- idle lock screen ---- */
.aj-unlock-card { text-align: center; }
.aj-unlock-icon { font-size: 2.4rem; line-height: 1; margin-bottom: 0.4rem; }
.aj-unlock-lead { font-size: 0.9rem; color: #6b6656; margin: 0 0 0.75rem; }
.aj-unlock-user { font-weight: 700; margin: 0 0 1rem; }
.aj-unlock-card .aj-form label { text-align: left; }
.aj-unlock-logout { margin-top: 1rem; }
.aj-unlock-logout .link-btn {
  background: none; border: none; color: #6b6656; cursor: pointer;
  font: inherit; font-size: 0.85rem; text-decoration: underline;
}

/* ---- operator (Haiti Central) screens ----
   The vendor app's vocabulary applied to the case queue: a tile row of state,
   a tab strip, cards. Everything here reuses the existing tokens -- these are
   arrangements of the same system, not a second one. */

.aj-stat-tile-mine { border-left-color: var(--aj-gold-dark); }
.aj-stat-tile-done { border-left-color: var(--aj-green); }

/* Tabs are links on the queue (server-filtered, polled) and buttons on the
   case screen (client-side panels). Same strip either way. */
a.aj-tab-btn { text-decoration: none; }

/* One field, the way a phone app searches: the icon sits inside the input's
   box rather than beside it, and changing the channel submits instead of
   asking for a second tap on a button. */
.aj-searchbar { position: relative; display: flex; gap: 6px; margin-bottom: 0.9rem; }
.aj-searchbar-icon {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  width: 16px; height: 16px; pointer-events: none;
  fill: none; stroke: #9aa0a7; stroke-width: 2; stroke-linecap: round;
}
.aj-searchbar input[type="search"] {
  flex: 1 1 auto; min-width: 0; padding: 0.6rem 0.75rem 0.6rem 34px;
  border: 1px solid var(--aj-border); border-radius: 999px;
  font-size: 0.9rem; background: #fff; -webkit-appearance: none;
}
.aj-searchbar input[type="search"]:focus {
  outline: none; border-color: var(--aj-gold); box-shadow: 0 0 0 3px rgba(255, 199, 0, 0.18);
}
.aj-searchbar select {
  flex: 0 0 auto; max-width: 42%; padding: 0.6rem 0.5rem;
  border: 1px solid var(--aj-border); border-radius: 999px;
  font-size: 0.85rem; background: #fff;
}

/* The three things read aloud on the call, above the tabs so they are never
   a tap away while the phone is at the operator's ear. */
.aj-case-hero {
  background: linear-gradient(160deg, #17191d 0%, #0b0d10 100%);
  color: #fff; border-radius: 14px; padding: 12px 16px; margin-bottom: 0.75rem;
}
.aj-case-hero-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.aj-case-hero-name { font-size: 0.98rem; font-weight: 700; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aj-case-hero-amount { font-size: 1.5rem; font-weight: 800; color: var(--aj-gold); line-height: 1.1; flex: 0 0 auto; }
.aj-case-hero-amount span { font-size: 0.8rem; font-weight: 700; color: #cfcabb; }
.aj-case-hero-account {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-top: 9px; padding-top: 9px; border-top: 1px solid rgba(255, 255, 255, 0.14);
}
.aj-case-hero-account .aj-ct-account { color: #fff; font-size: 1.05rem; }
.aj-copy-btn {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px;
  min-height: 34px; padding: 0 12px; border-radius: 999px; cursor: pointer;
  background: rgba(255, 255, 255, 0.12); border: 1px solid rgba(255, 255, 255, 0.2);
  color: #fff; font: inherit; font-size: 0.78rem; font-weight: 700;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.aj-copy-btn svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.aj-copy-btn:hover, .aj-copy-btn:active { background: var(--aj-gold); border-color: var(--aj-gold); color: var(--aj-black); }
.aj-copy-btn.is-copied { background: var(--aj-green); border-color: var(--aj-green); color: #fff; }

/* Three discrete states, not a progress bar: there is no meaningful fraction
   between "called" and "money sent". */
.aj-steps { display: flex; gap: 6px; list-style: none; margin: 0 0 1rem; padding: 0; }
.aj-steps li {
  flex: 1 1 0; display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 8px 4px; border-radius: 8px; background: #fff; border: 1px solid var(--aj-border);
  font-size: 0.75rem; font-weight: 700; color: #9aa0a7; text-align: center;
}
.aj-steps li span {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%; flex: 0 0 auto;
  background: var(--aj-bg); color: #9aa0a7; font-size: 0.68rem;
}
.aj-steps li.active { color: var(--aj-text); border-color: var(--aj-gold); }
.aj-steps li.active span { background: var(--aj-gold); color: var(--aj-black); }
.aj-steps li.done { color: var(--aj-text); border-color: var(--aj-green); }
.aj-steps li.done span { background: var(--aj-green); color: #fff; }

/* A caption inside a card, for the round counter the calls list is scoped to. */
.aj-card-caption {
  font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em;
  color: #6b6656; padding-bottom: 8px; border-bottom: 1px solid var(--aj-border); margin-bottom: 4px;
}

/* Dialling is the operator's most-repeated action, so it gets a real button
   rather than a phone number they have to select and copy. */
.aj-call-btn { display: flex; align-items: center; justify-content: center; gap: 8px; text-decoration: none; }
.aj-call-btn svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* ---- unevidenced delivery ----
   An operator who said the money went out and has not shown the receipt. The
   app stops handing them new work until they do. */

.aj-notice-alert { color: #7a1f14; background: #fdecea; border-color: #f5b7b1; }

.aj-alert-banner {
  background: #fdecea; border: 1px solid #f5b7b1; border-left: 4px solid var(--aj-red);
  color: #7a1f14; border-radius: 10px; padding: 12px 14px; margin-bottom: 1rem;
  font-size: 0.88rem;
}
.aj-transfer-card.is-alert { border-left: 4px solid var(--aj-red); }

/* The blur is the point: the screen behind is legible enough to show it is
   still there, but plainly not usable. The panel carries exactly one action --
   offering a dismiss would make the block a suggestion. */
.aj-blockgate, .aj-modal {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center; padding: 1.25rem;
  background: rgba(11, 13, 16, 0.55);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  animation: aj-blockgate-in 180ms ease-out;
}
@keyframes aj-blockgate-in { from { opacity: 0; } to { opacity: 1; } }
.aj-blockgate-panel {
  background: #fff; border-radius: 14px; padding: 20px 18px;
  width: 100%; max-width: 380px;
  border-top: 4px solid var(--aj-red);
  box-shadow: 0 18px 50px -12px rgba(0, 0, 0, 0.5);
}
.aj-blockgate-panel h2 { margin: 0 0 8px; font-size: 1.05rem; }
.aj-blockgate-panel p { margin: 0 0 16px; font-size: 0.88rem; color: #4a4a4a; line-height: 1.5; }
.aj-blockgate-panel .aj-btn { text-decoration: none; }
a.aj-alert-link { display: block; text-decoration: none; }
a.aj-alert-link:hover, a.aj-alert-link:active { background: #fbdbd7; }

/* ---- the three things an operator does with a case ----
   Paying is the common one and gets the full-width primary button; ringing and
   reporting an error are secondary and open a panel rather than sitting open,
   so the screen stays one decision tall. */
.aj-actions { margin-bottom: 10px; }
.aj-action-pay { font-size: 1rem; }
.aj-action-row { display: flex; gap: 8px; margin-bottom: 10px; }
.aj-action-row .aj-btn { flex: 1 1 0; margin-top: 0; }
.aj-action-row .aj-btn.is-open { border-color: var(--aj-text); background: var(--aj-bg); }

/* ---- modal ----
   Logging a call is one decision finished in one go. Inline, the panel pushed
   the rest of the case around while the operator typed; as a modal the case
   holds still behind it. Shares the blockgate's backdrop above -- one overlay
   look, not two that drift apart. */
.aj-modal-panel {
  background: #fff; border-radius: 14px; padding: 16px 18px 18px;
  width: 100%; max-width: 420px; max-height: 88vh; overflow-y: auto;
  box-shadow: 0 18px 50px -12px rgba(0, 0, 0, 0.5);
}
.aj-modal-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.aj-modal-head h2 { margin: 0 0 6px; font-size: 1.05rem; }
.aj-modal-close {
  flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%; cursor: pointer;
  background: var(--aj-bg); border: 1px solid var(--aj-border); color: #6b6656;
  font-size: 1.3rem; line-height: 1; padding: 0;
}
.aj-modal-close:hover, .aj-modal-close:active { background: var(--aj-border); color: var(--aj-text); }

/* A tappable row per answer. Two options in a select cost two taps and hide
   whichever one is not showing; as rows both are readable at a glance. */
.aj-field-label {
  display: block; font-size: 0.8rem; font-weight: 700; color: #6b6656; margin: 12px 0 6px;
}
.aj-choice {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  padding: 11px 12px; margin-bottom: 6px; min-height: 44px;
  border: 1px solid var(--aj-border); border-radius: 10px; background: #fff;
  font-size: 0.9rem;
}
.aj-choice input { width: 18px; height: 18px; flex: 0 0 auto; accent-color: var(--aj-gold-dark); margin: 0; }
.aj-choice:has(input:checked) { border-color: var(--aj-gold); background: #fffdf2; font-weight: 600; }

/* ---- the case screen as a fixed-height column ----
   On a phone the operator should never scroll to reach an action. The shell
   fills what is left between the app bar and the tab bar; the hero and tabs
   pin to the top, the actions pin to the bottom where a thumb is, and only the
   call list in between moves. A case with ten calls logged is exactly the one
   whose buttons must not have been pushed off the fold.

   Desktop keeps ordinary page flow: there is no tab bar to measure against and
   no thumb to reach with. */
.aj-case-scroll > :first-child { margin-top: 0; }
.aj-case-foot-note { font-size: 0.75rem; color: #6b6656; margin: 6px 0 0; text-align: center; }
.aj-case-foot .aj-btn { margin-top: 8px; }
.aj-case-foot > form:first-child .aj-btn { margin-top: 0; }

@media (max-width: 768px) {
  .aj-case-shell {
    display: flex;
    flex-direction: column;
    /* dvh, not vh: the mobile URL bar collapsing must not leave the footer
       under the tab bar. env() covers the notch at both ends. */
    height: calc(100dvh - var(--aj-header-h) - var(--aj-tabbar-h) - 2rem
                 - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px));
  }
  .aj-case-top { flex: 0 0 auto; }
  .aj-case-top .aj-tabs { margin: 0 0 0.6rem; }

  /* min-height:0 is what lets a flex child shrink below its content and
     actually scroll -- without it the panel grows and the page scrolls again,
     which is the whole bug. */
  .aj-case-shell > .aj-panel {
    flex: 1 1 auto; min-height: 0;
    display: flex; flex-direction: column;
  }
  .aj-case-scroll {
    flex: 1 1 auto; min-height: 0;
    overflow-y: auto; -webkit-overflow-scrolling: touch;
  }
  .aj-case-foot {
    flex: 0 0 auto;
    padding-top: 10px; margin-top: 4px;
    border-top: 1px solid var(--aj-border);
  }

  /* The case screen manages its own height, so the shell must not also be
     pushed down by the main scroller's tab-bar allowance. */
  .aj-main:has(.aj-case-shell) { overflow: hidden; }
}
.aj-stat-tile-sent { border-left-color: var(--aj-gold); }

/* The figure inside the ring steps down as it lengthens. A week of HTG runs to
   five or six digits where a DOP commission runs to three, and the ring is the
   same 128px either way -- so the size follows the number rather than the
   number overflowing the ring. max-width is the backstop for anything longer
   than the steps anticipate. */
.aj-fin-hero-value { max-width: 96px; letter-spacing: -0.02em; }
.aj-fin-hero-value.fit-5 { font-size: 1.35rem; }
.aj-fin-hero-value.fit-6 { font-size: 1.1rem; }
.aj-fin-hero-value.fit-7 { font-size: 0.92rem; letter-spacing: -0.03em; }

/* ---- RD manager screens ----
   The one role that genuinely works from both a laptop and a phone: at the
   office reviewing a morning's cases, and in a branch with a tablet. One set
   of markup, laid out twice. Everything below is arrangement -- the tokens,
   cards, badges and buttons are the same ones the rest of the app uses. */

/* 900px is right for a form and cramped for a board. */
.aj-container.wide { max-width: 1180px; }

/* Cards flow to fill the width instead of stretching to it. A single case at
   1180px wide is a sentence pretending to be a card. */
.aj-case-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap: 12px;
  margin-bottom: 1.5rem;
}
.aj-case-grid .aj-empty-state { grid-column: 1 / -1; }

.aj-mgr-card {
  display: block; text-decoration: none; color: inherit;
  background: #fff; border: 1px solid var(--aj-border);
  border-left: 4px solid var(--aj-gold);
  border-radius: 12px; padding: 14px 16px;
  transition: border-color 0.15s, box-shadow 0.15s, transform 0.15s;
}
.aj-mgr-card:hover, .aj-mgr-card:active {
  border-top-color: var(--aj-gold); border-right-color: var(--aj-gold);
  border-bottom-color: var(--aj-gold);
  box-shadow: 0 6px 18px -10px rgba(0, 0, 0, 0.45);
  transform: translateY(-1px);
}
/* The accent carries the queue's priority order, so a manager can see which
   pile a card belongs to without reading its heading. */
.aj-mgr-card.urgent { border-left-color: var(--aj-red); }
.aj-mgr-card.muted { border-left-color: #b9b3a2; opacity: 0.92; }

.aj-mgr-card-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.aj-mgr-card-ref { font-family: monospace; font-size: 0.82rem; font-weight: 700; color: #6b6656; }
.aj-mgr-card-amount { font-size: 1.5rem; font-weight: 800; line-height: 1.15; margin-top: 8px; }
.aj-mgr-card-amount span { font-size: 0.78rem; font-weight: 700; color: #8a8577; }
.aj-mgr-card-name { font-size: 0.95rem; font-weight: 600; margin-top: 2px; }

/* Label above value: two short columns read faster than four cramped ones,
   and it survives a 320px phone without truncating an account number. */
.aj-mgr-card-facts {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px 12px;
  margin: 12px 0 0; padding-top: 10px; border-top: 1px dashed var(--aj-border);
}
.aj-mgr-card-facts div { min-width: 0; }
.aj-mgr-card-facts dt {
  font-size: 0.64rem; text-transform: uppercase; letter-spacing: 0.04em;
  font-weight: 700; color: #9aa0a7;
}
.aj-mgr-card-facts dd {
  margin: 2px 0 0; font-size: 0.85rem; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.aj-mgr-card-note {
  margin: 10px 0 0; padding-top: 9px; border-top: 1px dashed var(--aj-border);
  font-size: 0.82rem; color: #4a4a4a; line-height: 1.45;
}

/* ---- the case screen ----
   Reading on one side, deciding on the other. Stacked on a phone, which puts
   the reading first -- the order a manager would want regardless. */
.aj-mgr-layout { display: grid; grid-template-columns: 1fr; gap: 0 24px; }
.aj-mgr-main, .aj-mgr-side { min-width: 0; }
.aj-mgr-main > :first-child, .aj-mgr-side > :first-child { margin-top: 0; }

@media (min-width: 900px) {
  .aj-mgr-layout { grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); }
  /* The actions follow a long call history down the page rather than
     stranding it at the top of a column nobody scrolled back to. */
  .aj-mgr-side { position: sticky; top: 1rem; align-self: start; }
}

/* One action, its consequence, and its button. The consequence is next to the
   control rather than in a heading above it, because that is where somebody
   about to press it is looking. */
.aj-act {
  background: #fff; border: 1px solid var(--aj-border);
  border-left: 4px solid var(--aj-border);
  border-radius: 12px; padding: 14px 16px; margin-bottom: 12px;
}
.aj-act h2 { margin: 0 0 6px; font-size: 0.98rem; font-weight: 700; }
.aj-act p { margin: 0 0 10px; font-size: 0.84rem; line-height: 1.5; color: #4a4a4a; }
.aj-act .aj-form { margin-top: 0; }
.aj-act-urgent { border-left-color: var(--aj-red); background: #fffaf9; }
.aj-act-danger { border-left-color: var(--aj-red); }

/* Finished work, folded away but reachable. */
.aj-mgr-archive { margin-top: 1.5rem; }
.aj-mgr-archive summary {
  cursor: pointer; padding: 11px 14px; min-height: 44px;
  background: #fff; border: 1px solid var(--aj-border); border-radius: 10px;
  font-size: 0.88rem; font-weight: 700; color: #6b6656;
}
.aj-mgr-archive summary:hover { border-color: var(--aj-gold); color: var(--aj-text); }
.aj-mgr-archive[open] summary { border-radius: 10px 10px 0 0; border-bottom-color: transparent; }
.aj-mgr-archive .aj-card { border-radius: 0 0 10px 10px; margin-top: 0; }

.aj-stat-tile-urgent { border-left-color: var(--aj-red); }
.aj-stat-tile-urgent .aj-stat-value { color: var(--aj-red); }
/* Neither good nor urgent: a debt of paperwork on a case already closed. */
.aj-stat-tile-owed { border-left-color: #b9b3a2; }

/* A row the manager can sign off. The button sits beside the case on a laptop
   and under it on a phone, where a 44px target next to text would crowd it. */
.aj-review-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.aj-review-body { min-width: 0; flex: 1 1 auto; }
.aj-review-btn { margin-top: 0; flex: 0 0 auto; white-space: nowrap; }
@media (max-width: 560px) {
  .aj-review-row { flex-direction: column; }
  .aj-review-btn { width: 100%; }
}

/* ---- admin console ----
   Almost nothing new: the console is the same tiles, cards, tables and action
   blocks the rest of the app uses. What is here is the handful of things it
   asks for that nothing else did. */

/* The peer config is meant to be selected and copied whole, so it gets a
   monospace box that does not wrap a base64 key across lines. */
.aj-peer-config {
  width: 100%; font-family: monospace; font-size: 0.82rem; line-height: 1.5;
  white-space: pre; overflow-x: auto;
  border: 1px solid var(--aj-border); border-radius: 8px; padding: 10px 12px;
  background: var(--aj-bg); color: var(--aj-text);
}

/* A cell can carry a second, quieter line -- a station's name under its code,
   a timestamp under a badge -- without becoming its own column. */
.aj-table .aj-ct-call-meta { display: block; margin-top: 2px; }

/* The responsive table stacks under 640px; its cards need the same breathing
   room as the rest, and a row that is a link should feel like one. */
.aj-table-responsive a { color: var(--aj-text); font-weight: 700; }
.aj-table-responsive a:hover { color: var(--aj-gold-dark); }

/* The "it did not print" escape hatch on a receipt. Folded away by default:
   on a terminal whose printer works, none of it should ever be seen. */
.aj-receipt-fallbacks { margin-top: 1rem; border-top: 1px solid var(--aj-border); padding-top: 0.75rem; }
.aj-receipt-fallbacks summary { font-weight: 700; font-size: 0.9rem; cursor: pointer; padding: 6px 0; }
.aj-receipt-fallbacks .aj-btn { margin-top: 8px; }

/* ---- upload progress ----
   Under the submit button, because that is where the agent is looking when
   they wonder whether the tap did anything. */
.aj-uploading { margin-top: 10px; }
.aj-uploading-track {
  height: 8px; border-radius: 4px; background: #eeeae0; overflow: hidden;
}
.aj-uploading-fill {
  height: 100%; width: 0; background: var(--aj-gold);
  transition: width 0.2s ease-out;
}
.aj-uploading-label {
  margin-top: 6px; font-size: 0.85rem; font-weight: 700; color: #6b6656;
  text-align: center;
}
/* Nothing else on the form is tappable while a photo is on its way: a second
   POST of the same file is a second copy on disk and a case saved twice. */
form.is-uploading { pointer-events: none; opacity: 0.75; }
form.is-uploading .aj-uploading { pointer-events: auto; opacity: 1; }

/* ---- public tracking ----
   The one page a customer sees. Wider proof image than the card's text so a
   screenshot is legible on a phone without pinching. */
.aj-track-lang { display: flex; gap: 6px; margin-bottom: 0.9rem; }
.aj-track-state { text-align: center; margin: 1rem 0 0.5rem; }
.aj-track-note { font-size: 0.9rem; color: #6b6656; margin: 8px 0 0; }
.aj-track-proof { margin-top: 0.5rem; }
.aj-track-proof-img {
  display: block; width: 100%; height: auto; border: 1px solid var(--aj-border);
  border-radius: 10px; margin-bottom: 10px;
}

/* Public state names only -- see the comment in public_tracking.html. */
.aj-track-badge-working { background: #fff3cd; color: #8a6d00; }
.aj-track-badge-delivered { background: #d6f5df; color: var(--aj-green); }
.aj-track-badge-cancelled { background: #fde2e0; color: var(--aj-red); }
