/* ==========================================================================
   THE SPARK — element defaults and shared components.
   ==========================================================================

   Every component later phases need is here. Phases 3, 4 and 6 compose these
   classes; they do not write new CSS for a button, a card, an input or a status
   pill. If a screen needs something this file lacks, add it HERE and add it to
   the styleguide, so the next screen finds it.

   NO HARDCODED COLOUR VALUES IN THIS FILE. Every colour is a var(--…) from
   tokens.css. Validation (Phase 0 plan, Task 0.4):

     grep -rEn '#[0-9a-fA-F]{3,8}' static/css/app.css templates/

   must return nothing. Same for rgb()/rgba()/hsl() literals.

   Mobile-first: base rules are the phone, media queries add the desktop.
   ========================================================================== */

/* ==========================================================================
   1. RESET AND ELEMENT DEFAULTS
   ========================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  /* Anchored scrolling clears the sticky header. */
  scroll-padding-top: var(--space-lg);
}

body {
  margin: 0;
  min-height: 100dvh;
  background-color: var(--color-surface);
  color: var(--color-on-surface);
  font-family: var(--font-sans);
  font-size: var(--text-body-md-size);
  line-height: var(--text-body-md-line);
  font-weight: var(--weight-regular);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Room for the bottom nav, so the last card is never trapped underneath it. */
body.has-bottom-nav {
  padding-bottom: calc(var(--nav-height) + var(--space-lg));
}

h1,
h2,
h3,
h4 {
  margin: 0;
  font-weight: var(--weight-extrabold);
  letter-spacing: var(--text-headline-lg-tracking);
  text-wrap: balance;
}

h1 {
  font-size: var(--text-headline-lg-mobile-size);
  line-height: var(--text-headline-lg-mobile-line);
}

h2 {
  font-size: var(--text-headline-md-size);
  line-height: var(--text-headline-md-line);
  font-weight: var(--text-headline-md-weight);
  letter-spacing: normal;
}

h3 {
  font-size: var(--text-body-lg-size);
  line-height: var(--text-body-lg-line);
  font-weight: var(--weight-bold);
  letter-spacing: normal;
}

p {
  margin: 0;
  text-wrap: pretty;
}

a {
  color: var(--color-primary-strong);
  text-decoration-thickness: 2px;
  text-underline-offset: 2px;
}

a:hover {
  color: var(--color-secondary-strong);
}

img,
svg {
  max-width: 100%;
  display: block;
}

/* One visible focus treatment everywhere, keyboard-only. Removing focus rings
   is how a form becomes unusable without a mouse. */
:focus-visible {
  outline: 2px solid var(--color-primary-strong);
  outline-offset: 2px;
}

/* Honour the OS setting. The bounce is decoration; nobody needs it. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   2. LAYOUT
   ========================================================================== */

/* The content column. 640px on wide viewports keeps the intimate mobile feel
   DESIGN.md asks for, rather than stretching a phone layout across a monitor. */
.container {
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--space-container);
}

/* The main content region. Breathing room top and bottom without every view
   restating it. */
.page {
  padding-block: var(--space-md) var(--space-lg);
}

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.stack-lg {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

.stack-sm {
  display: flex;
  flex-direction: column;
  gap: var(--space-base);
}

.stack-xs {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.divider {
  height: 1px;
  background-color: var(--color-outline-variant);
  border: 0;
  margin: 0;
}

.gap-md {
  gap: var(--space-md);
}

.gap-xs {
  gap: var(--space-xs);
}

.pt-xs {
  padding-top: var(--space-xs);
}

.pt-sm {
  padding-top: var(--space-sm);
}

.pt-md {
  padding-top: var(--space-md);
}

.mb-md {
  margin-bottom: var(--space-md);
}

.mt-lg {
  margin-top: var(--space-lg);
}

.row {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.row-between {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
}

.wrap {
  flex-wrap: wrap;
}

.grow {
  flex: 1 1 auto;
  min-width: 0;
}

/* Screen-reader-only. For labels a sighted user gets from context and an
   assistive-technology user does not. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ==========================================================================
   3. TYPOGRAPHY HELPERS
   ========================================================================== */

.text-display {
  font-size: var(--text-display-size);
  line-height: var(--text-display-line);
  font-weight: var(--text-display-weight);
  letter-spacing: var(--text-display-tracking);
}

.text-headline {
  font-size: var(--text-headline-lg-mobile-size);
  line-height: var(--text-headline-lg-mobile-line);
  font-weight: var(--weight-extrabold);
  letter-spacing: var(--text-headline-lg-tracking);
}

.text-body-lg {
  font-size: var(--text-body-lg-size);
  line-height: var(--text-body-lg-line);
}

.text-body-md {
  font-size: var(--text-body-md-size);
  line-height: var(--text-body-md-line);
}

.text-sm {
  font-size: var(--text-body-sm-size);
  line-height: var(--text-body-sm-line);
}

.text-muted {
  color: var(--color-on-surface-muted);
}

.text-faint {
  color: var(--color-on-surface-faint);
}

.text-error {
  color: var(--color-error);
}

.text-success {
  color: var(--color-on-success-container);
}

.text-center {
  text-align: center;
}

.text-right {
  text-align: right;
}

.font-mono {
  font-family: var(--font-mono);
}

.font-bold {
  font-weight: var(--weight-bold);
}

.font-medium {
  font-weight: var(--weight-medium);
}

/* Tracked-out uppercase. The only place uppercase is used. */
.label {
  font-size: var(--text-label-size);
  line-height: var(--text-label-line);
  font-weight: var(--text-label-weight);
  letter-spacing: var(--text-label-tracking);
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   Money. Always mono, always tabular so columns of Rands line up, never a
   float — see MASTER_MAP §6.1 and core.money.format_zar, which is the single
   place a ZAR string is produced.
   -------------------------------------------------------------------------- */
.money {
  font-family: var(--font-mono);
  font-size: var(--text-number-md-size);
  line-height: var(--text-number-md-line);
  font-weight: var(--text-number-md-weight);
  font-variant-numeric: tabular-nums;
}

.money-xl {
  font-family: var(--font-mono);
  font-size: var(--text-number-xl-size);
  line-height: var(--text-number-xl-line);
  font-weight: var(--text-number-xl-weight);
  font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   4. BUTTONS

   Always pills. Pressing performs a sink — scale to 0.98 with a softer shadow
   — rather than a lift, mimicking a tactile physical press (DESIGN.md).
   ========================================================================== */

.btn-primary,
.btn-secondary,
.btn-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-base);
  min-height: 3rem; /* 48px — comfortable thumb target */
  padding: var(--space-sm) var(--space-md);
  border: 0;
  border-radius: var(--radius-full);
  font-family: inherit;
  font-size: var(--text-body-md-size);
  font-weight: var(--weight-bold);
  line-height: 1.25;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition:
    transform var(--duration-fast) var(--ease-out),
    box-shadow var(--duration-fast) var(--ease-out),
    background-color var(--duration-base) var(--ease-out);
}

.btn-primary:active,
.btn-secondary:active,
.btn-ghost:active {
  transform: scale(var(--press-scale));
  box-shadow: var(--shadow-sunk);
}

.btn-primary:disabled,
.btn-secondary:disabled,
.btn-ghost:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

/* Coral Pop, reserved exclusively for the primary action on a screen. Two
   primary buttons in one view means one of them is not primary. */
.btn-primary {
  background-color: var(--color-secondary);
  color: var(--color-on-secondary);
  box-shadow: var(--shadow-soft);
}

.btn-primary:hover:not(:disabled) {
  background-color: var(--color-secondary-strong);
  color: var(--color-on-tertiary); /* white — contrast holds on the darker coral */
}

/* White with a 2px Zest border. */
.btn-secondary {
  background-color: var(--color-surface-card);
  color: var(--color-on-surface);
  box-shadow: inset 0 0 0 2px var(--color-primary);
}

.btn-secondary:hover:not(:disabled) {
  background-color: var(--color-primary-soft);
}

/* Ink Navy text, no background. Cancel and Back. */
.btn-ghost {
  background-color: transparent;
  color: var(--color-on-surface);
  font-weight: var(--weight-medium);
}

.btn-ghost:hover:not(:disabled) {
  background-color: var(--color-surface-alt);
}

.btn-block {
  width: 100%;
}

.btn-sm {
  min-height: 2.25rem;
  padding: var(--space-xs) var(--space-sm);
  font-size: var(--text-body-sm-size);
}

/* ==========================================================================
   5. CARDS

   The primary organisational unit: 24px radius, pure white, soft navy shadow.
   ========================================================================== */

.card {
  background-color: var(--color-surface-card);
  border-radius: var(--radius-md);
  padding: var(--space-md);
  box-shadow: var(--shadow-soft);
}

/* Featured rewards get a 2px Zest border to denote "the spark". */
.card-featured {
  box-shadow:
    var(--shadow-soft),
    inset 0 0 0 2px var(--color-primary);
}

/* A card that is a link or a button: it sinks when pressed. */
.card-pressable {
  cursor: pointer;
  transition:
    transform var(--duration-fast) var(--ease-out),
    box-shadow var(--duration-fast) var(--ease-out);
}

.card-pressable:active {
  transform: scale(var(--press-scale));
  box-shadow: var(--shadow-sunk);
}

/* The wallet balance card — Zest, because money is the brand moment. */
.card-hero {
  background-color: var(--color-primary);
  color: var(--color-on-primary);
  border-radius: var(--radius-md);
  padding: var(--space-md);
  box-shadow: var(--shadow-soft);
}

/* ==========================================================================
   6. FORMS

   24px radius, and the focus state is a Zest halo rather than a border-colour
   change (DESIGN.md).
   ========================================================================== */

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.field-label {
  font-size: var(--text-body-sm-size);
  font-weight: var(--weight-bold);
  color: var(--color-on-surface);
}

.input,
.select,
.textarea {
  width: 100%;
  padding: var(--space-sm) var(--space-md);
  /* 16px minimum, or iOS Safari zooms the viewport when the field is focused. */
  font-family: inherit;
  font-size: var(--text-body-md-size);
  line-height: var(--text-body-md-line);
  color: var(--color-on-surface);
  background-color: var(--color-surface-card);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-md);
  transition:
    box-shadow var(--duration-base) var(--ease-out),
    border-color var(--duration-base) var(--ease-out);
}

.input:focus,
.select:focus,
.textarea:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: var(--shadow-focus);
}

.input::placeholder,
.textarea::placeholder {
  color: var(--color-on-surface-faint);
}

.textarea {
  min-height: 6rem;
  resize: vertical;
}

.input-error,
.input-error:focus {
  border-color: var(--color-error);
}

/* Helper text under a field. */
.field-help {
  font-size: var(--text-body-sm-size);
  line-height: var(--text-body-sm-line);
  color: var(--color-on-surface-muted);
}

.field-error {
  font-size: var(--text-body-sm-size);
  line-height: var(--text-body-sm-line);
  color: var(--color-on-error-container);
  font-weight: var(--weight-medium);
}

/* One-time-pin entry: wide tracking, mono, centred. */
.input-otp {
  font-family: var(--font-mono);
  font-size: var(--text-number-xl-size);
  letter-spacing: 0.25em;
  text-align: center;
}

/* ==========================================================================
   7. BADGES AND STATUS PILLS
   ========================================================================== */

/* Grape Fizz stickers, rotated a degree so they read as hand-placed. */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--radius-full);
  background-color: var(--color-tertiary-container);
  color: var(--color-on-tertiary-container);
  font-size: var(--text-label-size);
  line-height: var(--text-label-line);
  font-weight: var(--text-label-weight);
  letter-spacing: var(--text-label-tracking);
  text-transform: uppercase;
  transform: rotate(-1deg);
}

/* Neutral chip — counters and metadata, no status meaning. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--radius-full);
  background-color: var(--color-surface-card);
  border: 1px solid var(--color-outline-variant);
  color: var(--color-on-surface-muted);
  font-size: var(--text-body-sm-size);
  box-shadow: var(--shadow-soft);
}

/* --------------------------------------------------------------------------
   Status pills — EXACTLY four variants, matching the public status mapping in
   spec §11.1. This is not a styling decision, it is a privacy boundary:

     pending    PENDING_VETTING · ATTEMPTING_CONTACT · MANUAL_REVIEW
     contacting VETTED_QUALIFIED · SENT_TO_PARTNER · HANDOFF_FAILED
     converted  CLOSED_WON · ACCOUNT_INVITED · ACCOUNT_ACTIVE · ACCOUNT_DECLINED
     closed     DECLINED_CONSENT · CLOSED_LOST · CLOSED_UNREACHABLE ·
                LOST_STALE · REJECTED_BLOCKED

   A referrer must never be able to tell "declined consent" from "not a fit"
   from the colour — that would leak a third party's decision (ADR-012). All
   four of those internal states share the one neutral `closed` pill.

   Do not add a fifth variant. If a new internal status appears, map it into one
   of these four.
   -------------------------------------------------------------------------- */
.pill-status {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--radius-full);
  font-size: var(--text-label-size);
  line-height: var(--text-label-line);
  font-weight: var(--text-label-weight);
  letter-spacing: var(--text-label-tracking);
  white-space: nowrap;
}

.pill-status--pending {
  background-color: var(--color-tertiary-container);
  color: var(--color-on-tertiary-container);
}

.pill-status--contacting {
  background-color: var(--color-primary);
  color: var(--color-on-primary);
}

.pill-status--converted {
  background-color: var(--color-success-container);
  color: var(--color-on-success-container);
}

.pill-status--closed {
  background-color: var(--color-surface-sunken);
  color: var(--color-on-surface-muted);
}

/* ==========================================================================
   8. AVATARS

   Strictly circular, and every one wears a 2px Zest "Spark Ring" — a
   consistent brand halo around people.
   ========================================================================== */

.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--radius-full);
  overflow: hidden;
  background-color: var(--color-primary-soft);
  color: var(--color-on-primary-soft);
  font-weight: var(--weight-extrabold);
  box-shadow: var(--shadow-spark-ring);
}

.avatar-lg {
  width: 3rem;
  height: 3rem;
  font-size: var(--text-headline-md-size);
}

/* An initial in a circle. No ring — used inside list rows, where a ring on
   every row would be noise. */
.avatar-initial {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 3rem;
  height: 3rem;
  border-radius: var(--radius-full);
  background-color: var(--color-surface-alt);
  color: var(--color-primary-strong);
  font-size: var(--text-headline-md-size);
  font-weight: var(--weight-bold);
}

/* ==========================================================================
   9. BOTTOM NAVIGATION (referrer app, mobile)
   ========================================================================== */

.bottom-nav {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: var(--z-nav);
  display: flex;
  justify-content: space-around;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-sm) var(--space-gutter);
  /* Clears the iOS home indicator. */
  padding-bottom: max(var(--space-md), env(safe-area-inset-bottom));
  background-color: var(--color-surface-card);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  box-shadow: var(--shadow-nav);
}

.bottom-nav__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-xs);
  flex: 1 1 0;
  padding: var(--space-base) var(--space-xs);
  border-radius: var(--radius-full);
  color: var(--color-on-surface-muted);
  text-decoration: none;
  font-size: var(--text-label-size);
  font-weight: var(--text-label-weight);
  letter-spacing: var(--text-label-tracking);
  transition: background-color var(--duration-base) var(--ease-out);
}

.bottom-nav__item:hover {
  background-color: var(--color-surface-alt);
  color: var(--color-on-surface);
}

.bottom-nav__item[aria-current='page'] {
  background-color: var(--color-secondary);
  color: var(--color-on-secondary);
}

.bottom-nav__icon {
  width: 1.5rem;
  height: 1.5rem;
}

/* A phone layout stretched across a monitor is worse than a sidebar, but the
   bottom bar at 1280px reads as a phone emulator. Centre it to the content
   column instead. */
@media (min-width: 768px) {
  .bottom-nav {
    inset-inline: auto;
    left: 50%;
    transform: translateX(-50%);
    width: min(var(--content-max), 100%);
    border-radius: var(--radius-lg);
    bottom: var(--space-md);
  }
}

/* ==========================================================================
   10. EMPTY STATES

   Where the Spark mascot lives, "reacting" to the absence of data rather than
   sitting there as a static icon.
   ========================================================================== */

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-lg) var(--space-md);
  text-align: center;
  color: var(--color-on-surface-muted);
}

.empty-state__mascot {
  width: 4rem;
  height: 4rem;
  animation: spark-float 3s var(--ease-in-out) infinite;
}

.empty-state__title {
  font-size: var(--text-body-lg-size);
  font-weight: var(--weight-bold);
  color: var(--color-on-surface);
}

@keyframes spark-float {
  0%,
  100% {
    transform: translateY(0) rotate(-2deg);
  }
  50% {
    transform: translateY(-6px) rotate(2deg);
  }
}

/* ==========================================================================
   11. TOASTS AND MESSAGES
   ========================================================================== */

.toast-region {
  position: fixed;
  inset-inline: 0;
  top: 0;
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--space-base);
  padding: var(--space-sm) var(--space-container);
  pointer-events: none;
}

.toast {
  pointer-events: auto;
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-card);
  color: var(--color-on-surface);
  box-shadow: var(--shadow-lifted);
  animation: toast-in var(--duration-slow) var(--ease-spring);
}

.toast--success {
  background-color: var(--color-success-container);
  color: var(--color-on-success-container);
}

.toast--error {
  background-color: var(--color-error-container);
  color: var(--color-on-error-container);
}

.toast--warning {
  background-color: var(--color-primary-soft);
  color: var(--color-on-primary-soft);
}

.toast__close {
  margin-inline-start: auto;
  background: none;
  border: 0;
  padding: 0;
  color: inherit;
  cursor: pointer;
  font-size: var(--text-body-lg-size);
  line-height: 1;
}

@keyframes toast-in {
  from {
    opacity: 0;
    transform: translateY(-0.75rem);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ==========================================================================
   12. MODAL (HTMX-swappable dialog shell)
   ========================================================================== */

.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: var(--space-md);
  background-color: rgb(var(--shadow-rgb) / 45%);
  animation: fade-in var(--duration-base) var(--ease-out);
}

.modal {
  width: 100%;
  max-width: var(--content-max);
  max-height: 85dvh;
  overflow-y: auto;
  padding: var(--space-md);
  background-color: var(--color-surface-card);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  box-shadow: var(--shadow-lifted);
  animation: sheet-up var(--duration-slow) var(--ease-spring);
}

.modal__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-sm);
  margin-bottom: var(--space-md);
}

.modal__close {
  background: none;
  border: 0;
  padding: var(--space-xs);
  color: var(--color-on-surface-muted);
  cursor: pointer;
  font-size: var(--text-body-lg-size);
  line-height: 1;
}

/* On a phone it rises from the bottom like a sheet; on a desktop it centres. */
@media (min-width: 768px) {
  .modal-backdrop {
    align-items: center;
  }

  .modal {
    border-radius: var(--radius-lg);
  }
}

@keyframes fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes sheet-up {
  from {
    transform: translateY(1.5rem);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

/* ==========================================================================
   13. HTMX
   ========================================================================== */

/* An in-flight indicator, shown only while a request is running. */
.htmx-indicator {
  opacity: 0;
  transition: opacity var(--duration-base) var(--ease-out);
}

.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator {
  opacity: 1;
}

/* Anything mid-request stops accepting clicks — the cheapest double-submit
   guard there is, and on the money paths it matters. */
.htmx-request[disabled],
.htmx-request button,
button.htmx-request {
  cursor: progress;
  opacity: 0.65;
  pointer-events: none;
}

/* ==========================================================================
   14. CALL-CENTRE AND ADMIN SUBSET (ADR-008)

   Only overrides. Everything above still applies — same palette, same type
   scale, same components — so a fix to `.card` fixes both surfaces. What
   changes is geometry and density: agents work this screen for eight hours.
   No mascot, no decorative animation, no pill buttons except status chips.
   ========================================================================== */

.cc body,
body.cc {
  background-color: var(--cc-surface);
  font-size: var(--cc-text-size);
  line-height: var(--cc-text-line);
}

.cc .card {
  border-radius: var(--cc-radius-md);
  padding: var(--cc-density-lg);
  border: var(--cc-border);
  box-shadow: var(--cc-shadow);
}

.cc .btn-primary,
.cc .btn-secondary,
.cc .btn-ghost {
  min-height: 2.25rem;
  padding: var(--cc-density-sm) var(--cc-density-md);
  border-radius: var(--cc-radius);
  font-size: var(--cc-text-size);
  box-shadow: none;
}

.cc .input,
.cc .select,
.cc .textarea {
  padding: var(--cc-density-sm) var(--cc-density-md);
  border-radius: var(--cc-radius);
  font-size: var(--text-body-md-size); /* stays 16px — iOS zoom, still */
}

.cc .empty-state__mascot {
  display: none;
}

.cc .badge {
  transform: none; /* nothing wobbly on a working screen */
  border-radius: var(--cc-radius);
}

.cc .container {
  max-width: none;
  padding-inline: var(--cc-density-lg);
}

/* --- Top bar, in place of the bottom nav ----------------------------------- */
.cc-topbar {
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  padding: var(--space-xs) var(--cc-density-lg);
  background-color: var(--cc-surface-header);
  border-bottom: var(--cc-border);
  min-height: 3.5rem;
}

.cc-topbar__start {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  flex: 1 1 auto;
  min-width: 0;
}

.cc-topbar__end {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-shrink: 0;
}

.cc-topbar__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-weight: var(--weight-extrabold);
  color: var(--color-on-surface);
  text-decoration: none;
  flex-shrink: 0;
}

.cc-topbar__spark {
  width: 1.25rem;
  height: 1.25rem;
  /* The one brand moment allowed on a working screen. */
  color: var(--color-primary);
  flex-shrink: 0;
}

.cc-topbar__brand-text {
  font-size: var(--text-body-md-size);
  white-space: nowrap;
}

.cc-topbar__pill {
  display: inline-block;
  padding: 1px var(--space-xs);
  border-radius: var(--radius-full);
  font-size: var(--text-label-size);
  font-weight: var(--weight-bold);
  background-color: var(--color-surface-sunken);
  color: var(--color-on-surface-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.cc-topbar__meta {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  font-size: var(--cc-text-size);
  color: var(--color-on-surface-muted);
}

/* --- Dense table — the shared queue lives in this --------------------------- */
.cc-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--cc-text-size);
}

.cc-table th {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: var(--cc-density-sm) var(--cc-density-md);
  text-align: left;
  background-color: var(--cc-surface-header);
  border-bottom: var(--cc-border);
  font-size: var(--text-label-size);
  font-weight: var(--text-label-weight);
  letter-spacing: var(--text-label-tracking);
  text-transform: uppercase;
  color: var(--color-on-surface-muted);
  white-space: nowrap;
}

.cc-table td {
  height: var(--cc-row-height);
  padding: var(--cc-density-sm) var(--cc-density-md);
  border-bottom: 1px solid var(--color-outline-variant);
  vertical-align: middle;
}

.cc-table tbody tr:nth-child(even) {
  background-color: var(--cc-surface-row-alt);
}

.cc-table tbody tr:hover {
  background-color: var(--cc-surface-hover);
}

.cc-table__num {
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* Wide content must scroll inside its own box rather than the page. */
.cc-table-wrap {
  overflow-x: auto;
  background-color: var(--cc-surface-card);
  border: var(--cc-border);
  border-radius: var(--cc-radius-md);
}

/* A keyboard hint next to an action. The console is keyboard-driven. */
.cc-kbd {
  display: inline-block;
  min-width: 1.5rem;
  padding: 0 var(--space-xs);
  border: var(--cc-border);
  border-radius: var(--cc-radius-sm);
  background-color: var(--cc-surface-row-alt);
  font-family: var(--font-mono);
  font-size: var(--text-label-size);
  text-align: center;
  color: var(--color-on-surface-muted);
}

/* --- LQS Tier dots (Plan correction 4) -------------------------------------- */
.lqs-dot {
  display: inline-block;
  width: 0.625rem;
  height: 0.625rem;
  border-radius: var(--radius-full);
}

.lqs-dot--high {
  background-color: var(--color-primary);
}

.lqs-dot--normal {
  background-color: var(--color-tertiary);
}

.lqs-dot--low {
  background-color: var(--color-outline-variant);
}

/* Pinned active claim banner in call centre console */
.cc-pinned-claim {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  padding: var(--cc-density-md) var(--space-base);
  background-color: var(--color-primary-soft);
  border: 1px solid var(--color-primary);
  border-radius: var(--cc-radius-md);
  flex-wrap: wrap;
}

.cc-pinned-claim__info {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  font-size: var(--cc-text-size);
  flex-wrap: wrap;
}

.cc-pinned-claim__actions {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  flex-shrink: 0;
}

/* Console filter bar */
.cc-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--cc-radius-md);
  border: var(--cc-border);
  background-color: var(--cc-surface-card);
}

/* ==========================================================================
   15. REFERRER SCREENS (Phase 3)

   Components that belong to one surface rather than to the system: the app
   header, the wallet card's internals, a referral row, the sticky CTA. They sit
   after the call-centre subset because they are referrer-only and nothing in
   §14 overrides them — a console screen never renders any of this.

   Every value is a token. No exceptions (MASTER_MAP §4.3).
   ========================================================================== */

/* The greeting bar. Cream-on-cream with the avatar leading, matching the
   reference screen's "Hey Thabo 👋". */
.app-header {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding-block: var(--space-md) var(--space-base);
}

.app-header__greeting {
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--text-headline-md-size);
  line-height: var(--text-headline-md-line);
  font-weight: var(--text-headline-md-weight);
  letter-spacing: var(--text-headline-lg-tracking);
}


/* A card that invites rather than demands — the "add your name" nudge a
   freshly signed-up referrer sees, since sign-in collects no name (ADR-013,
   task 2.3). Dismissible by doing it, not by a close button. */
.name-nudge {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  text-decoration: none;
  color: inherit;
  box-shadow:
    var(--shadow-soft),
    inset 0 0 0 2px var(--color-primary);
}

/* -------------------------------------------------------------- wallet -- */

.wallet-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.wallet-card__label {
  font-size: var(--text-body-lg-size);
  font-weight: var(--weight-semibold);
  color: var(--color-on-primary-soft);
}

/* The honest replacement for the design's "Cash out" button (ADR-007). It is
   information, so it is weighted as information — not as a disabled control. */
.wallet-card__next {
  font-size: var(--text-body-sm-size);
  line-height: var(--text-body-sm-line);
  font-weight: var(--weight-medium);
  color: var(--color-on-primary-soft);
}

.bank-card__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 3rem;
  height: 3rem;
  border-radius: var(--radius-full);
  background-color: var(--color-primary-soft);
  color: var(--color-on-primary-soft);
}

.bank-card__icon svg {
  width: 1.5rem;
  height: 1.5rem;
}

/* ------------------------------------------------------------ counters -- */

.chip__icon {
  width: 1.125rem;
  height: 1.125rem;
  color: var(--color-primary-strong);
}

.chip__icon--success {
  color: var(--color-on-success-container);
}

/* ----------------------------------------------------------- referrals -- */

.referral-row {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.referral-row__name {
  font-size: var(--text-body-lg-size);
  line-height: var(--text-body-lg-line);
  font-weight: var(--weight-bold);
  /* A long first name must not push the status pill off a 375px screen. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ----------------------------------------------------------------- CTA -- */

/* The primary action, held above the bottom nav rather than scrolling away.
   `position: sticky` inside the content flow, so it never covers the last row
   the way a fixed element would. */
.cta-sticky {
  position: sticky;
  bottom: calc(var(--nav-height) + var(--space-sm));
  z-index: calc(var(--z-nav) - 1);
  box-shadow: var(--shadow-lifted);
}

/* ------------------------------------------------------ navigation gaps -- */

/* A nav item whose route has not landed yet resolves to an empty href
   (partials/bottom_nav.html). Shown as visibly unavailable rather than as a
   link that goes nowhere. Nothing should render this once Phase 3 is complete,
   and tests/test_pwa.py asserts as much. */
.bottom-nav__item--pending {
  opacity: 0.4;
  pointer-events: none;
}

/* ==========================================================================
   16. REFER A FRIEND — Task 3.2
   ========================================================================== */

/* The mint promise banner: "We'll only call once… No spam, ever." */
.promise-banner {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  background-color: var(--color-success-container);
  color: var(--color-on-success-container);
  border-radius: var(--radius-md);
  padding: var(--space-md);
  box-shadow: var(--shadow-soft);
}

.promise-banner__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--radius-full);
  background-color: var(--color-success-container);
  color: var(--color-on-success-container);
}

.promise-banner__icon svg {
  width: 1.25rem;
  height: 1.25rem;
}

.promise-banner__text {
  font-size: var(--text-body-md-size);
  font-weight: var(--weight-medium);
  line-height: 1.35;
  margin: 0;
}

/* Product picker grid */
.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: var(--space-sm);
}

.product-option {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--space-md);
  background-color: var(--color-surface-card);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-md);
  cursor: pointer;
  text-align: center;
  box-shadow: var(--shadow-soft);
  transition:
    box-shadow var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out),
    transform var(--duration-fast) var(--ease-out);
}

.product-option:hover {
  border-color: var(--color-outline);
}

.product-option:active {
  transform: scale(var(--press-scale));
}

.product-option input[type="radio"] {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.product-option:has(input[type="radio"]:checked),
.product-option.is-selected {
  box-shadow:
    inset 0 0 0 2px var(--color-primary),
    var(--shadow-soft);
  border-color: var(--color-primary);
}

.product-option__icon {
  width: 3rem;
  height: 3rem;
  border-radius: var(--radius-full);
  background-color: var(--color-primary-soft);
  color: var(--color-on-primary-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: var(--space-xs);
}

.product-option__icon svg {
  width: 1.5rem;
  height: 1.5rem;
}

.product-option__name {
  font-size: var(--text-body-md-size);
  font-weight: var(--weight-bold);
  color: var(--color-on-surface);
}

.product-option__partner {
  font-size: var(--text-body-sm-size);
  color: var(--color-on-surface-muted);
}

/* Input with leading icon */
.input-with-icon {
  position: relative;
  display: flex;
  align-items: center;
}

.input-with-icon .input-icon {
  position: absolute;
  left: var(--space-md);
  color: var(--color-on-surface-faint);
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
}

.input-with-icon .input-icon svg {
  width: 1.25rem;
  height: 1.25rem;
}

.input-with-icon .input {
  padding-left: 2.75rem;
}

/* Success card */
.refer-success-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: var(--space-xl) var(--space-md);
  gap: var(--space-md);
}

.refer-success-icon {
  width: 4rem;
  height: 4rem;
  border-radius: var(--radius-full);
  background-color: var(--color-success-container);
  color: var(--color-on-success-container);
  display: flex;
  align-items: center;
  justify-content: center;
}

.refer-success-icon svg {
  width: 2rem;
  height: 2rem;
}

/* ==========================================================================
   17. CALL CENTRE CALL CARD — Task 4.2
   ========================================================================== */

.cc-card-layout {
  display: grid;
  grid-template-columns: 320px 1fr 380px;
  gap: var(--space-md);
  align-items: start;
}

.cc-card-col {
  min-width: 0;
}

@media (max-width: 1200px) {
  .cc-card-layout {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width: 768px) {
  .cc-card-layout {
    grid-template-columns: 1fr;
  }
}

.cc-panel {
  background-color: var(--cc-surface-card);
  border: var(--cc-border);
  border-radius: var(--cc-radius-md);
  padding: var(--cc-density-md);
  box-shadow: var(--cc-shadow);
}

.cc-consent-card {
  background-color: var(--cc-surface-card);
  border: 2px solid var(--color-primary);
  border-radius: var(--cc-radius-md);
  padding: var(--space-md);
  box-shadow: var(--shadow-soft);
}

.cc-consent-body {
  font-size: var(--text-body-md-size);
  line-height: var(--text-body-md-line);
  color: var(--color-on-surface);
  background-color: var(--color-surface-alt);
  padding: var(--space-md);
  border-radius: var(--cc-radius);
  border-left: 4px solid var(--color-primary-strong);
  margin-top: var(--space-sm);
  font-weight: var(--weight-medium);
}

.cc-referee-phone {
  font-family: var(--font-mono);
  font-size: 1.5rem;
  font-weight: var(--weight-bold);
  color: var(--color-on-surface);
  letter-spacing: 0.04em;
}

.cc-history-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  max-height: 220px;
  overflow-y: auto;
  padding-right: var(--space-xs);
}

.cc-history-item {
  padding: var(--cc-density-sm);
  background-color: var(--cc-surface-row-alt);
  border-radius: var(--cc-radius-sm);
  border-left: 3px solid var(--color-outline-variant);
  font-size: var(--cc-text-size);
}

.cc-shortcuts-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xs);
  padding: var(--cc-density-sm) var(--cc-density-md);
  background-color: var(--cc-surface-row-alt);
  border: var(--cc-border);
  border-radius: var(--cc-radius);
  font-size: var(--text-label-size);
}

.cc-outcome-btn-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-xs);
}

/* --- Staff Navigation bar in topbar -------------------------------------- */
.cc-nav {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  overflow-x: auto;
  scrollbar-width: none;
}

.cc-nav::-webkit-scrollbar {
  display: none;
}

.cc-nav__group {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.cc-nav__divider {
  width: 1px;
  height: 1.25rem;
  background-color: var(--color-outline-variant);
  margin: 0 var(--space-xs);
  flex-shrink: 0;
}

.cc-nav__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--cc-radius);
  color: var(--color-on-surface-muted);
  text-decoration: none;
  font-size: var(--cc-text-size);
  font-weight: var(--weight-medium);
  white-space: nowrap;
  transition: all var(--duration-fast) var(--ease-out);
}

.cc-nav__link:hover {
  background-color: var(--cc-surface-hover);
  color: var(--color-on-surface);
}

.cc-nav__link.is-active,
.cc-nav__link[aria-current="page"] {
  background-color: var(--color-primary-soft);
  color: var(--color-on-primary-soft);
  font-weight: var(--weight-bold);
  box-shadow: inset 0 0 0 1px var(--color-primary-strong);
}

.cc-nav__icon {
  width: 0.9375rem;
  height: 0.9375rem;
  flex-shrink: 0;
}

/* User Identity Capsule & Roles */
.cc-user-capsule {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--cc-density-xs) var(--space-xs);
  border-radius: var(--radius-full);
  background-color: var(--cc-surface-row-alt);
  border: var(--cc-border);
}

.cc-user-capsule--drawer {
  padding: var(--space-xs);
  background-color: transparent;
  border: none;
}

.cc-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: var(--radius-full);
  background-color: var(--color-surface-inverse);
  color: var(--color-on-surface-inverse);
  font-family: var(--font-mono);
  font-size: var(--text-label-size);
  font-weight: var(--weight-bold);
  flex-shrink: 0;
}

.cc-avatar--lg {
  width: 2.25rem;
  height: 2.25rem;
  font-size: var(--text-body-sm-size);
}

.cc-user-info {
  display: flex;
  flex-direction: column;
  gap: 0;
  line-height: 1.1;
  padding-right: var(--space-xs);
}

.cc-user-name {
  font-size: var(--text-label-size);
  font-weight: var(--weight-bold);
  color: var(--color-on-surface);
  max-width: 140px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cc-role-badge {
  display: inline-block;
  font-size: 0.625rem;
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  line-height: 1;
}

.cc-role-badge--admin {
  color: var(--color-tertiary);
}

.cc-role-badge--agent {
  color: var(--color-on-surface-faint);
}

/* Logout Form & Button */
.cc-logout-form {
  margin: 0;
  display: inline-flex;
}

.cc-logout-form--full {
  width: 100%;
}

.cc-logout-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--cc-radius);
  background: transparent;
  border: var(--cc-border);
  color: var(--color-on-surface-muted);
  font-size: var(--cc-text-size);
  font-weight: var(--weight-medium);
  cursor: pointer;
  min-height: 2rem;
  transition: all var(--duration-fast) var(--ease-out);
}

.cc-logout-btn:hover {
  background-color: var(--color-error-container);
  color: var(--color-on-error-container);
  border-color: var(--color-error);
}

.cc-icon-sm {
  width: 0.875rem;
  height: 0.875rem;
  flex-shrink: 0;
}

/* Mobile Toggle & Drawer Navigation */
.cc-mobile-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 4px;
  width: 2.25rem;
  height: 2.25rem;
  padding: 6px;
  background: transparent;
  border: var(--cc-border);
  border-radius: var(--cc-radius);
  cursor: pointer;
  color: var(--color-on-surface);
}

.cc-mobile-toggle__bar {
  display: block;
  width: 1.125rem;
  height: 2px;
  background-color: var(--color-on-surface);
  border-radius: 2px;
  transition: all var(--duration-fast) var(--ease-out);
}

.cc-mobile-backdrop {
  position: fixed;
  inset: 0;
  background-color: rgb(var(--shadow-rgb) / 40%);
  z-index: var(--z-modal);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--duration-base) var(--ease-out), visibility var(--duration-base);
}

.cc-mobile-backdrop.is-open {
  opacity: 1;
  visibility: visible;
}

.cc-mobile-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 300px;
  max-width: 85vw;
  background-color: var(--cc-surface-header);
  z-index: calc(var(--z-modal) + 1);
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform var(--duration-slow) var(--ease-out);
  box-shadow: var(--shadow-lifted);
  border-left: var(--cc-border);
}

.cc-mobile-drawer.is-open {
  transform: translateX(0);
}

.cc-mobile-drawer__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-md);
  border-bottom: var(--cc-border);
}

.cc-mobile-drawer__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--radius-full);
  border: var(--cc-border);
  background: transparent;
  color: var(--color-on-surface);
  cursor: pointer;
  transition: background-color var(--duration-fast);
}

.cc-mobile-drawer__close:hover {
  background-color: var(--cc-surface-hover);
}

.cc-mobile-drawer__close svg {
  width: 1.125rem;
  height: 1.125rem;
}

.cc-mobile-drawer__body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: var(--space-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.cc-mobile-nav__section {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.cc-mobile-nav__heading {
  font-size: var(--text-label-size);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-on-surface-faint);
  padding: 0 var(--space-xs);
}

.cc-mobile-nav__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.cc-mobile-nav__item {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--cc-radius);
  color: var(--color-on-surface);
  text-decoration: none;
  font-size: var(--text-body-md-size);
  font-weight: var(--weight-medium);
  min-height: 44px;
  transition: background-color var(--duration-fast);
}

.cc-mobile-nav__item:hover {
  background-color: var(--cc-surface-hover);
}

.cc-mobile-nav__item.is-active {
  background-color: var(--color-primary-soft);
  color: var(--color-on-primary-soft);
  font-weight: var(--weight-bold);
}

.cc-mobile-drawer__footer {
  padding: var(--space-md);
  border-top: var(--cc-border);
  background-color: var(--cc-surface-row-alt);
}

body.cc-drawer-locked {
  overflow: hidden !important;
}

/* Responsive Comparison Grid for Manual Review */
.cc-comparison-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-md);
  margin-top: var(--space-sm);
}

/* Breakpoint for Console Mobile Navigation */
@media (max-width: 1024px) {
  .cc-nav {
    display: none;
  }

  .cc-user-capsule {
    display: none;
  }

  .cc-logout-btn .cc-logout-text {
    display: none;
  }

  .cc-logout-btn {
    padding: var(--space-xs);
    border-radius: var(--radius-full);
  }

  .cc-mobile-toggle {
    display: flex;
  }
}

@media (max-width: 768px) {
  .cc-comparison-grid {
    grid-template-columns: 1fr;
  }

  .cc-filters {
    flex-direction: column;
    align-items: stretch;
  }

  .cc-filters > * {
    width: 100% !important;
  }

  .cc-topbar {
    padding-inline: var(--space-gutter);
  }
}



