/* ============================================================
 * PAYMENT EXECUTION (#902)
 *
 * The confirmation ceremony, live progress, and permanent log for running a
 * payment instruction through the bank API.
 *
 * Built on existing primitives wherever one fits — `.ng-form-modal` for the
 * shell, `.ng-form-preview` for the async count panel, `.ng-status-pill` for
 * state, `.ng-loader` for waiting. What is new here is only what had no
 * neighbour: a mode banner that must dominate the dialog, a challenge field
 * that must read as a transcription target rather than a text input, a
 * determinate progress meter, and a log feed.
 *
 * Every colour resolves to a semantic token or a color-mix against
 * --color-bg-surface, so all of it flips in dark mode. px only.
 * ============================================================ */

/* ---------- Upstream banner ----------
 * The first thing read and the last thing doubted. Full-bleed inside the
 * modal body, heavier than the surrounding text, and tinted by intent —
 * info for a confirmed stand-in bank, danger for the real one, warning
 * when the payment service could not be asked. The unknown state is
 * deliberately closer to danger than to info: an unverified system is
 * treated as real, and its colour should not read as reassurance. */
.ng-pay-exec__mode {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid transparent;
  border-radius: var(--radius-lg);
  margin-bottom: var(--space-4);
}
.ng-pay-exec__mode--simulation {
  border-color: color-mix(in srgb, var(--color-feedback-info) 35%, transparent);
  background: color-mix(in srgb, var(--color-feedback-info) 10%, var(--color-bg-surface));
}
.ng-pay-exec__mode--live {
  border-color: color-mix(in srgb, var(--color-feedback-danger) 45%, transparent);
  background: color-mix(in srgb, var(--color-feedback-danger) 12%, var(--color-bg-surface));
}
.ng-pay-exec__mode--unknown {
  border-color: color-mix(in srgb, var(--color-feedback-warning) 45%, transparent);
  background: color-mix(in srgb, var(--color-feedback-warning) 12%, var(--color-bg-surface));
}
.ng-pay-exec__mode-icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-full);
  font-size: var(--font-size-lg);
}
.ng-pay-exec__mode--simulation .ng-pay-exec__mode-icon {
  background: color-mix(in srgb, var(--color-feedback-info) 18%, var(--color-bg-surface));
  color: var(--color-feedback-info);
}
.ng-pay-exec__mode--live .ng-pay-exec__mode-icon {
  background: color-mix(in srgb, var(--color-feedback-danger) 18%, var(--color-bg-surface));
  color: var(--color-feedback-danger);
}
.ng-pay-exec__mode--unknown .ng-pay-exec__mode-icon {
  background: color-mix(in srgb, var(--color-feedback-warning) 18%, var(--color-bg-surface));
  color: var(--color-feedback-warning);
}
.ng-pay-exec__mode-title {
  margin: 0 0 var(--space-1);
  font-family: var(--font-family-display);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.ng-pay-exec__mode--simulation .ng-pay-exec__mode-title { color: var(--color-feedback-info); }
.ng-pay-exec__mode--live .ng-pay-exec__mode-title { color: var(--color-feedback-danger); }
.ng-pay-exec__mode--unknown .ng-pay-exec__mode-title { color: var(--color-feedback-warning); }
.ng-pay-exec__mode-text {
  margin: 0;
  font-family: var(--font-family-ui);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-normal);
  color: var(--color-text-default);
}

/* ---------- Consequence panel ----------
 * States what a live run would do, in the same words either way. Quieter
 * than the mode banner on purpose: the banner says which world you are in,
 * this says what the action weighs. */
.ng-pay-exec__consequence {
  padding: var(--space-4);
  border: 1px solid var(--color-border-default);
  border-left: 3px solid var(--color-feedback-warning);
  border-radius: var(--radius-md);
  background: var(--color-bg-raised);
  margin-bottom: var(--space-4);
}
.ng-pay-exec__consequence-heading {
  margin: 0 0 var(--space-2);
  font-family: var(--font-family-display);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-strong);
}
.ng-pay-exec__consequence-text {
  margin: 0;
  font-family: var(--font-family-ui);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-normal);
  color: var(--color-text-default);
}
.ng-pay-exec__consequence-text strong {
  font-family: var(--font-family-data);
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
  color: var(--color-text-strong);
}

/* ---------- Meta row (file / provider) ---------- */
.ng-pay-exec__meta {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.ng-pay-exec__meta-item {
  min-width: 0;
}
.ng-pay-exec__meta-label {
  display: block;
  margin-bottom: 2px;
  font-family: var(--font-family-ui);
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
}
.ng-pay-exec__meta-value {
  display: block;
  font-family: var(--font-family-ui);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-default);
  overflow-wrap: anywhere;
}

/* ---------- Challenge field ----------
 * The code is displayed as data, not prose: monospaced, spaced out, and
 * selectable. The input sits directly beneath so the eye travels from the
 * code to the field without hunting. */
.ng-pay-exec__challenge {
  margin-top: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-lg);
  background: var(--color-bg-raised);
}
.ng-pay-exec__challenge-label {
  display: block;
  margin-bottom: var(--space-2);
  font-family: var(--font-family-display);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-strong);
}
.ng-pay-exec__challenge-code {
  display: block;
  padding: var(--space-3);
  margin-bottom: var(--space-3);
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-bg-sunken);
  font-family: var(--font-family-data);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.18em;
  text-align: center;
  color: var(--color-text-strong);
  user-select: all;
}
.ng-pay-exec__challenge-input.form-control {
  font-family: var(--font-family-data);
  font-size: var(--font-size-lg);
  letter-spacing: 0.12em;
  text-align: center;
  text-transform: uppercase;
}
.ng-pay-exec__challenge-help {
  margin: var(--space-2) 0 0;
  font-family: var(--font-family-ui);
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
}
.ng-pay-exec__challenge-error {
  margin: var(--space-2) 0 0;
  font-family: var(--font-family-ui);
  font-size: var(--font-size-xs);
  color: var(--color-feedback-danger);
}

/* ---------- Preview metric strip ----------
 * The shared `.ng-form-preview__stat-value` is sized for short counts
 * ("4,657"). A PGK total is far longer, and at --font-size-2xl inside a
 * quarter-width column it breaks after the currency symbol — "K" alone on
 * one line above the figure, which reads as a different number entirely.
 * Scoped to this modal so the shared component keeps its own sizing. */
.ng-pay-exec__stats .ng-form-preview__stat-value {
  font-size: var(--font-size-xl);
  overflow-wrap: anywhere;
}
.ng-pay-exec__stats .ng-form-preview__stat--amount .ng-form-preview__stat-value {
  font-size: var(--font-size-lg);
  /* Keep the currency symbol with its figure — the whole point of the fix. */
  white-space: nowrap;
}

/* ---------- Skipped / already-submitted hints ---------- */
.ng-pay-exec__hint {
  margin: var(--space-2) 0 0;
  font-family: var(--font-family-ui);
  font-size: var(--font-size-xs);
  line-height: var(--line-height-snug);
  color: var(--color-text-muted);
}

/* ---------- Progress ---------- */
.ng-pay-exec__progress {
  padding: var(--space-4) 0;
}
.ng-pay-exec__progress-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.ng-pay-exec__progress-percent {
  font-family: var(--font-family-data);
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
  color: var(--color-text-strong);
}
.ng-pay-exec__meter {
  height: 10px;
  border-radius: var(--radius-full);
  background: var(--color-bg-sunken);
  overflow: hidden;
}
.ng-pay-exec__meter-fill {
  height: 100%;
  width: 0;
  border-radius: var(--radius-full);
  background: var(--color-brand-secondary);
  transition: width var(--duration-slow, 320ms) var(--easing-standard, ease);
}
.ng-pay-exec__meter-fill--done { background: var(--color-feedback-success); }
.ng-pay-exec__meter-fill--failures { background: var(--color-feedback-warning); }
.ng-pay-exec__meter-fill--stopped { background: var(--color-text-faint); }
.ng-pay-exec__counts {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-2);
  margin-top: var(--space-4);
}
.ng-pay-exec__count {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-3);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-md);
  background: var(--color-bg-surface);
  text-align: center;
}
.ng-pay-exec__count-value {
  font-family: var(--font-family-data);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
  color: var(--color-text-strong);
}
.ng-pay-exec__count-label {
  font-family: var(--font-family-ui);
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
}

/* ---------- Log feed ----------
 * A vertical rail with one dot per event, mirroring the audit-trail feed on
 * the applicant profile so the two read as the same kind of object. */
.ng-pay-exec__feed {
  position: relative;
  margin: 0;
  padding: 0 0 0 var(--space-6);
  list-style: none;
}
.ng-pay-exec__feed::before {
  content: '';
  position: absolute;
  top: 6px;
  bottom: 6px;
  left: 5px;
  width: 2px;
  background: var(--color-border-subtle);
}
.ng-pay-exec__feed-item {
  position: relative;
  padding: 0 0 var(--space-4);
}
.ng-pay-exec__feed-item::before {
  content: '';
  position: absolute;
  top: 5px;
  left: calc(var(--space-6) * -1 + 1px);
  width: 10px;
  height: 10px;
  border-radius: var(--radius-full);
  background: var(--color-text-faint);
  box-shadow: 0 0 0 3px var(--color-bg-surface);
}
.ng-pay-exec__feed-item--success::before { background: var(--color-feedback-success); }
.ng-pay-exec__feed-item--warning::before { background: var(--color-feedback-warning); }
.ng-pay-exec__feed-item--danger::before  { background: var(--color-feedback-danger); }
.ng-pay-exec__feed-item--info::before    { background: var(--color-feedback-info); }
.ng-pay-exec__feed-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
  margin-bottom: 2px;
}
.ng-pay-exec__feed-label {
  font-family: var(--font-family-display);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-strong);
}
.ng-pay-exec__feed-time {
  font-family: var(--font-family-data);
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}
.ng-pay-exec__feed-text {
  margin: 0;
  font-family: var(--font-family-ui);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-snug);
  color: var(--color-text-default);
}

/* ---------- Run list ---------- */
.ng-pay-exec__runs {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-5);
}
.ng-pay-exec__run {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-3);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-md);
  background: var(--color-bg-surface);
  text-align: left;
  cursor: pointer;
}
.ng-pay-exec__run:hover,
.ng-pay-exec__run:focus-visible {
  border-color: var(--color-border-strong);
  background: var(--color-bg-raised);
}
.ng-pay-exec__run[aria-current='true'] {
  border-color: var(--color-brand-secondary);
  background: color-mix(in srgb, var(--color-brand-secondary) 8%, var(--color-bg-surface));
}
.ng-pay-exec__run-main { flex: 1 1 auto; min-width: 0; }
.ng-pay-exec__run-title {
  display: block;
  font-family: var(--font-family-ui);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-default);
}
.ng-pay-exec__run-sub {
  display: block;
  font-family: var(--font-family-ui);
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
}

/* ---------- Beneficiary table search + filter ---------- */
.ng-pay-exec__table-tools {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.ng-pay-exec__search {
  position: relative;
  flex: 1 1 240px;
  min-width: 0;
}
.ng-pay-exec__search-icon {
  position: absolute;
  top: 50%;
  left: var(--space-3);
  transform: translateY(-50%);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  pointer-events: none;
}
.ng-pay-exec__search .ng-pay-exec__search-input {
  /* clears the search icon; the two-class selector out-specifies
     _forms.css's `input.form-control` padding !important */
  padding-left: var(--space-8) !important;
}
.ng-pay-exec__status-filter {
  flex: 0 0 auto;
  width: auto;
  min-width: 180px;
}
.ng-pay-exec__table-empty {
  margin: var(--space-3) 0 0;
  padding: var(--space-4);
  text-align: center;
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  background: var(--color-bg-sunken);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-md);
}

/* ---------- Beneficiary outcome table ---------- */
.ng-pay-exec__table-wrap {
  max-height: 380px;
  overflow: auto;
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-md);
}
.ng-pay-exec__table {
  width: 100%;
  margin: 0;
  border-collapse: collapse;
}
.ng-pay-exec__table th,
.ng-pay-exec__table td {
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-border-subtle);
  font-size: var(--font-size-sm);
  text-align: left;
  white-space: nowrap;
}
.ng-pay-exec__table th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--color-bg-sunken);
  font-family: var(--font-family-display);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}
.ng-pay-exec__table tr:last-child td { border-bottom: 0; }
.ng-pay-exec__table td.is-numeric,
.ng-pay-exec__table td.is-code {
  font-family: var(--font-family-data);
  font-variant-numeric: tabular-nums;
}
.ng-pay-exec__row--attention {
  background: color-mix(in srgb, var(--color-feedback-danger) 6%, var(--color-bg-surface));
}

/* Retry — a compact inline action inside the status cell, beside the pill, so
   the remedy sits next to the failure. Rendered only on bank-rejected rows
   (execute.blade.php). Colour, border and the hover fill all come from the DS
   secondary button (`.btn-default` in _buttons.css, which owns them with
   `!important`); this only tightens it to an inline, table-cell scale, so it
   stays theme-correct in both modes for free. */
.ng-pay-exec__retry.btn.btn-default.btn-xs {
  margin-left: var(--space-2);
  padding: 1px var(--space-2);
  font-family: var(--font-family-display);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  line-height: 1.5;
  vertical-align: baseline;
  border-radius: var(--radius-sm);
}

/* Never-sent recovery banner (#937): a warning-toned strip above the event
   feed, shown only when a run has rows that resolved to ERROR without ever
   reaching the bank. Mirrors the .ng-pay-exec__mode--unknown warning panel so
   the recovery affordance reads as attention-needed, not danger. */
.ng-pay-exec__reattempt {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  padding: var(--space-3);
  border: 1px solid color-mix(in srgb, var(--color-feedback-warning) 45%, transparent);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--color-feedback-warning) 12%, var(--color-bg-surface));
}
.ng-pay-exec__reattempt-text {
  font-size: var(--font-size-sm);
  color: var(--color-text-default);
}
.ng-pay-exec__reattempt-btn.btn.btn-warning.btn-xs {
  flex: 0 0 auto;
  font-family: var(--font-family-display);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  border-radius: var(--radius-sm);
}

@media (max-width: 767px) {
  .ng-pay-exec__meta,
  .ng-pay-exec__counts {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .ng-pay-exec__reattempt {
    flex-direction: column;
    align-items: stretch;
  }
  .ng-pay-exec__challenge-code {
    font-size: var(--font-size-lg);
    letter-spacing: 0.12em;
  }
}
