/*
 * WalletUp console design system — "Quiet Ledger".
 *
 * One stylesheet for merchant and admin. Served as a static file rather than inlined per
 * response: it was previously duplicated inside two layout functions, so the two halves of
 * the product drifted apart every time either was touched.
 *
 * Depth comes from hairline rings and layered tint, never shadow. Warm neutrals rather than
 * cold grey, because this is a console people keep open all day. Mobile styles are the base;
 * larger screens are progressive enhancement.
 *
 * No webfont is fetched. The old layout pulled Inter from Google's CDN, which put a
 * third-party request in front of a payments console and blocked first paint on it.
 */

/* ============================================================ 1. tokens == */

:root {
  --ink-0:   #ffffff;
  --ink-25:  #fdfcfb;
  --ink-50:  #faf9f7;
  --ink-100: #f3f1ee;
  --ink-200: #e8e4de;
  --ink-300: #d7d2ca;
  --ink-400: #a9a39a;
  --ink-500: #7a746b;
  --ink-600: #58534b;
  --ink-700: #3e3a34;
  --ink-800: #272420;
  --ink-900: #171512;

  --accent-50:  #f4f2ff;
  --accent-100: #eae6fe;
  --accent-200: #d9d2fd;
  --accent-400: #a08cf6;
  --accent:     #6c5ce7;
  --accent-600: #5f4ede;
  --accent-700: #4e3ec4;
  --on-accent:  #ffffff;

  --ok-bg:   #e9f6ee; --ok-fg:   #1a6a3f; --ok-ring:   #cde7d9;
  --warn-bg: #fdf4e4; --warn-fg: #8a5910; --warn-ring: #f2e1c2;
  --bad-bg:  #fdedec; --bad-fg:  #9a2b24; --bad-ring:  #f5d7d4;
  --info-bg: #edf0fd; --info-fg: #33449a; --info-ring: #d7dff8;

  --canvas:      var(--ink-50);
  --surface:     var(--ink-0);
  --surface-alt: var(--ink-25);
  --sunken:      var(--ink-100);
  --hairline:    var(--ink-200);
  --hairline-soft: var(--ink-100);
  --text:        var(--ink-800);
  --text-soft:   var(--ink-600);
  --text-muted:  var(--ink-500);
  --text-faint:  #736d63; /* 5.13:1 on white — AA for the small caps labels */

  --r-xs: 6px; --r-sm: 8px; --r-md: 12px; --r-lg: 16px; --r-xl: 22px; --r-pill: 999px;

  --dur-fast: 120ms;
  --dur:      190ms;
  --dur-slow: 300ms;
  --ease:      cubic-bezier(0.22, 1, 0.36, 1);
  --ease-soft: cubic-bezier(0.33, 0.85, 0.35, 1);

  --nav-w: 248px;
  --gutter: 1rem;

  --font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  color-scheme: light;
}

[data-theme='dark'] {
  --ink-0:   #17150F;
  --ink-25:  #1b1915;
  --ink-50:  #201d19;
  --ink-100: #27241f;
  --ink-200: #332f29;
  --ink-300: #45403a;
  --ink-400: #6d675e;
  --ink-500: #958e84;
  --ink-600: #b9b2a8;
  --ink-700: #d9d4cc;
  --ink-800: #efece6;
  --ink-900: #ffffff;

  --accent-50:  #221c3f;
  --accent-100: #2c2454;
  --accent-200: #3b3070;
  --accent-400: #8f7bf2;
  --accent:     #a593fb;
  --accent-600: #b7a8fc;
  --accent-700: #cabffd;
  --on-accent:  #1a1430;

  --ok-bg:   #16271e; --ok-fg:   #85d6aa; --ok-ring:   #234533;
  --warn-bg: #2a2013; --warn-fg: #e7bc78; --warn-ring: #493a20;
  --bad-bg:  #2c1a18; --bad-fg:  #efa39c; --bad-ring:  #4c2b27;
  --info-bg: #191d32; --info-fg: #a6b3ef; --info-ring: #2b3256;

  --canvas:      #141210;
  --surface:     var(--ink-25);
  --surface-alt: var(--ink-50);
  --sunken:      var(--ink-100);
  --hairline:    var(--ink-200);
  --hairline-soft: var(--ink-100);
  --text:        var(--ink-800);
  --text-soft:   var(--ink-600);
  --text-muted:  var(--ink-500);
  --text-faint:  var(--ink-400);

  color-scheme: dark;
}

/* ============================================================== 2. base == */

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

html { -webkit-text-size-adjust: 100%; }
/* No overflow-x:hidden here. It turns the root into a scroll container, and position:sticky
   then never engages for any descendant — which is why the sidebar scrolled away with the
   page. Horizontal overflow is contained where it originates instead (.table-wrap et al). */
html, body { max-width: 100%; }

body {
  font-family: var(--font);
  background-color: var(--canvas);
  /* Two faint washes give the page a centre of gravity without a gradient that
     announces itself. Fixed so scrolling does not drag the light around. */
  background-image:
    radial-gradient(115% 75% at 0% 0%, color-mix(in oklab, var(--accent) 8%, transparent), transparent 58%),
    radial-gradient(85% 65% at 100% 0%, color-mix(in oklab, #3fa89b 5%, transparent), transparent 52%);
  background-attachment: fixed;
  color: var(--text);
  font-size: 15px;
  line-height: 1.55;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-variant-numeric: tabular-nums;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 2px; }

h1, h2, h3, h4 { letter-spacing: -0.017em; line-height: 1.25; font-weight: 660; color: var(--text); }
h1 { font-size: 1.5rem; }
h2 { font-size: 1.05rem; }
h3 { font-size: 0.95rem; }
small, .small { font-size: 0.8rem; }
code, kbd, pre, .mono { font-family: var(--mono); font-size: 0.82em; }

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

/* ===================================================== 3. accessibility == */

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}
:where(a, button, input, select, textarea):focus:not(:focus-visible) { outline: none; }

/* Keyboard and screen-reader users get past the navigation in one keystroke. */
.skip {
  position: fixed; left: 12px; top: -60px; z-index: 90;
  padding: 10px 16px; border-radius: var(--r-md);
  background: var(--surface); color: var(--text); font-weight: 600;
  box-shadow: inset 0 0 0 1px var(--hairline);
  transition: top var(--dur) var(--ease);
}
.skip:focus { top: 12px; text-decoration: none; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Any control that only shows an icon still needs a reachable target. */
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: var(--r-md);
  background: transparent; border: 0; color: var(--text-muted); cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.icon-btn:hover { background: var(--sunken); color: var(--text); }
/* The button is 40px for touch; the glyph inside it is not. */
.icon-btn svg { width: 18px; height: 18px; }

/* ============================================================ 4. layout == */

.shell { display: flex; flex-direction: column; min-height: 100vh; }

/* --- top bar: the only nav on small screens ---------------------------- */
.topbar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.6rem var(--gutter);
  background: color-mix(in oklab, var(--surface) 88%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  -webkit-backdrop-filter: saturate(1.4) blur(10px);
  box-shadow: inset 0 -1px 0 var(--hairline);
}
.topbar .spacer { flex: 1; }

.brand { display: inline-flex; align-items: center; gap: 0.55rem; font-weight: 700; letter-spacing: -0.02em; color: var(--text); }
.brand:hover { text-decoration: none; }
/* The logo carries its own rounded gradient, so the tile behind it is gone — two stacked
   corner radii read as a badge inside a badge. */
.brand .mark {
  width: 30px; height: 30px; flex: none;
  display: grid; place-items: center;
}
.brand .mark img { width: 30px; height: 30px; border-radius: 8px; display: block; }
.brand .mark svg { width: 16px; height: 16px; }
.brand .name { font-size: 0.98rem; }
.brand .env {
  font-size: 10px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  padding: 2px 6px; border-radius: var(--r-pill);
  background: var(--warn-bg); color: var(--warn-fg);
  box-shadow: inset 0 0 0 1px var(--warn-ring);
}

/* --- side navigation --------------------------------------------------- */
.nav {
  background: var(--surface);
  box-shadow: inset -1px 0 0 var(--hairline);
  display: flex; flex-direction: column;
}
.nav__head { padding: 1.1rem 1rem 0.9rem; box-shadow: inset 0 -1px 0 var(--hairline-soft); }
.nav__scroll { flex: 1; overflow-y: auto; padding: 0.9rem 0.6rem 1.2rem; }
.nav__group + .nav__group { margin-top: 1.15rem; }
.nav__label {
  font-size: 10px; font-weight: 700; letter-spacing: 0.11em; text-transform: uppercase;
  color: var(--text-faint); padding: 0 0.7rem; margin-bottom: 0.4rem;
}
.nav__link {
  position: relative;
  display: flex; align-items: center; gap: 0.65rem;
  padding: 0.5rem 0.7rem; margin-bottom: 2px;
  border-radius: var(--r-md);
  font-size: 0.875rem; font-weight: 520;
  color: var(--text-soft);
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.nav__link:hover { background: var(--sunken); color: var(--text); text-decoration: none; }
.nav__link svg { width: 17px; height: 17px; flex: none; opacity: 0.8; }
.nav__link .label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* The active item gets a short spine rather than a filled block: it marks position
   without turning a quiet list into a row of buttons. */
.nav__link[aria-current='page'] {
  background: var(--accent-50);
  color: var(--accent-700);
  font-weight: 640;
}
.nav__link[aria-current='page']::before {
  content: ''; position: absolute; left: 0; top: 50%;
  width: 3px; height: 18px; margin-top: -9px;
  border-radius: 0 var(--r-pill) var(--r-pill) 0;
  background: var(--accent);
  animation: spine var(--dur-slow) var(--ease) both;
}
.nav__link[aria-current='page'] svg { opacity: 1; }
@keyframes spine { from { transform: scaleY(0.2); opacity: 0; } to { transform: none; opacity: 1; } }

.nav__foot { padding: 0.7rem; box-shadow: inset 0 1px 0 var(--hairline-soft); }
.nav__user { display: flex; align-items: center; gap: 0.6rem; padding: 0.45rem 0.5rem; border-radius: var(--r-md); }
.nav__account {
  display: flex; align-items: center; gap: 0.6rem; flex: 1; min-width: 0;
  padding: 0.2rem; margin: -0.2rem; border-radius: var(--r-md);
  color: inherit; text-decoration: none;
  transition: background var(--dur) var(--ease);
}
.nav__account:hover { background: var(--sunken); text-decoration: none; }
.nav__account:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.nav__user .who { min-width: 0; flex: 1; }
.nav__user .who b { display: block; font-size: 0.83rem; font-weight: 620; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav__user .who span { display: block; font-size: 0.74rem; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.avatar {
  width: 32px; height: 32px; border-radius: var(--r-pill); flex: none;
  display: grid; place-items: center;
  font-size: 0.75rem; font-weight: 700; letter-spacing: 0.02em;
  background: var(--accent-100); color: var(--accent-700);
}

/* --- drawer behaviour (small screens) ---------------------------------- */
.nav {
  position: fixed; inset: 0 auto 0 0; z-index: 60;
  width: min(86vw, var(--nav-w));
  transform: translate3d(-100%, 0, 0);
  visibility: hidden;
  transition: transform var(--dur) var(--ease), visibility var(--dur);
}
.nav[data-open='true'] { transform: none; visibility: visible; }
.scrim {
  position: fixed; inset: 0; z-index: 50;
  background: color-mix(in oklab, var(--ink-900) 42%, transparent);
  opacity: 0; visibility: hidden;
  transition: opacity var(--dur) var(--ease), visibility var(--dur);
}
.scrim[data-open='true'] { opacity: 1; visibility: visible; }

/* Flex and grid children default to min-width:auto and will happily grow past their
   container to fit content. Every level of the shell has to opt out explicitly or one wide
   descendant drags the whole column off the side of a phone. */
.shell > * { min-width: 0; max-width: 100%; }
.main { flex: 1; min-width: 0; max-width: 100%; padding: 1.15rem var(--gutter) 3rem; }
.wrap { width: 100%; max-width: min(1180px, 100%); margin: 0 auto; min-width: 0; }
.stat-grid, .section, .card, .table-wrap { min-width: 0; max-width: 100%; }

@media (min-width: 900px) {
  :root { --gutter: 2rem; }
  .shell { flex-direction: row; }
  .nav {
    position: sticky; top: 0; height: 100vh;
    width: var(--nav-w); flex: none;
    transform: none; visibility: visible;
  }
  .scrim, .topbar__menu { display: none; }
  .topbar { position: static; background: transparent; backdrop-filter: none; box-shadow: none; padding: 1.4rem var(--gutter) 0; }
  .topbar .brand { display: none; }
  .main { padding-top: 0.5rem; }
}

/* ======================================================== 5. page head == */

.page-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 1rem; margin: 0.6rem 0 1.5rem; }
.eyebrow { font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-faint); margin-bottom: 0.35rem; }
.page-head h1 { font-size: clamp(1.35rem, 1.1rem + 1.1vw, 1.75rem); }

/* The house motif: a short rule that fades out, rather than a solid highlighter bar. */
.seam { height: 2px; width: 34px; border-radius: var(--r-pill); margin-top: 0.55rem;
  background: linear-gradient(90deg, var(--accent), color-mix(in oklab, var(--accent) 10%, transparent)); }
.seam--sm { width: 22px; margin-top: 0.35rem; }
.page-head p.sub { color: var(--text-muted); font-size: 0.9rem; margin-top: 0.7rem; max-width: 62ch; }

/* ========================================================= 6. surfaces == */

.card {
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: inset 0 0 0 1px var(--hairline);
  transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.card--pad { padding: 1.25rem; }
.card--quiet { background: var(--surface-alt); }
.card--link { cursor: pointer; }
.card--link:hover { box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--accent) 36%, var(--hairline)); transform: translateY(-1px); }
.card--link:active { transform: none; }

.section { background: var(--surface); border-radius: var(--r-lg); box-shadow: inset 0 0 0 1px var(--hairline); margin-bottom: 1.15rem; }
.section__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; padding: 1.15rem 1.25rem 0; }
.section__head h2 { font-size: 1rem; }
.section__body { padding: 1.15rem 1.25rem 1.25rem; }
.section__desc { color: var(--text-muted); font-size: 0.86rem; margin-top: 0.55rem; max-width: 66ch; }

/* One stat per row on a phone: two 190px columns plus the gutter do not fit 360px, and a
   half-legible number is worse than a scroll. */
.stat-grid { display: grid; gap: 0.85rem; grid-template-columns: 1fr; margin-bottom: 1.35rem; }
@media (min-width: 560px) { .stat-grid { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); } }
.stat { background: var(--surface); border-radius: var(--r-lg); box-shadow: inset 0 0 0 1px var(--hairline); padding: 1rem 1.1rem; }
.stat .label { font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-faint); }
.stat .value { font-size: 1.55rem; font-weight: 680; letter-spacing: -0.025em; margin-top: 0.3rem; color: var(--text); }
.stat .value.pos { color: var(--ok-fg); }
.stat .foot { font-size: 0.78rem; color: var(--text-muted); margin-top: 0.25rem; }

/* =========================================================== 7. pills === */

.pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px; border-radius: var(--r-pill);
  font-size: 11.5px; font-weight: 640; line-height: 1.5; white-space: nowrap;
}
.pill--ok   { background: var(--ok-bg);   color: var(--ok-fg);   box-shadow: inset 0 0 0 1px var(--ok-ring); }
.pill--warn { background: var(--warn-bg); color: var(--warn-fg); box-shadow: inset 0 0 0 1px var(--warn-ring); }
.pill--bad  { background: var(--bad-bg);  color: var(--bad-fg);  box-shadow: inset 0 0 0 1px var(--bad-ring); }
.pill--info { background: var(--info-bg); color: var(--info-fg); box-shadow: inset 0 0 0 1px var(--info-ring); }
.pill--mute { background: var(--sunken);  color: var(--text-muted); box-shadow: inset 0 0 0 1px var(--hairline); }

.dot { width: 7px; height: 7px; border-radius: var(--r-pill); background: currentColor; position: relative; flex: none; }
.dot--live::after {
  content: ''; position: absolute; inset: -3px; border-radius: inherit; background: currentColor;
  opacity: 0.25; animation: breathe 2.4s var(--ease-soft) infinite;
}
@keyframes breathe { 0%,100% { transform: scale(0.7); opacity: 0.3; } 50% { transform: scale(1.2); opacity: 0.05; } }

/* ========================================================= 8. controls == */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.45rem;
  min-height: 40px; padding: 0.5rem 1.05rem;
  border: 0; border-radius: var(--r-md);
  font: inherit; font-size: 0.86rem; font-weight: 620;
  cursor: pointer; text-decoration: none;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease), transform var(--dur-fast) var(--ease);
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn svg { width: 16px; height: 16px; }
.btn[disabled], .btn[aria-disabled='true'] { opacity: 0.55; pointer-events: none; }

.btn--primary { background: var(--accent); color: var(--on-accent); }
.btn--primary:hover { background: var(--accent-600); }
.btn--ghost { background: transparent; color: var(--text-soft); box-shadow: inset 0 0 0 1px var(--hairline); }
.btn--ghost:hover { background: var(--sunken); color: var(--text); }
.btn--quiet { background: transparent; color: var(--accent); }
.btn--quiet:hover { background: var(--accent-50); }
.btn--danger { background: var(--bad-fg); color: #fff; }
.btn--danger:hover { filter: brightness(1.08); }
.btn--sm { min-height: 32px; padding: 0.3rem 0.7rem; font-size: 0.79rem; border-radius: var(--r-sm); }
.btn--block { width: 100%; }

.field { margin-bottom: 1rem; }
.field > label { display: block; font-size: 0.82rem; font-weight: 620; color: var(--text-soft); margin-bottom: 0.35rem; }
.input, .field input, .field textarea, .field select {
  width: 100%; min-height: 42px;
  padding: 0.55rem 0.75rem;
  font: inherit; font-size: 0.88rem;
  color: var(--text); background: var(--surface);
  border: 0; border-radius: var(--r-md);
  box-shadow: inset 0 0 0 1px var(--hairline);
  transition: box-shadow var(--dur) var(--ease);
}
.field textarea { min-height: 96px; resize: vertical; }
.input:hover, .field input:hover, .field textarea:hover { box-shadow: inset 0 0 0 1px var(--ink-300); }
.input:focus, .field input:focus, .field textarea:focus, .field select:focus {
  outline: none;
  box-shadow: inset 0 0 0 1.5px var(--accent), 0 0 0 3px color-mix(in oklab, var(--accent) 16%, transparent);
}
.field .hint { font-size: 0.76rem; color: var(--text-muted); margin-top: 0.3rem; }
.field .err { font-size: 0.78rem; color: var(--bad-fg); margin-top: 0.3rem; }
.field[data-invalid='true'] input { box-shadow: inset 0 0 0 1.5px var(--bad-fg); }

/* ========================================================== 9. tables === */

.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table.data { width: 100%; border-collapse: collapse; font-size: 0.86rem; }
table.data th {
  text-align: left; padding: 0.6rem 1rem;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-faint); background: var(--surface-alt);
  box-shadow: inset 0 -1px 0 var(--hairline);
  white-space: nowrap; position: sticky; top: 0; z-index: 1;
}
table.data td { padding: 0.7rem 1rem; color: var(--text-soft); box-shadow: inset 0 -1px 0 var(--hairline-soft); }
table.data tr:last-child td { box-shadow: none; }
table.data tbody tr { transition: background var(--dur-fast) var(--ease); }
table.data tbody tr:hover { background: var(--surface-alt); }
table.data td .strong { color: var(--text); font-weight: 620; }

/*
 * Below 640px a wide table stops being a table: each row becomes a stacked card with the
 * column name in front of every value, so nothing depends on horizontal scrolling.
 */
@media (max-width: 639px) {
  /* The table element must stop being a table too: display:table sizes itself from its
     columns min-content even when the rows are overridden, which is what pushed the values
     off the right edge of a phone. */
  table.data.stackable,
  table.data.stackable tbody { display: block; width: 100%; }
  table.data.stackable thead { display: none; }
  table.data.stackable tr {
    display: block; padding: 0.75rem 0.9rem;
    box-shadow: inset 0 0 0 1px var(--hairline); border-radius: var(--r-md); margin-bottom: 0.6rem;
  }
  table.data.stackable td { display: flex; gap: 1rem; justify-content: space-between; align-items: center;
    padding: 0.3rem 0; box-shadow: none; text-align: right; }
  table.data.stackable td::before {
    content: attr(data-label);
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase;
    color: var(--text-faint); text-align: left; flex: none;
  }
}

.empty { text-align: center; padding: 2.75rem 1.25rem; color: var(--text-muted); }
.empty svg { width: 34px; height: 34px; margin: 0 auto 0.75rem; color: var(--text-faint); }
.empty h3 { font-size: 0.95rem; margin-bottom: 0.3rem; }
.empty p { font-size: 0.85rem; max-width: 44ch; margin: 0 auto; }

.pager { display: flex; flex-wrap: wrap; gap: 0.4rem; justify-content: center; padding: 1rem; }
.pager a, .pager span {
  min-width: 38px; min-height: 38px; padding: 0 0.7rem;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--r-sm); font-size: 0.83rem; font-weight: 600;
  color: var(--text-soft); box-shadow: inset 0 0 0 1px var(--hairline);
}
.pager a:hover { background: var(--sunken); text-decoration: none; }
.pager .current { background: var(--accent); color: var(--on-accent); box-shadow: none; }

/* ======================================================== 10. notices === */

.notice { display: flex; gap: 0.7rem; padding: 0.85rem 1rem; border-radius: var(--r-md); font-size: 0.86rem; margin-bottom: 1rem; }
.notice svg { width: 18px; height: 18px; flex: none; margin-top: 1px; }
.notice--info { background: var(--info-bg); color: var(--info-fg); box-shadow: inset 0 0 0 1px var(--info-ring); }
.notice--ok   { background: var(--ok-bg);   color: var(--ok-fg);   box-shadow: inset 0 0 0 1px var(--ok-ring); }
.notice--warn { background: var(--warn-bg); color: var(--warn-fg); box-shadow: inset 0 0 0 1px var(--warn-ring); }
.notice--bad  { background: var(--bad-bg);  color: var(--bad-fg);  box-shadow: inset 0 0 0 1px var(--bad-ring); }

.key { display: flex; align-items: center; gap: 0.5rem; }
.key code {
  flex: 1; min-width: 0; padding: 0.5rem 0.7rem; border-radius: var(--r-sm);
  background: var(--sunken); color: var(--text-soft);
  word-break: break-all; box-shadow: inset 0 0 0 1px var(--hairline);
}

/* ========================================================== 11. auth ==== */

.auth {
  min-height: 100vh; padding: 2rem var(--gutter);
  display: grid; align-content: center;
  /* A single fixed track sits at the start of the grid; justify-content is what centres
     the track itself, place-items only centres content inside it. */
  grid-template-columns: minmax(0, 560px);
  justify-content: center;
  justify-items: stretch;
}

.auth__card {
  width: 100%; min-width: 0;
  background: var(--surface);
  border-radius: var(--r-xl);
  box-shadow: inset 0 0 0 1px var(--hairline);
  padding: 1.5rem 1.25rem 1.75rem;
}
@media (min-width: 560px) { .auth__card { padding: 2.5rem 3rem 2.75rem; } }

/* The mark sits alone above the heading, so it carries the brand on its own. */
.auth__mark {
  width: 60px; height: 60px; margin: 0 auto 1.75rem;
  border-radius: 18px; display: grid; place-items: center;
  background: linear-gradient(150deg, var(--accent), color-mix(in oklab, var(--accent) 58%, #2ec5b6));
  color: var(--on-accent);
  animation: mark-in var(--dur-slow) var(--ease) both;
}
.auth__mark svg { width: 30px; height: 30px; }
/* Same reasoning as the nav mark: the logo brings its own rounded gradient, so the tile
   behind it would be a second radius around the first. */
.auth__mark:has(img) { background: none; border-radius: 0; }
.auth__mark img { width: 60px; height: 60px; border-radius: 16px; display: block; }
@keyframes mark-in { from { opacity: 0; transform: scale(0.86) translateY(-4px); } to { opacity: 1; transform: none; } }

.auth__title {
  font-size: clamp(1.9rem, 1.4rem + 2.4vw, 2.6rem);
  font-weight: 760; letter-spacing: -0.033em; line-height: 1.05;
  animation: rise var(--dur-slow) var(--ease) both; animation-delay: 60ms;
}

/* The seam draws itself in — the one flourish on the page, and it reads as a
   signature rather than decoration. */
.auth__seam {
  height: 5px; width: 68px; margin: 1rem 0 1.15rem;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--accent), color-mix(in oklab, var(--accent) 30%, transparent));
  transform-origin: left center;
  animation: seam-draw 520ms var(--ease) both; animation-delay: 140ms;
}
@keyframes seam-draw { from { transform: scaleX(0); opacity: 0; } to { transform: none; opacity: 1; } }

.auth__sub {
  color: var(--text-muted); font-size: 1rem; margin-bottom: 2rem;
  animation: rise var(--dur-slow) var(--ease) both; animation-delay: 180ms;
}

/* Each field enters just behind the one above it. */
.auth__field { margin-bottom: 1.35rem; animation: rise var(--dur-slow) var(--ease) both;
  animation-delay: calc(220ms + var(--i, 0) * 70ms); }
.auth__field > label { display: block; font-size: 0.95rem; font-weight: 600; color: var(--text); margin-bottom: 0.6rem; }

/* Icon chip beside the control, matching the reference layout. */
.field-row { display: flex; gap: 0.75rem; align-items: stretch; }
.field-chip {
  width: 54px; flex: none; border-radius: var(--r-md);
  display: grid; place-items: center;
  background: var(--accent-50); color: var(--accent);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.field-chip svg { width: 22px; height: 22px; }
.field-ctl { position: relative; flex: 1; min-width: 0; }
.field-ctl input {
  width: 100%; height: 100%; min-height: 54px;
  padding: 0.75rem 1rem; font-size: 1rem;
  color: var(--text); background: var(--surface);
  border: 0; border-radius: var(--r-md);
  box-shadow: inset 0 0 0 1px var(--hairline);
  transition: box-shadow var(--dur) var(--ease);
}
.field-ctl input::placeholder { color: var(--text-faint); }
.field-ctl input:hover { box-shadow: inset 0 0 0 1px var(--ink-300); }
.field-ctl input:focus {
  outline: none;
  box-shadow: inset 0 0 0 1.5px var(--accent), 0 0 0 4px color-mix(in oklab, var(--accent) 14%, transparent);
}
/* The chip lights up with its field, so focus is legible at a glance. */
.auth__field:focus-within .field-chip { background: var(--accent); color: var(--on-accent); }
.field-ctl input[type='password'], .field-ctl input[data-pw] { padding-right: 3rem; }

.pw-toggle {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  width: 38px; height: 38px; border: 0; border-radius: var(--r-sm);
  background: transparent; color: var(--text-faint); cursor: pointer;
  display: grid; place-items: center;
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.pw-toggle:hover { color: var(--text); background: var(--sunken); }
.pw-toggle svg { width: 19px; height: 19px; }

.auth__slot { margin: 0 0 1.5rem; display: flex; justify-content: center;
  animation: rise var(--dur-slow) var(--ease) both; animation-delay: 420ms; }

.auth__actions {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  animation: rise var(--dur-slow) var(--ease) both; animation-delay: 470ms;
}
.auth__actions .btn { min-height: 48px; padding: 0.7rem 1.9rem; font-size: 0.95rem; border-radius: var(--r-md); }
.auth__actions a.alt { font-weight: 620; font-size: 0.95rem; }

.auth__copy { text-align: center; color: var(--text-faint); font-size: 0.88rem; margin-top: 1.5rem;
  animation: fade var(--dur-slow) var(--ease) both; animation-delay: 560ms; }
.auth__foot { text-align: center; color: var(--text-muted); font-size: 0.9rem; margin-top: 1.35rem; line-height: 1.7; }

@media (prefers-reduced-motion: reduce) {
  .auth__mark, .auth__title, .auth__seam, .auth__sub,
  .auth__field, .auth__slot, .auth__actions, .auth__copy { animation: none !important; opacity: 1; transform: none; }
}

/* ======================================================== 12. motion ==== */

/*
 * One orchestrated entrance per page. Children inherit a stagger from --i, so the page
 * settles as a single gesture instead of a scatter of independent animations.
 */
@keyframes rise { from { opacity: 0; transform: translate3d(0, 9px, 0); } to { opacity: 1; transform: none; } }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

.rise { animation: rise var(--dur-slow) var(--ease) both; animation-delay: calc(var(--i, 0) * 45ms); }
.fade { animation: fade var(--dur) var(--ease) both; animation-delay: calc(var(--i, 0) * 40ms); }

/* Movement is removed, not merely shortened: motion sensitivity is a real accessibility
   failure and a 1ms slide is still a slide. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important; animation-iteration-count: 1 !important;
    transition-duration: 1ms !important; scroll-behavior: auto !important;
  }
  .rise, .fade { animation: none !important; opacity: 1; transform: none; }
  .dot--live::after { animation: none !important; opacity: 0.2; }
  .card--link:hover, .btn:active { transform: none; }
  .nav__link[aria-current='page']::before { animation: none; }
}

@media (prefers-contrast: more) {
  :root { --hairline: var(--ink-500); --text-muted: var(--ink-700); }
  .card, .section, .stat { box-shadow: inset 0 0 0 1.5px var(--hairline); }
}

/* ===================================================== 13. scrollbars === */

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: color-mix(in oklab, var(--ink-400) 46%, transparent);
  border-radius: var(--r-pill); border: 3px solid transparent; background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: color-mix(in oklab, var(--ink-500) 62%, transparent); background-clip: content-box; }
* { scrollbar-width: thin; }
::selection { background: var(--accent-100); color: var(--accent-700); }

/* ========================================================= 14. helpers == */

.row { display: flex; align-items: center; gap: 0.6rem; }
/* The legacy admin markup also calls a table row "row". Turning a <tr> into a flex container
   blockifies its cells, so the body rows leave the column grid the header still sits in and the
   table renders as two misaligned halves. The utility must never win against a real table row. */
tr.row { display: table-row; align-items: initial; gap: 0; }
.row--wrap { flex-wrap: wrap; }
.row--end { justify-content: flex-end; }
.grid-2 { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 760px) { .grid-2 { grid-template-columns: 1fr 1fr; } }
.muted { color: var(--text-muted); }
.faint { color: var(--text-faint); }
.strong { font-weight: 640; color: var(--text); }
.mt0 { margin-top: 0; } .mb0 { margin-bottom: 0; }
.mt1 { margin-top: 0.75rem; } .mb1 { margin-bottom: 0.75rem; }
.mt2 { margin-top: 1.25rem; } .mb2 { margin-bottom: 1.25rem; }
.nowrap { white-space: nowrap; }

@media print {
  .nav, .topbar, .scrim, .skip { display: none !important; }
  body { background: #fff; }
  .card, .section, .stat { box-shadow: none; border: 1px solid #ddd; }
}

/* ─────────────────────────────────────────────────────────────────────────────
   Merchant portal component names.

   The portal's ~42 SSR routes were written against a class vocabulary that this
   stylesheet never defined (.page-title, .btn-primary, .stat-card, .badge…), so their
   content rendered unstyled inside the shared shell while the login and register pages
   — which use the shell primitives directly — looked finished.

   These are not a second design language: each rule is the SAME token-driven declaration
   as its shell counterpart, given the name the markup already uses. Converting 42 routes
   by hand would risk the pages while changing nothing a user can see.
   ───────────────────────────────────────────────────────────────────────────── */
body:not(.wu-legacy) .page-title {
  font-size: clamp(1.35rem, 1.1rem + 1.1vw, 1.75rem);
  font-weight: 660; letter-spacing: -0.02em; color: var(--text);
  margin: 0.6rem 0 0;
}
body:not(.wu-legacy) .page-sub { color: var(--text-muted); font-size: 0.9rem; margin: 0.45rem 0 1.5rem; max-width: 62ch; }
body:not(.wu-legacy) .btn-primary { background: var(--accent); color: var(--on-accent); }
body:not(.wu-legacy) .btn-primary:hover { background: var(--accent-600); }
body:not(.wu-legacy) .btn-outline { background: transparent; color: var(--text-soft); box-shadow: inset 0 0 0 1px var(--hairline); }
body:not(.wu-legacy) .btn-outline:hover { background: var(--sunken); color: var(--text); }
/* --bad-fg is tuned to be readable AS TEXT on --bad-bg; used as a solid fill it reads muddy.
   A dedicated fill keeps destructive buttons unmistakably red without the brown cast. */
body:not(.wu-legacy) .btn-danger { background: #c0392b; color: #fff; }
body:not(.wu-legacy) .btn-success { background: var(--ok-fg); color: #fff; }
body:not(.wu-legacy) .btn-warning { background: var(--warn-fg); color: #fff; }
body:not(.wu-legacy) .btn-danger:hover,
body:not(.wu-legacy) .btn-success:hover,
body:not(.wu-legacy) .btn-warning:hover { filter: brightness(1.08); }
body:not(.wu-legacy) .btn-sm { min-height: 32px; padding: 0.3rem 0.7rem; font-size: 0.79rem; border-radius: var(--r-sm); }/* Markup that carries only .btn-* without the .btn base still needs the base shape. */
body:not(.wu-legacy) .btn-primary,
body:not(.wu-legacy) .btn-outline,
body:not(.wu-legacy) .btn-danger,
body:not(.wu-legacy) .btn-success,
body:not(.wu-legacy) .btn-warning,
body:not(.wu-legacy) .copy-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.45rem;
  min-height: 40px; padding: 0.5rem 0.95rem;
  font: inherit; font-size: 0.87rem; font-weight: 620; line-height: 1;
  border: 0; border-radius: var(--r-md); cursor: pointer; text-decoration: none;
  transition: background var(--dur-fast) var(--ease), filter var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
body:not(.wu-legacy) .btn-primary:active,
body:not(.wu-legacy) .btn-outline:active,
body:not(.wu-legacy) .btn-danger:active,
body:not(.wu-legacy) .btn-success:active,
body:not(.wu-legacy) .btn-warning:active,
body:not(.wu-legacy) .copy-btn:active { transform: translateY(1px); }
body:not(.wu-legacy) .stat-card { background: var(--surface); border-radius: var(--r-lg); box-shadow: inset 0 0 0 1px var(--hairline); padding: 1rem 1.1rem; min-width: 0; }
body:not(.wu-legacy) .stat-card .label { font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-faint); }
body:not(.wu-legacy) .stat-card .value { font-size: 1.55rem; font-weight: 680; letter-spacing: -0.025em; margin-top: 0.3rem; color: var(--text); }
body:not(.wu-legacy) .stat-card .sub { font-size: 0.78rem; color: var(--text-muted); margin-top: 0.25rem; }
body:not(.wu-legacy) .badge {
  display: inline-flex; align-items: center; gap: 0.3rem;
  padding: 0.2rem 0.6rem; border-radius: var(--r-pill);
  font-size: 0.72rem; font-weight: 640; line-height: 1.5; white-space: nowrap;
  background: var(--sunken); color: var(--text-muted); box-shadow: inset 0 0 0 1px var(--hairline);
}
body:not(.wu-legacy) .badge-green,
body:not(.wu-legacy) .badge-completed,
body:not(.wu-legacy) .badge-succeeded,
body:not(.wu-legacy) .badge-paid,
body:not(.wu-legacy) .badge-active,
body:not(.wu-legacy) .badge-live {
  background: var(--ok-bg); color: var(--ok-fg); box-shadow: inset 0 0 0 1px var(--ok-ring);
}
body:not(.wu-legacy) .badge-yellow,
body:not(.wu-legacy) .badge-pending,
body:not(.wu-legacy) .badge-processing,
body:not(.wu-legacy) .badge-awaiting_confirm,
body:not(.wu-legacy) .badge-trialing {
  background: var(--warn-bg); color: var(--warn-fg); box-shadow: inset 0 0 0 1px var(--warn-ring);
}
body:not(.wu-legacy) .badge-red,
body:not(.wu-legacy) .badge-failed,
body:not(.wu-legacy) .badge-cancelled,
body:not(.wu-legacy) .badge-canceled,
body:not(.wu-legacy) .badge-expired,
body:not(.wu-legacy) .badge-refunded {
  background: var(--bad-bg); color: var(--bad-fg); box-shadow: inset 0 0 0 1px var(--bad-ring);
}
body:not(.wu-legacy) .badge-blue,
body:not(.wu-legacy) .badge-draft,
body:not(.wu-legacy) .badge-sent,
body:not(.wu-legacy) .badge-info {
  background: var(--info-bg); color: var(--info-fg); box-shadow: inset 0 0 0 1px var(--info-ring);
}
body:not(.wu-legacy) .green { color: var(--ok-fg); }
body:not(.wu-legacy) .form-group { margin-bottom: 1rem; }
body:not(.wu-legacy) .form-group > label { display: block; font-size: 0.82rem; font-weight: 620; color: var(--text-soft); margin-bottom: 0.35rem; }
body:not(.wu-legacy) .form-group .hint { font-size: 0.76rem; color: var(--text-muted); margin-top: 0.3rem; }
body:not(.wu-legacy) .form-row { display: grid; gap: 0.75rem; grid-template-columns: 1fr; }
body:not(.wu-legacy) .form-row-3 { display: grid; gap: 0.75rem; grid-template-columns: 1fr; }
body:not(.wu-legacy) .filter-bar,
body:not(.wu-legacy) .search-bar,
body:not(.wu-legacy) .inline-form {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; margin-bottom: 1rem;
}
body:not(.wu-legacy) .inline-form { margin-bottom: 0; }
body:not(.wu-legacy) .table-card {
  background: var(--surface); border-radius: var(--r-lg);
  box-shadow: inset 0 0 0 1px var(--hairline);
  overflow-x: auto; -webkit-overflow-scrolling: touch; margin-bottom: 1.15rem; min-width: 0;
}
body:not(.wu-legacy) .actions-cell { display: flex; gap: 0.4rem; justify-content: flex-end; flex-wrap: wrap; }
body:not(.wu-legacy) .pagination { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin-top: 1rem; }
body:not(.wu-legacy) .pagination a,
body:not(.wu-legacy) .pagination span {
  min-width: 34px; min-height: 34px; padding: 0 0.55rem;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--r-sm); font-size: 0.84rem; text-decoration: none;
  color: var(--text-soft); box-shadow: inset 0 0 0 1px var(--hairline);
}
body:not(.wu-legacy) .pagination a:hover { background: var(--sunken); color: var(--text); }
body:not(.wu-legacy) .pagination .current { background: var(--accent); color: var(--on-accent); box-shadow: none; }
body:not(.wu-legacy) .key-display {
  font-family: var(--mono); font-size: 0.82rem; word-break: break-all;
  background: var(--surface-alt); color: var(--text-soft);
  padding: 0.7rem 0.85rem; border-radius: var(--r-md);
  box-shadow: inset 0 0 0 1px var(--hairline);
}
body:not(.wu-legacy) .copy-btn { background: transparent; color: var(--accent); min-height: 32px; padding: 0.3rem 0.7rem; font-size: 0.79rem; }
body:not(.wu-legacy) .copy-btn:hover { background: var(--accent-50); }
body:not(.wu-legacy) .line-items-wrapper { display: grid; gap: 0.6rem; }
body:not(.wu-legacy) .line-item { display: grid; gap: 0.6rem; grid-template-columns: 1fr; align-items: end; padding: 0.75rem; background: var(--surface-alt); border-radius: var(--r-md); box-shadow: inset 0 0 0 1px var(--hairline); }
body:not(.wu-legacy) main .header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.75rem; margin-bottom: 0.9rem; }
body:not(.wu-legacy) .alert { display: flex; gap: 0.7rem; padding: 0.85rem 1rem; border-radius: var(--r-md); font-size: 0.86rem; margin-bottom: 1rem; }
body:not(.wu-legacy) .alert-success { background: var(--ok-bg);  color: var(--ok-fg);  box-shadow: inset 0 0 0 1px var(--ok-ring); }
body:not(.wu-legacy) .alert-error,
body:not(.wu-legacy) .alert-danger { background: var(--bad-bg); color: var(--bad-fg); box-shadow: inset 0 0 0 1px var(--bad-ring); }
body:not(.wu-legacy) .alert-warning { background: var(--warn-bg); color: var(--warn-fg); box-shadow: inset 0 0 0 1px var(--warn-ring); }
body:not(.wu-legacy) .alert-info { background: var(--info-bg); color: var(--info-fg); box-shadow: inset 0 0 0 1px var(--info-ring); }/* Portal tables were plain <table> with no wrapper styling of their own. */
body:not(.wu-legacy) main table { width: 100%; border-collapse: collapse; }
body:not(.wu-legacy) main thead th {
  text-align: left; padding: 0.65rem 0.9rem; white-space: nowrap;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-faint); background: var(--surface-alt);
  box-shadow: inset 0 -1px 0 var(--hairline);
}
body:not(.wu-legacy) main tbody td { padding: 0.7rem 0.9rem; color: var(--text-soft); font-size: 0.87rem; box-shadow: inset 0 -1px 0 var(--hairline-soft); }
body:not(.wu-legacy) main tbody tr:last-child td { box-shadow: none; }
body:not(.wu-legacy) main tbody tr:hover { background: var(--surface-alt); }

@media (min-width: 640px) {
  body:not(.wu-legacy) .form-row { grid-template-columns: 1fr 1fr; }

  body:not(.wu-legacy) .line-item { grid-template-columns: 2fr 1fr auto; }
}
@media (min-width: 900px) {
  body:not(.wu-legacy) .form-row-3 { grid-template-columns: 1fr 1fr 1fr; }
}

/* ─────────────────────────────────────────────────────────────────────────────
   Merchant portal: bare sections and unclassed form controls.

   These 32 sections are `<div class="section">` with the heading and content as direct
   children. `.section` carries the surface and the ring but no padding — that lives on
   .section__head/.section__body, which this markup never used — so every heading sat flush
   against the card's top-left corner, reading as if printed on the border.

   And 54 inputs, selects and textareas across the two route files carry no class at all, so
   they rendered as raw browser controls beside design-system buttons. Styling the elements
   themselves is the only fix that reaches all of them without editing 54 call sites.

   Scoped away from the legacy admin, which brings its own control layer in wu-compat.css.
   ───────────────────────────────────────────────────────────────────────────── */

body:not(.wu-legacy) .section:not(:has(.section__body)) {
  padding: 1.15rem 1.25rem 1.25rem;
}
body:not(.wu-legacy) .section:not(:has(.section__body)) > h2,
body:not(.wu-legacy) .section:not(:has(.section__body)) > h3 {
  font-size: 1rem; font-weight: 640; letter-spacing: -0.01em;
  color: var(--text); margin: 0 0 0.9rem;
}

body:not(.wu-legacy) main input:not([type='checkbox']):not([type='radio']):not([type='hidden']):not([type='submit']):not([type='button']),
body:not(.wu-legacy) main select,
body:not(.wu-legacy) main textarea {
  width: 100%; max-width: 100%; min-height: 40px;
  padding: 0.5rem 0.7rem;
  font: inherit; font-size: 0.9rem; color: var(--text);
  background: var(--surface);
  border: 0; border-radius: var(--r-md);
  box-shadow: inset 0 0 0 1px var(--hairline);
  transition: box-shadow var(--dur-fast) var(--ease);
}
body:not(.wu-legacy) main textarea { min-height: 88px; resize: vertical; }
body:not(.wu-legacy) main input::placeholder,
body:not(.wu-legacy) main textarea::placeholder { color: var(--text-faint); }
body:not(.wu-legacy) main input:hover:not(:focus),
body:not(.wu-legacy) main select:hover:not(:focus),
body:not(.wu-legacy) main textarea:hover:not(:focus) { box-shadow: inset 0 0 0 1px var(--ink-300); }
body:not(.wu-legacy) main input:focus,
body:not(.wu-legacy) main select:focus,
body:not(.wu-legacy) main textarea:focus {
  outline: none;
  box-shadow: inset 0 0 0 1.5px var(--accent), 0 0 0 3px color-mix(in oklab, var(--accent) 16%, transparent);
}
body:not(.wu-legacy) main input[readonly],
body:not(.wu-legacy) main input:disabled { background: var(--surface-alt); color: var(--text-muted); }

/* Native selects lose their arrow once appearance is reset; draw one back. */
body:not(.wu-legacy) main select {
  appearance: none; -webkit-appearance: none;
  padding-right: 2rem;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237a746b' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 0.6rem center; background-size: 15px;
}

/* Controls sitting side by side in a filter row should not each stretch to full width. */
body:not(.wu-legacy) .filter-bar input,
body:not(.wu-legacy) .filter-bar select,
body:not(.wu-legacy) .search-bar input,
body:not(.wu-legacy) .inline-form input,
body:not(.wu-legacy) .inline-form select { width: auto; min-width: 12rem; }

body:not(.wu-legacy) .btn-danger-quiet {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 40px; padding: 0.5rem 0.95rem;
  font: inherit; font-size: 0.87rem; font-weight: 620; line-height: 1;
  background: transparent; color: #c0392b;
  border: 0; border-radius: var(--r-md); cursor: pointer;
  box-shadow: inset 0 0 0 1px color-mix(in oklab, #c0392b 30%, transparent);
  transition: background var(--dur-fast) var(--ease);
}
body:not(.wu-legacy) .btn-danger-quiet:hover { background: color-mix(in oklab, #c0392b 8%, transparent); }

/* ─────────────────────────────────────────────────────────────────────────────
   Card headers outside .section.

   The dashboard's transaction card is a .table-card, not a .section, so the padding added for
   sections never reached it and its heading sat on the card's top-left corner with the button
   on the top-right — the same defect, in a container the earlier fix (and the check that
   verified it) both looked straight past.

   The table itself stays flush to the card edges; only the chrome around it is inset.
   ───────────────────────────────────────────────────────────────────────────── */

body:not(.wu-legacy) .table-card > .header,
body:not(.wu-legacy) .table-card > h2,
body:not(.wu-legacy) .table-card > h3 {
  padding: 1.05rem 1.25rem;
  margin: 0;
}
body:not(.wu-legacy) .table-card > .header {
  box-shadow: inset 0 -1px 0 var(--hairline-soft);
  margin-bottom: 0;
}
body:not(.wu-legacy) .table-card > .header h2,
body:not(.wu-legacy) .table-card > .header h3 {
  padding: 0; margin: 0;
  font-size: 1rem; font-weight: 640; letter-spacing: -0.01em; color: var(--text);
}

/* An empty state should sit in the middle of the card, not hard against its walls. */
body:not(.wu-legacy) .table-card > .empty,
body:not(.wu-legacy) .section > .empty { padding: 2.5rem 1.25rem; }

/* ─────────────────────────────────────────────────────────────────────────────
   Payment methods picker.

   A checkbox that has to read as a switch: the merchant is deciding what a shopper
   will be offered, so the on/off state must survive a glance. The native input stays
   in the DOM — it IS the control, and replacing it with a styled span would take the
   keyboard and the screen reader with it.
   ───────────────────────────────────────────────────────────────────────────── */
body:not(.wu-legacy) .section-head { margin-bottom: 0.95rem; }
body:not(.wu-legacy) .section-head h2 { font-size: 1rem; font-weight: 640; color: var(--text); }
body:not(.wu-legacy) .section-sub { font-size: 0.84rem; color: var(--text-muted); margin-top: 0.3rem; max-width: 68ch; }
body:not(.wu-legacy) .form-actions { display: flex; gap: 0.6rem; margin-top: 1.15rem; }

body:not(.wu-legacy) .method-grid { display: grid; gap: 0.7rem; grid-template-columns: 1fr; }
@media (min-width: 720px) { body:not(.wu-legacy) .method-grid { grid-template-columns: 1fr 1fr; } }
/* One method should fill the row rather than leave a hole where a second would go. */
body:not(.wu-legacy) .method-grid > :only-child { grid-column: 1 / -1; }

body:not(.wu-legacy) .method-card {
  display: flex; align-items: flex-start; gap: 0.8rem; min-width: 0;
  padding: 0.95rem 1.05rem; border-radius: var(--r-md);
  background: var(--surface); box-shadow: inset 0 0 0 1px var(--hairline);
  cursor: pointer;
  transition: box-shadow var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
body:not(.wu-legacy) .method-card:hover { box-shadow: inset 0 0 0 1px var(--accent-200); }
body:not(.wu-legacy) .method-card:has(input:checked) {
  background: var(--accent-50); box-shadow: inset 0 0 0 1.5px var(--accent);
}
/* Focus belongs on the card the merchant is reading, not the 17px box tucked inside it. */
body:not(.wu-legacy) .method-card:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
body:not(.wu-legacy) .method-card input {
  flex: none; margin: 0.15rem 0 0; width: 17px; height: 17px; accent-color: var(--accent);
}
body:not(.wu-legacy) .method-body { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
body:not(.wu-legacy) .method-name { font-size: 0.92rem; font-weight: 620; color: var(--text); }
body:not(.wu-legacy) .method-meta { font-size: 0.78rem; color: var(--text-faint); }
body:not(.wu-legacy) .method-desc { font-size: 0.8rem; color: var(--text-muted); margin-top: 0.2rem; }

body:not(.wu-legacy) .method-card.is-locked {
  cursor: default; align-items: center; justify-content: space-between;
  background: var(--surface-alt); color: var(--text-muted);
}
body:not(.wu-legacy) .method-card.is-locked:hover { box-shadow: inset 0 0 0 1px var(--hairline); }
body:not(.wu-legacy) .method-card.is-locked .method-name { color: var(--text-soft); }
body:not(.wu-legacy) .badge-gray { background: var(--sunken); color: var(--text-muted); }

/* A table wider than its card has to scroll, not be sliced off. The portal's tables sit as a
   direct child of .section, which — unlike .table-card — had no scroll container of its own, so
   the last column (usually the one with the buttons) was simply cut away at the card's edge.
   Scoped to sections that actually hold a table: overflow on an element also makes it the
   containing block for any position:sticky inside it. */
body:not(.wu-legacy) .section:has(> table) {
  overflow-x: auto; -webkit-overflow-scrolling: touch;
}
/* Let a wide table reach its natural width instead of being crushed into the card.
   The Transactions table has eight columns in a 968px card: table-layout:auto hands the last
   ones almost nothing, the dates wrap a character at a time, and a 44px row renders 115px tall
   as mostly whitespace. Both containers already scroll horizontally — the table just has to be
   allowed to ask for the room. width:100% still fills the card when there is space. */
body:not(.wu-legacy) .section:has(> table) > table,
body:not(.wu-legacy) .table-card > table { min-width: max-content; }

/* Identifiers and timestamps are single tokens; breaking them mid-string helps no one. */
body:not(.wu-legacy) main tbody td { white-space: nowrap; }
body:not(.wu-legacy) main tbody td.wrap { white-space: normal; }
