/* Pakt — design-system foundation ("terminal-grade fintech", docs/DESIGN.md §1–4).

   Tokens, fonts, base, the 48px top bar, page grid helpers and every shared
   component. View-specific layout lives in css/<view>.css and must only use
   the tokens below. Hard rules: flat colour fills only, no coloured or glowing
   shadows, no blur, no decorative icons, 90 % neutrals — the accent marks
   interactive state only; green/red/amber mark meaning only. */

/* ==========================================================================
   1. Fonts — IBM Plex Sans 400/500/600 + Plex Mono 400/500 (OFL, bundled),
      split latin / latin-ext by unicode-range exactly like fontsource.
   ========================================================================== */

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/ibm-plex-sans-latin-ext-400-normal.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/ibm-plex-sans-latin-400-normal.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(fonts/ibm-plex-sans-latin-ext-500-normal.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(fonts/ibm-plex-sans-latin-500-normal.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(fonts/ibm-plex-sans-latin-ext-600-normal.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(fonts/ibm-plex-sans-latin-600-normal.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/ibm-plex-mono-latin-ext-400-normal.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/ibm-plex-mono-latin-400-normal.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(fonts/ibm-plex-mono-latin-ext-500-normal.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(fonts/ibm-plex-mono-latin-500-normal.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ==========================================================================
   2. Tokens
   ========================================================================== */

:root {
  --bg: #090A0C;          /* page */
  --surface: #111317;     /* panels */
  --elevated: #171A20;    /* raised: menus, modal, toasts, selected controls */
  --hover: #1C1F26;       /* row / control hover */
  --field: #0D0F12;       /* inputs */
  --border: rgba(255, 255, 255, 0.07);
  --border-2: rgba(255, 255, 255, 0.12);   /* inputs, secondary buttons */
  --divider: rgba(255, 255, 255, 0.05);

  --text-1: #E9E6DF;      /* warm off-white, primary */
  --text-2: #A29F97;      /* secondary */
  --text-3: #6B6964;      /* labels, meta */
  --text-4: #45443F;      /* disabled, dimmed zeros */

  --accent: #7AA7FF;      /* the ONE accent: focus, selection, active tab, links, toggles, progress */
  --accent-weak: rgba(122, 167, 255, 0.10);
  --accent-line: rgba(122, 167, 255, 0.45);

  --pos: #4CB782;  --pos-weak: rgba(76, 183, 130, 0.10);    /* completed, received, +values */
  --neg: #E5645C;  --neg-weak: rgba(229, 100, 92, 0.10);    /* failed, errors, −values */
  --warn: #D9A23D; --warn-weak: rgba(217, 162, 61, 0.10);   /* pending, near expiry, refunds, time warp */

  --btc: #9E7A4A;         /* chain markers ONLY — a muted bronze, never mistaken for --warn */
  --evm: #8A90B8;

  --primary-bg: #ECE8E1;  --primary-fg: #0B0C0E;   /* primary button = solid off-white */
  --primary-hover: #F7F4EE;
  --primary-active: #DAD6CF;

  --r-1: 3px;   /* badges, kbd */
  --r-2: 4px;   /* buttons, inputs */
  --r-3: 6px;   /* panels, modal */

  --font: "IBM Plex Sans", system-ui, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, monospace;

  --ease: cubic-bezier(.2, .0, .0, 1);
  --t-fast: 120ms;
  --t: 180ms;

  --bar-h: 48px;
  --gutter: 16px;
  --page-max: 1920px;
  --overlay-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);   /* overlays only (toasts, modal) */

  color-scheme: dark;
}

/* ==========================================================================
   3. Reset + base
   ========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scrollbar-gutter: stable;
  scroll-padding-top: calc(var(--bar-h) + 16px);
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--text-1);
  font-family: var(--font);
  font-size: 14px;
  font-weight: 400;
  line-height: 1.45;
  font-feature-settings: "tnum" 0;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6 { margin: 0; font-size: inherit; font-weight: 500; }
p, figure, blockquote, dl, dd { margin: 0; }
hr { height: 1px; margin: 0; border: 0; background: var(--divider); }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 2px; }
button, input, select, textarea { font: inherit; color: inherit; letter-spacing: inherit; }
button { cursor: pointer; }
button:disabled { cursor: not-allowed; }
table { border-collapse: collapse; border-spacing: 0; }
img, svg { max-width: 100%; }
code, kbd, samp, pre { font-family: var(--mono); }
code { font-size: 12px; color: var(--text-2); }
pre { margin: 0; font-size: 12px; white-space: pre-wrap; overflow-wrap: anywhere; }
[hidden] { display: none !important; }

kbd {
  display: inline-flex;
  align-items: center;
  height: 18px;
  padding: 0 5px;
  border: 1px solid var(--border-2);
  border-radius: var(--r-1);
  background: var(--field);
  font-size: 11px;
  line-height: 1;
  color: var(--text-3);
}

::selection { background: rgba(122, 167, 255, 0.28); color: var(--text-1); }

:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }
:focus:not(:focus-visible) { outline: none; }

* { scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, 0.12) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.1); border: 3px solid transparent; border-radius: 6px; background-clip: padding-box; }

/* Icons (icons.js): 16px line icons, currentColor. */
.ic { display: inline-block; width: 16px; height: 16px; flex: none; vertical-align: -3px; }
.ic.sm { width: 14px; height: 14px; vertical-align: -2px; }
.ic.xs { width: 12px; height: 12px; vertical-align: -1px; }

/* ==========================================================================
   4. Typography utilities
   ========================================================================== */

.num { font-variant-numeric: tabular-nums; }
.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; letter-spacing: 0; }

/* Hierarchy: uppercase is reserved for panel titles (.panel-t), table
   headers and badges. Inside a panel, a section starts with .sec-h (12/500,
   --text-2, sentence case, hairline above via .panel-sec / .sec-bar);
   field and value labels are .t-label (12/400, --text-3, sentence case). */
.t-label { font-size: 12px; font-weight: 400; line-height: 16px; color: var(--text-3); }
.sec-h {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 12px;
  font-weight: 500;
  line-height: 16px;
  color: var(--text-2);
}
/* A 36px section bar inside a flush panel body (e.g. a second table). */
.sec-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 36px;
  padding: 0 16px;
  border-top: 1px solid var(--divider);
  border-bottom: 1px solid var(--divider);
}
.t-meta { font-size: 12px; color: var(--text-3); }
.t-body { font-size: 14px; color: var(--text-1); }
.t-em { font-size: 16px; font-weight: 500; color: var(--text-1); }
.t-1 { color: var(--text-1); }
.t-2 { color: var(--text-2); }
.t-3 { color: var(--text-3); }
.t-4 { color: var(--text-4); }
.c-pos { color: var(--pos); }
.c-neg { color: var(--neg); }
.c-warn { color: var(--warn); }
.c-accent { color: var(--accent); }
.t-right { text-align: right; }
.nowrap { white-space: nowrap; }
.truncate { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; min-width: 0; }
.break { overflow-wrap: anywhere; word-break: break-all; }
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Layout utilities */
.row { display: flex; align-items: center; gap: 8px; min-width: 0; }
.row-wrap { flex-wrap: wrap; }
.row-between { justify-content: space-between; }
.stack { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.stack-4 { gap: 4px; }
.stack-12 { gap: 12px; }
.stack-16 { gap: 16px; }
.spacer { flex: 1 1 auto; }

/* ==========================================================================
   5. Top bar (48px) + nav
   ========================================================================== */

.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  height: var(--bar-h);
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}
.topbar-in {
  display: flex;
  align-items: stretch;
  gap: 24px;
  height: 100%;
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  color: var(--text-1);
  text-decoration: none;
}
.brand:hover { text-decoration: none; }
.brand-mark { display: flex; color: var(--text-1); }
.brand-name { font-size: 14px; font-weight: 600; letter-spacing: 0.01em; }

.nav { display: flex; align-items: stretch; gap: 4px; min-width: 0; }
.nav-tab {
  position: relative;
  display: flex;
  align-items: center;
  padding: 0 10px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-2);
  white-space: nowrap;
  text-decoration: none;
  transition: color var(--t-fast) var(--ease);
}
.nav-tab:hover { color: var(--text-1); text-decoration: none; }
.nav-tab.is-active { color: var(--text-1); }
.nav-tab.is-active::after {
  content: "";
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: -1px;          /* flush with the bar's bottom border */
  height: 2px;
  background: var(--accent);
}
.nav-tab:focus-visible { outline-offset: -6px; }

.topbar-status {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  margin-left: auto;
  font-size: 12px;
  color: var(--text-2);
  white-space: nowrap;
}
.topbar .lang { align-self: center; flex: none; }

.tb-item { display: inline-flex; align-items: center; gap: 6px; }
.tb-k { font-size: 11px; font-weight: 500; letter-spacing: 0.06em; color: var(--text-3); }
.tb-v {
  margin: 0 -3px;
  padding: 1px 3px;
  border-radius: 2px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--text-2);
  font-variant-numeric: tabular-nums;
}
.tb-sep { width: 1px; height: 16px; background: var(--border-2); flex: none; }
.tb-net { flex: none; }
.tb-dot { width: 6px; height: 6px; flex: none; border-radius: 50%; background: var(--text-4); }
.conn-live .tb-dot, .conn-mock .tb-dot { background: var(--pos); }
.conn-polling .tb-dot, .conn-connecting .tb-dot { background: var(--warn); }
.conn-offline { color: var(--neg); }
.conn-offline .tb-dot { background: var(--neg); }
.tb-warp { color: var(--text-3); text-decoration: none; }
.tb-warp .tb-v { color: inherit; }
.tb-warp.is-on { color: var(--warn); }
.tb-warp:hover { text-decoration: none; }
.tb-warp:hover .tb-v { text-decoration: underline; text-underline-offset: 2px; }

/* Offline banner: a slim neutral strip under the bar. */
.banner { background: var(--surface); border-bottom: 1px solid var(--border); }
.banner-in {
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: var(--page-max);
  min-height: 40px;
  margin: 0 auto;
  padding: 6px var(--gutter);
  font-size: 13px;
  color: var(--text-2);
}
.banner-dot { width: 6px; height: 6px; flex: none; border-radius: 50%; background: var(--neg); }
.banner-text { flex: 1 1 auto; min-width: 0; }

@media (max-width: 1100px) {
  .topbar-in { gap: 16px; }
  .tb-hgt .tb-k { display: none; }
}
@media (max-width: 900px) {
  .tb-hgt, .tb-sep, .tb-net { display: none; }
}

/* ==========================================================================
   6. Page + grid helpers
   ========================================================================== */

main {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: var(--gutter) var(--gutter) 48px;
}

/* A view's root: vertical stack of grids with 16px between them. */
.page { display: flex; flex-direction: column; gap: 16px; min-width: 0; }

/* Panels sharing hairlines: children sit on 1px gaps that show --border;
   only the outer frame is rounded. Fill every cell (use .span-*), or the
   gap colour shows through. */
.grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1px;
  min-width: 0;
  background: var(--border);
  background-clip: padding-box;
  border: 1px solid var(--border);
  border-radius: var(--r-3);
  overflow: hidden;
}
.grid > * { min-width: 0; background: var(--surface); }
.grid > .panel { border: 0; border-radius: 0; }
.cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cols-3 { grid-template-columns: minmax(260px, 300px) minmax(0, 1fr) minmax(340px, 380px); }
.cols-3-eq { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cols-main-side { grid-template-columns: minmax(0, 1fr) minmax(340px, 420px); }
.span-2 { grid-column: span 2; }
.span-all { grid-column: 1 / -1; }

/* Hairline columns inside one panel body (e.g. two party columns). */
.split { display: grid; gap: 1px; background: var(--divider); min-width: 0; }
.split > * { min-width: 0; background: var(--surface); }
.split-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.split-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

@media (max-width: 1180px) {
  .cols-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cols-3 > :first-child { grid-column: 1 / -1; }
  .cols-3-eq { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 860px) {
  .cols-2, .cols-3, .cols-3-eq, .cols-main-side, .split-2, .split-3 { grid-template-columns: minmax(0, 1fr); }
  .span-2 { grid-column: auto; }
}

/* ==========================================================================
   7. Panel
   ========================================================================== */

.panel {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-3);
}
.panel-h {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  min-width: 0;
  height: 40px;
  padding: 0 16px;
  border-bottom: 1px solid var(--divider);
}
.panel-t {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  margin: 0;
  overflow: hidden;
  font-size: 11px;
  font-weight: 500;
  line-height: 16px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--text-3);
}
.panel-t code, .panel-t .mono { font-size: 11px; letter-spacing: 0.02em; color: var(--text-2); }
.panel-count { font-family: var(--mono); letter-spacing: 0; color: var(--text-3); }
.panel-actions { display: flex; align-items: center; gap: 8px; flex: none; margin-left: auto; }
.panel-b { flex: 1 1 auto; min-width: 0; padding: 16px; }
.panel-b.flush { padding: 0; }
.panel-sec { padding: 16px; border-top: 1px solid var(--divider); }
.panel-sec:first-child { border-top: 0; }
.panel-f {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  padding: 12px 16px;
  border-top: 1px solid var(--divider);
}

/* ==========================================================================
   8. Buttons
   ========================================================================== */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  flex: none;
  height: 32px;
  padding: 0 12px;
  border: 1px solid var(--border-2);
  border-radius: var(--r-2);
  background: transparent;
  color: var(--text-1);
  font-size: 13px;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  user-select: none;
  transition: background-color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease), opacity var(--t-fast) var(--ease);
}
.btn:hover { text-decoration: none; }
.btn:not(:disabled):hover { background: var(--hover); }
.btn:not(:disabled):active { background: var(--elevated); }
.btn .ic { width: 16px; height: 16px; }

.btn-secondary { border-color: var(--border-2); background: transparent; color: var(--text-1); }

.btn-primary { border-color: var(--primary-bg); background: var(--primary-bg); color: var(--primary-fg); }
.btn-primary:not(:disabled):hover { border-color: var(--primary-hover); background: var(--primary-hover); }
.btn-primary:not(:disabled):active { border-color: var(--primary-active); background: var(--primary-active); }

.btn-ghost { border-color: transparent; color: var(--text-2); }
.btn-ghost:not(:disabled):hover { color: var(--text-1); }

.btn-danger { color: var(--neg); }
.btn-danger:not(:disabled):hover { border-color: var(--neg); background: var(--neg-weak); }

.btn-sm { height: 28px; padding: 0 10px; font-size: 12px; }
.btn-lg { height: 40px; padding: 0 16px; font-size: 14px; }
.btn-block { display: flex; width: 100%; }
.btn-icon { width: 32px; padding: 0; }
.btn-icon.btn-sm { width: 28px; }
.btn-icon.btn-lg { width: 40px; }

.btn:disabled:not(.is-loading), .btn[aria-disabled="true"] { opacity: 0.4; cursor: not-allowed; }

.btn.is-loading { color: transparent !important; pointer-events: none; }
.btn.is-loading > * { visibility: hidden; }
.btn.is-loading::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 12px;
  height: 12px;
  margin: -6px 0 0 -6px;
  border: 1.5px solid var(--text-4);
  border-top-color: var(--text-1);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
.btn-primary.is-loading::after { border-color: rgba(11, 12, 14, 0.25); border-top-color: var(--primary-fg); }

/* Text button in the accent colour (inline actions such as "MAX"). */
.link {
  display: inline;
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent);
  font: inherit;
  cursor: pointer;
}
.link:hover { text-decoration: underline; text-underline-offset: 2px; }

/* Quiet text button (secondary inline actions: "show closed", …). */
.btn-text {
  display: inline;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-3);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
  transition: color var(--t-fast) var(--ease);
}
.btn-text:hover { color: var(--text-1); }

/* 20px icon button (copyBtn()). */
.copy {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 20px;
  height: 20px;
  padding: 0;
  border: 0;
  border-radius: var(--r-1);
  background: transparent;
  color: var(--text-3);
  cursor: pointer;
  vertical-align: middle;
  transition: color var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease);
}
.copy:hover { color: var(--text-1); background: var(--hover); }
.copy.copied { color: var(--pos); }

/* ==========================================================================
   9. Forms: .field, .input / .select, .seg, .toggle
   ========================================================================== */

.form { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field > span:first-child, .field-label {
  font-size: 12px;
  font-weight: 400;
  line-height: 16px;
  color: var(--text-3);
}
.field-hint { font-size: 12px; color: var(--text-3); }
.field-error { font-size: 12px; color: var(--neg); }
.field-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.field-row-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }

.input, .select,
:where(input:not([type]), input[type="text"], input[type="number"], input[type="search"], input[type="email"], input[type="url"], input[type="password"], input[type="datetime-local"], select, textarea) {
  width: 100%;
  min-width: 0;
  height: 32px;
  padding: 0 10px;
  border: 1px solid var(--border-2);
  border-radius: var(--r-2);
  background-color: var(--field);
  color: var(--text-1);
  font-size: 13px;
  outline: none;
  transition: border-color var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease);
}
:where(.input, .select, input, select, textarea):hover:not(:disabled):not(:focus) { border-color: rgba(255, 255, 255, 0.18); }
:where(.input, .select, input, select, textarea):focus { border-color: var(--accent); }
:where(.input, .select, input, select, textarea):focus-visible { outline: none; }
:where(.input, input, textarea)::placeholder { color: var(--text-4); opacity: 1; }
:where(.input, .select, input, select, textarea):disabled { opacity: 0.5; cursor: not-allowed; }
textarea.input, :where(textarea) {
  height: auto;
  min-height: 72px;
  padding: 8px 10px;
  line-height: 1.45;
  resize: vertical;
}
.select, :where(select) {
  appearance: none;
  padding-right: 28px;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none' stroke='%23A29F97' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 6.25 8 9.75l3.5-3.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 8px center;
  background-size: 14px 14px;
}
select option { background: var(--elevated); color: var(--text-1); }
.input-mono { font-family: var(--mono); font-size: 12px; }
.input-sm { height: 28px; font-size: 12px; }
.input-lg { height: 40px; font-size: 14px; }
.is-invalid, [aria-invalid="true"] { border-color: var(--neg) !important; }
input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[type="checkbox"], input[type="radio"] { accent-color: var(--accent); }

/* Segmented control: <div class="seg"><button class="is-active">A</button><button>B</button></div>
   Selected = .is-active | [aria-pressed=true] | [aria-selected=true] | label with a checked radio. */
.seg {
  display: inline-flex;
  align-items: stretch;
  gap: 2px;
  flex: none;
  height: 32px;
  padding: 2px;
  border: 1px solid var(--border-2);
  border-radius: var(--r-2);
  background: var(--field);
}
.seg > button, .seg > a, .seg > label {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 0 10px;
  border: 0;
  border-radius: 3px;
  background: transparent;
  color: var(--text-2);
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  transition: color var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease);
}
.seg > :hover { color: var(--text-1); text-decoration: none; }
.seg > .is-active, .seg > .active, .seg > [aria-pressed="true"], .seg > [aria-selected="true"], .seg > label:has(input:checked) {
  background: var(--elevated);
  color: var(--text-1);
  box-shadow: inset 0 0 0 1px var(--border);
}
.seg > label input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.seg > label:has(input:focus-visible) { outline: 1px solid var(--accent); outline-offset: 1px; }
.seg > :disabled { opacity: 0.4; cursor: not-allowed; }
.seg-sm { height: 26px; padding: 2px; }
.seg-sm > button, .seg-sm > a, .seg-sm > label { padding: 0 8px; font-size: 11px; letter-spacing: 0.04em; }
.seg-block { display: flex; width: 100%; }
.seg-block > * { flex: 1 1 0; }

/* Toggle 28×16: <label class="toggle"><input type="checkbox"><span class="toggle-track"></span><span class="toggle-l">Auto</span></label>
   A setting, not a state: "on" is a quiet accent outline + accent knob on the field colour. */
.toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--text-2);
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
}
.toggle input { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; pointer-events: none; }
.toggle-track {
  position: relative;
  flex: none;
  width: 28px;
  height: 16px;
  border: 1px solid var(--border-2);
  border-radius: var(--r-1);
  background: var(--field);
  transition: border-color var(--t) var(--ease);
}
.toggle-track::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  background: var(--text-3);
  transition: transform var(--t) var(--ease), background-color var(--t) var(--ease);
}
.toggle input:checked + .toggle-track { border-color: var(--accent-line); }
.toggle input:checked + .toggle-track::after { transform: translateX(12px); background: var(--accent); }
.toggle input:focus-visible + .toggle-track { outline: 1px solid var(--accent); outline-offset: 2px; }
.toggle:hover .toggle-track { border-color: rgba(255, 255, 255, 0.2); }
.toggle:hover input:checked + .toggle-track { border-color: var(--accent); }
.toggle:has(input:disabled) { opacity: 0.4; cursor: not-allowed; }
.toggle-l { color: var(--text-2); }

/* ==========================================================================
   10. Swap ticket (Uniswap-simple)
   ========================================================================== */

.ticket { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.ticket-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: var(--r-2);
  background: var(--field);
  transition: border-color var(--t-fast) var(--ease);
}
.ticket-row:focus-within { border-color: var(--border-2); }
.ticket-row:has(.amount-input:focus-visible) { border-color: var(--accent-line); }   /* keyboard focus is always visible */
.ticket-row.is-invalid { border-color: var(--neg); }
.ticket-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 16px;
}
.ticket-label { font-size: 12px; font-weight: 400; line-height: 16px; color: var(--text-3); }
.ticket-bal { display: inline-flex; align-items: baseline; gap: 6px; font-size: 12px; color: var(--text-3); font-variant-numeric: tabular-nums; white-space: nowrap; }
.ticket-bal b { font-weight: 400; color: var(--text-2); }
.ticket-bal .amt { font-size: 12px; font-weight: 400; color: var(--text-2); }
.ticket-bal .amt-asset { font-size: 11px; }
/* The balance of the paying side fills the amount (MAX). */
.ticket-max { padding: 0; border: 0; background: none; font: inherit; cursor: pointer; }
.ticket-max:hover .amt, .ticket-max:hover .amt-pad { color: var(--accent); }
.ticket-main { display: flex; align-items: center; gap: 12px; min-width: 0; }
.amount-input {
  flex: 1 1 auto;
  width: 100%;
  min-width: 0;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--text-1);
  font-family: var(--font);
  font-size: 34px;
  font-weight: 500;
  line-height: 44px;
  letter-spacing: -0.015em;
  font-variant-numeric: tabular-nums;
  outline: none;
}
.amount-input::placeholder { color: var(--text-4); opacity: 1; }
.amount-input:focus, .amount-input:hover { border: 0; }
.amount-input:focus-visible { outline: none; }
.ticket-sub { min-height: 16px; font-size: 12px; color: var(--text-3); font-variant-numeric: tabular-nums; }

/* Between the two rows: zero-height line carrying the direction button. */
.ticket-divider { position: relative; z-index: 1; display: flex; justify-content: center; height: 0; }
.ticket-flip {
  position: absolute;
  top: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  transform: translateY(-50%);
  border: 1px solid var(--border-2);
  border-radius: var(--r-2);
  background: var(--surface);
  color: var(--text-2);
  cursor: pointer;
  transition: color var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease);
}
.ticket-flip:hover { color: var(--text-1); background: var(--hover); }

/* Token select: <label class="token-select"><span class="chain-mark cm-btc"></span><select>…</select></label>
   or <button class="token-select">mark + code + ic('chevron-down')</button>. */
/* One width for every asset (PLNT is the widest), so stacked selects line up. */
.token-select {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  flex: none;
  width: 96px;
  height: 32px;
  padding: 0 10px;
  border: 1px solid var(--border-2);
  border-radius: var(--r-2);
  background: var(--elevated);
  color: var(--text-1);
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.token-select:hover { background: var(--hover); }
.token-select:focus-within { border-color: var(--accent); }
.token-select .ic { width: 14px; height: 14px; color: var(--text-3); }
.token-select select {
  width: auto;
  min-width: 0;
  height: 30px;
  margin: 0;
  padding: 0 20px 0 0;
  border: 0;
  border-radius: 0;
  background-color: transparent;
  background-position: right 0 center;
  color: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
}
.token-select select:focus, .token-select select:hover { border: 0; }
.token-select.is-single select { pointer-events: none; background-image: none; padding-right: 0; }

.ticket-meta { padding: 8px 2px 4px; }
.ticket-meta .kv-row { min-height: 24px; padding: 2px 0; font-size: 12px; }

/* ==========================================================================
   11. Data display: chain mark, amount, badge, kv, addr, tx
   ========================================================================== */

.chain-mark { display: inline-block; flex: none; width: 6px; height: 6px; background: var(--evm); vertical-align: middle; }
.chain-mark.cm-btc { background: var(--btc); }
.chain-mark.cm-evm { background: var(--evm); }
.chain { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }

/* amount(): integer + significant decimals in --text-1, padding zeros --text-4, asset code small. */
.amt {
  font-family: var(--font);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.005em;
  line-height: 1.2;
  white-space: nowrap;
  color: var(--text-1);
}
.amt-pad { color: var(--text-4); }
/* More digits than drawn (the exact value is in the title): never cut
   silently. The marker hangs after the amount (and its asset code) in zero
   width, so a cut ETH balance keeps its digits in the column of an uncut
   BTC one; it overflows into the cell's padding. */
.amt-more { display: inline-block; width: 0; overflow: visible; font-weight: 400; color: var(--text-3); }
.amt-asset { margin-left: 0.25em; font-size: 11px; font-weight: 500; letter-spacing: 0.04em; color: var(--text-3); }
.amt-sign { margin-right: 0.04em; }
.amt-sm { font-size: 13px; }
.amt-md { font-size: 16px; }
.amt-lg { font-size: 20px; letter-spacing: -0.01em; }
.amt-xl { font-size: 28px; letter-spacing: -0.015em; line-height: 1.15; }
.amt-lg .amt-asset, .amt-xl .amt-asset { font-size: 12px; letter-spacing: 0.04em; }
.amt-pos { color: var(--pos); }
.amt-neg { color: var(--neg); }
.amt-pos .amt-pad, .amt-neg .amt-pad { color: inherit; opacity: 0.4; }

/* Badge: outlined, mono 11px uppercase, state colour at ~35 % for the border. */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex: none;
  height: 18px;
  padding: 0 6px;
  border: 1px solid;
  border-radius: var(--r-1);
  background: transparent;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  white-space: nowrap;
  vertical-align: middle;
}
.b-muted { color: var(--text-3); border-color: color-mix(in srgb, var(--text-3) 35%, transparent); }
.b-neutral { color: var(--text-2); border-color: color-mix(in srgb, var(--text-2) 35%, transparent); }
.b-accent { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 35%, transparent); }
.b-pos { color: var(--pos); border-color: color-mix(in srgb, var(--pos) 35%, transparent); }
.b-neg { color: var(--neg); border-color: color-mix(in srgb, var(--neg) 35%, transparent); }
.b-warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 35%, transparent); }

/* Key/value list: <dl class="kv"><div class="kv-row"><dt>Label</dt><dd>value</dd></div></dl> */
.kv { display: flex; flex-direction: column; min-width: 0; margin: 0; }
.kv-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  min-width: 0;
  min-height: 28px;
  padding: 4px 0;
  font-size: 13px;
}
.kv dt { flex: none; max-width: 50%; font-size: 12px; color: var(--text-3); }
.kv dd {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
  margin: 0;
  text-align: right;
  color: var(--text-1);
  font-variant-numeric: tabular-nums;
}
.kv dd.mono { font-family: var(--mono); font-size: 12px; color: var(--text-2); }
/* Technical values inside a value (timestamps, durations): the same 12px mono --text-2. */
.kv dd > .mono { font-size: 12px; color: var(--text-2); }
.kv-lines .kv-row + .kv-row { border-top: 1px solid var(--divider); }
.kv-stack .kv-row { flex-direction: column; align-items: stretch; gap: 2px; }
.kv-stack dt { max-width: none; }
.kv-stack dd { justify-content: flex-start; text-align: left; }
.kv-sm .kv-row { min-height: 24px; padding: 2px 0; font-size: 12px; }

/* Shortened address / hash with copy (addr()). */
.addr { display: inline-flex; align-items: center; gap: 4px; min-width: 0; max-width: 100%; vertical-align: middle; }
.addr-v { overflow: hidden; font-family: var(--mono); font-size: 12px; color: var(--text-2); white-space: nowrap; text-overflow: ellipsis; }
.addr.is-empty { color: var(--text-4); }

/* Tx id with explorer link + copy (txLink()). */
.tx { display: inline-flex; align-items: center; gap: 6px; min-width: 0; vertical-align: middle; }
.tx-label { font-size: 12px; color: var(--text-3); }
.tx-link { display: inline-flex; align-items: center; gap: 4px; color: var(--text-2); text-decoration: none; }
.tx-id { font-size: 12px; color: inherit; }
.tx-link .ic { color: var(--text-3); }
a.tx-link:hover { color: var(--accent); text-decoration: none; }
a.tx-link:hover .ic { color: var(--accent); }
.tx .copy { margin-left: -2px; }

/* Big readout (heights, offsets, totals). */
.stat { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.stat-l { font-size: 12px; line-height: 16px; color: var(--text-3); }
.stat-v { font-family: var(--mono); font-size: 20px; font-weight: 500; line-height: 1.2; color: var(--text-1); font-variant-numeric: tabular-nums; }
.stat-v.xl { font-size: 28px; }
.stat-sub { font-size: 12px; color: var(--text-3); }

/* ==========================================================================
   12. Table
   ========================================================================== */

.table-wrap { min-width: 0; overflow-x: auto; }
.table-scroll { min-width: 0; max-height: 420px; overflow: auto; }
.table { width: 100%; font-size: 13px; font-variant-numeric: tabular-nums; }
.table th {
  height: 32px;
  padding: 0 12px;
  border-bottom: 1px solid var(--divider);
  background: var(--surface);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-align: left;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--text-3);
}
.table thead th { position: sticky; top: 0; z-index: 1; }
.table td {
  height: 36px;
  padding: 0 12px;
  border-bottom: 1px solid var(--divider);
  color: var(--text-1);
  vertical-align: middle;
  transition: background-color var(--t-fast) var(--ease);
}
.table th:first-child, .table td:first-child { padding-left: 16px; }
.table th:last-child, .table td:last-child { padding-right: 16px; }
.table tbody tr:last-child td { border-bottom: 0; }
.table .num { text-align: right; }
.table td.mono, .table td code { font-size: 12px; color: var(--text-2); }
.table td.t-dim { color: var(--text-3); }
.table tbody tr:hover td { background: var(--hover); }
.table tr.is-selected td { background: var(--accent-weak); }
.table tr.is-selected td:first-child { box-shadow: inset 2px 0 0 var(--accent); }
.table tr.is-clickable, .table tr[data-open] { cursor: pointer; }
.table .actions { text-align: right; white-space: nowrap; }
.table .actions > * + * { margin-left: 4px; }
.table-sm td { height: 32px; }
.table-sm th { height: 28px; }
/* A table inside a padded .panel-b: no outer cell padding, aligns with the body text. */
.table-inset th:first-child, .table-inset td:first-child { padding-left: 0; }
.table-inset th:last-child, .table-inset td:last-child { padding-right: 0; }
.table-inset tr.is-selected td:first-child { padding-left: 8px; }
.modal .table th { background: var(--elevated); }

/* ==========================================================================
   13. Rail, countdown, log, empty, sub-tabs
   ========================================================================== */

/* rail(): horizontal steps joined by a 1px line. */
.rail { --rail-tone: var(--warn); display: flex; align-items: flex-start; min-width: 0; margin: 0; padding: 0; list-style: none; }
.rail-warn { --rail-tone: var(--warn); }
.rail-neg { --rail-tone: var(--neg); }
.rail-pos { --rail-tone: var(--pos); }
.rail-muted { --rail-tone: var(--text-3); }
.rail-accent { --rail-tone: var(--accent); }
.rail-step { position: relative; display: flex; flex: 1 1 0; flex-direction: column; gap: 6px; min-width: 0; padding-right: 8px; }
.rail-step:last-child { flex: 0 1 auto; padding-right: 0; }
.rail-node { position: relative; display: flex; align-items: center; height: 12px; }
.rail-node::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 18px;
  right: -2px;
  height: 1px;
  background: var(--border-2);
}
.rail-step:last-child .rail-node::after { display: none; }
.rail-dot { position: relative; display: inline-flex; align-items: center; justify-content: center; flex: none; width: 12px; height: 12px; color: var(--text-2); }
.rail-dot::before { content: ""; width: 6px; height: 6px; border: 1px solid var(--text-4); }
.rail-dot .ic { width: 12px; height: 12px; }
/* A label that does not fit wraps to a second line (never "Potwierdzenie odbi…"). */
.rail-l { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; font-size: 12px; line-height: 1.3; overflow-wrap: break-word; color: var(--text-3); }
.rail-m { overflow: hidden; font-family: var(--mono); font-size: 11px; white-space: nowrap; text-overflow: ellipsis; color: var(--text-3); }
.rail-step.is-done .rail-dot::before { display: none; }
.rail-step.is-done .rail-node::after { background: var(--text-3); }
.rail-step.is-done .rail-l { color: var(--text-2); }
.rail-step.is-current .rail-dot::before { width: 8px; height: 8px; border-color: var(--accent); background: var(--accent); }
.rail-step.is-current .rail-l { font-weight: 500; color: var(--text-1); }
.rail-step.is-current .rail-m { color: var(--text-1); }   /* who acts now */
.rail-step.is-halted .rail-dot::before { border-color: var(--rail-tone); }
.rail-step.is-halted .rail-l { color: var(--text-3); }
.rail-step.is-halted .rail-node::after, .rail.is-halted .is-pending .rail-node::after { background: none; border-top: 1px dashed var(--text-4); height: 0; }
.rail-terminal .rail-dot::before { width: 8px; height: 8px; border-color: var(--rail-tone); background: var(--rail-tone); }
.rail-terminal .rail-l { font-weight: 500; color: var(--rail-tone); }

/* countdown(): mono time over a 2px track. */
.countdown { display: inline-flex; flex-direction: column; gap: 4px; min-width: 96px; vertical-align: middle; }
.cd-v { font-family: var(--mono); font-size: 12px; white-space: nowrap; color: var(--text-2); font-variant-numeric: tabular-nums; }
.cd-track { position: relative; display: block; height: 2px; overflow: hidden; background: var(--border); }
.cd-fill { position: absolute; top: 0; bottom: 0; left: 0; background: var(--text-3); transition: width 1s linear, background-color var(--t) var(--ease); }
.countdown.is-bare { display: inline; min-width: 0; }
.cd-warn .cd-v { color: var(--warn); }
.cd-warn .cd-fill { background: var(--warn); }
.cd-neg .cd-v { color: var(--neg); }
.cd-neg .cd-fill { background: var(--neg); }
.cd-muted .cd-v { color: var(--text-3); }
.cd-muted .cd-fill { background: var(--text-4); }

/* Activity log: rows of "HH:MM:SS  ACTOR  EVENT  chain  txid" with a 2px kind marker.
   <div class="log"><div class="log-line k-pos"><span class="log-t">…</span><span class="log-a">…</span>
   <span class="log-e"><span class="log-k">Event</span><span class="log-m">message</span></span>
   <span class="log-c">chainMark()</span><span class="log-x">txLink()</span></div></div>
   Fixed tracks, so every column lines up across rows: always render all five
   cells (an empty .log-c / .log-x keeps its place). Time, actor, chain and tx
   are mono; the event keyword is sans 500 --text-1, its message sans --text-2. */
.log { display: flex; flex-direction: column; min-width: 0; font-family: var(--mono); font-size: 12px; container-type: inline-size; }
.log-line {
  display: grid;
  /* The event takes the free width, so chain + tx sit at the right edge like
     the values of the terms below; only the message itself is capped (.log-e). */
  /* The actor track fits a 16-character account name ("Maksymilian_kowa"). */
  grid-template-columns: 64px minmax(84px, 120px) minmax(0, 1fr) 64px 180px;
  align-items: center;
  gap: 12px;
  min-height: 28px;
  padding: 4px 16px 4px 14px;
  border-bottom: 1px solid var(--divider);
  border-left: 2px solid transparent;
  color: var(--text-2);
}
.log-line:last-child { border-bottom: 0; }
.log-t { color: var(--text-3); font-variant-numeric: tabular-nums; }
.log-a { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; color: var(--text-2); }
.log-e { min-width: 0; max-width: 880px; color: var(--text-1); overflow-wrap: anywhere; }
.log-k { margin-right: 8px; font-family: var(--font); font-weight: 500; color: var(--text-1); }
.log-m { font-family: var(--font); font-size: 13px; color: var(--text-2); font-variant-numeric: tabular-nums; }
.log-c { min-width: 0; color: var(--text-3); white-space: nowrap; }
.log-c .chain-name { font-size: 11px; color: var(--text-3); }
.log-x { justify-self: end; min-width: 0; }
/* Narrow logs (a side panel): the chain column gives way. */
@container (max-width: 640px) {
  .log-line { grid-template-columns: 64px minmax(72px, 112px) minmax(0, 1fr) 150px; }
  .log-c { display: none; }
}
.log-line.k-accent { border-left-color: var(--accent); }
.log-line.k-pos { border-left-color: var(--pos); }
.log-line.k-neg { border-left-color: var(--neg); }
.log-line.k-warn { border-left-color: var(--warn); }
.log-line.k-muted { border-left-color: var(--text-4); }

/* QR code on a warm off-white plate (never pure white): the image's white
   modules take the plate colour (multiply) and its black modules become
   --primary-fg (the lighten overlay), 12px quiet zone around it.
   <span class="qr-frame"><img class="qr" …></span> — hidden with a failed image. */
.qr-frame { position: relative; display: inline-flex; flex: none; padding: 12px; border-radius: var(--r-2); background: var(--primary-bg); isolation: isolate; }
.qr-frame > img { display: block; mix-blend-mode: multiply; image-rendering: pixelated; }
.qr-frame::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: var(--primary-fg); mix-blend-mode: lighten; pointer-events: none; }
.qr-frame:has(> img[hidden]) { display: none; }

/* Empty state: one quiet line (+ optional secondary button). */
.empty {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 24px 16px;
  font-size: 13px;
  text-align: center;
  color: var(--text-3);
}

/* Compact tab strip inside a panel header (e.g. other swaps). */
.subtabs { display: flex; align-items: center; gap: 2px; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.subtabs::-webkit-scrollbar { display: none; }
.subtab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: none;
  height: 26px;
  padding: 0 8px;
  border: 1px solid transparent;
  border-radius: var(--r-2);
  background: transparent;
  color: var(--text-3);
  font-size: 12px;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease);
}
.subtab:hover { color: var(--text-1); background: var(--hover); }
.subtab.is-active, .subtab[aria-selected="true"] { border-color: var(--border-2); background: var(--elevated); color: var(--text-1); }
.subtab code { font-size: 12px; color: inherit; }

/* ==========================================================================
   14. Overlays: toasts, modal
   ========================================================================== */

/* While the modal is open the stack lives inside the <dialog> (ui.js
   placeToasts), so it stays above the backdrop and clickable. */
.toasts {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: min(380px, calc(100vw - 32px));
  color: var(--text-1);
  text-align: left;
  pointer-events: none;
}
.toast {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  overflow: hidden;
  padding: 10px 8px 10px 14px;
  border: 1px solid var(--border-2);
  border-radius: var(--r-2);
  background: var(--elevated);
  box-shadow: var(--overlay-shadow);
  pointer-events: auto;
  animation: toast-in var(--t) var(--ease);
  transition: opacity var(--t) var(--ease), transform var(--t) var(--ease);
}
.toast::before { content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 2px; background: var(--text-3); }
.toast-success::before { background: var(--pos); }
.toast-warn::before { background: var(--warn); }
.toast-error::before { background: var(--neg); }
.toast-body { display: flex; flex: 1 1 auto; flex-direction: column; gap: 2px; min-width: 0; padding-top: 1px; font-size: 13px; line-height: 1.4; color: var(--text-2); overflow-wrap: anywhere; }
.toast-t { font-weight: 500; color: var(--text-1); }
.toast-m { color: var(--text-1); }
.toast-t + .toast-m { color: var(--text-2); }
.toast-d { margin-top: 2px; font-size: 12px; }
.toast-d summary { width: max-content; color: var(--text-3); cursor: pointer; list-style: none; }
.toast-d summary::-webkit-details-marker { display: none; }
.toast-d summary::after { content: " ›"; }
.toast-d[open] summary::after { content: " ‹"; }
.toast-d summary:hover { color: var(--text-1); }
.toast-d code { display: block; margin-top: 4px; font-size: 11px; line-height: 1.5; color: var(--text-3); overflow-wrap: anywhere; }
.toast-x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 20px;
  height: 20px;
  padding: 0;
  border: 0;
  border-radius: var(--r-1);
  background: transparent;
  color: var(--text-3);
}
.toast-x:hover { color: var(--text-1); background: var(--hover); }
.toast.is-out { opacity: 0; transform: translateY(4px); }
@keyframes toast-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.modal {
  width: min(520px, calc(100vw - 32px));
  max-width: none;
  max-height: calc(100vh - 64px);
  padding: 0;
  overflow: hidden;
  border: 1px solid var(--border-2);
  border-radius: var(--r-3);
  background: var(--elevated);
  color: var(--text-1);
  box-shadow: var(--overlay-shadow);
}
.modal[open] { display: flex; flex-direction: column; animation: modal-in var(--t) var(--ease); }
.modal:focus, .modal:focus-visible { outline: none; }
.modal-wide, .modal.wide { width: min(760px, calc(100vw - 32px)); }
.modal::backdrop { background: rgba(0, 0, 0, 0.6); }
.modal-card { display: flex; flex: 1 1 auto; flex-direction: column; min-height: 0; }
.modal-h {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  height: 40px;
  padding: 0 8px 0 16px;
  border-bottom: 1px solid var(--divider);
}
.modal-t {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  overflow: hidden;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--text-2);
}
.modal-t .ic { color: var(--text-3); }
.modal-b { flex: 1 1 auto; min-height: 0; padding: 16px; overflow: auto; }
.modal-f { display: flex; justify-content: flex-end; gap: 8px; flex: none; padding: 12px 16px; border-top: 1px solid var(--divider); }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }
/* Opacity only: a transform would make the dialog the containing block of the toast stack inside it. */
@keyframes modal-in { from { opacity: 0; } to { opacity: 1; } }

/* ==========================================================================
   15. Motion helpers
   ========================================================================== */

/* flash(el): value changed — brief accent-weak background fade. */
.flash { animation: flash 600ms var(--ease); }
@keyframes flash { from { background-color: var(--accent-weak); } to { background-color: transparent; } }

.spinner {
  display: inline-block;
  flex: none;
  width: 12px;
  height: 12px;
  border: 1.5px solid var(--text-4);
  border-top-color: var(--text-1);
  border-radius: 50%;
  vertical-align: middle;
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0s !important; }
  .spinner, .btn.is-loading::after { animation-duration: 1.4s !important; animation-iteration-count: infinite !important; }
}

.noscript { padding: 48px 16px; text-align: center; color: var(--text-2); }
