/* Gotham Wallet — Portfolio and Manage.
 *
 * Loaded after /static/style.css. It PLACES the app's components; it does not
 * restyle them. Almost everything on these two pages is already a component with
 * its own rules and its own animations — .app-header, .act-tabs, .act-cards /
 * .act-card, .act-wt-head / .act-wt-col, .sc-card, .sc-io-box / .sc-io-cap,
 * .sc-wallet-card, the rail's rows and groups — so what is left here is the
 * one-column shell, the 1280 measure, and the handful of grid tracks those
 * components read from a variable.
 */

/* ---- the shell is the app's, in its below-1280 configuration ---------------- */
/* One column, header on row 1, canvas on row 2 — the same three declarations the
   1279.98px media block makes, stated unconditionally because this page has no
   rail to give a column back to. */
#app.app,
#app.app:has(> .wallet-rail) { grid-template-columns: minmax(0, 1fr); }
#app.app > .app-main { grid-column: 1; grid-row: 2; }
/* The header's right border belongs to the rail seam it used to meet. */
#app.app > .app-header { border-right: 0; }
/* Its BAR is full-bleed — the background and the bottom rule run the window — but
   its CONTENTS sit on the same 1280 measure as everything below, so the wordmark
   and the coin picker line up with the page title and the boxes rather than with
   the window edges. Same expression the shell resolves to, so the two cannot drift. */
#app.app > .app-header { padding-inline: max(16px, calc((100% - 1280px) / 2 + 16px)); }

/* FIXED PAGE, NO SCROLL. .app-main is the dashboard's scroller; here everything
   has to fit, so the scroller is off and each row below claims its share. */
.app-main.wp-main {
  overflow: hidden; scrollbar-gutter: auto;
  padding: 0; margin: 0; min-height: 0;
  display: flex; flex-direction: column;
}

.msg { padding: 0 16px; }

.wp-shell {
  flex: 1 1 auto; min-height: 0;
  width: min(1280px, 100%); margin: 0 auto; padding: 0 16px 16px;
  display: flex; flex-direction: column;
}

/* ---- title row: the two pages ARE the heading ------------------------------ */
.wp-titlebar {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  padding: 40px 0 16px;
}
.wp-pages { display: flex; align-items: baseline; gap: 20px; }
/* The one thing with no component to borrow: a tab pair at display size. Type and
   colour are the app's tokens; nothing else is invented. */
.wp-page-tab {
  padding: 0; border: 0; background: none; cursor: pointer;
  font-family: inherit; font-size: 32px; line-height: 1.15; font-weight: 500;
  letter-spacing: -0.01em; color: var(--muted-2);
  transition: color .16s ease;
}
.wp-page-tab:hover { color: var(--muted); }
.wp-page-tab.active { color: var(--foreground); }
.wp-page-tab:focus-visible { outline: 2px solid var(--ring); outline-offset: 3px; }
.wp-vault-actions { display: flex; align-items: center; gap: 8px; }
/* Height comes from .btn — 32px, the app's one control height. */
.wp-vault-actions .btn { display: inline-flex; align-items: center; gap: 8px; }
.wp-vault-actions svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.5;
                        stroke-linecap: round; stroke-linejoin: round; }

/* NO gap under the tab strip: the strip is the box's own header, the way .act-tabs
   sits directly on the card it names everywhere else in the app. The stat band keeps
   its 8px, declared on itself. */
.wp-page { flex: 1 1 auto; min-height: 0; display: none; flex-direction: column; gap: 0; }
.wp-page.active { display: flex; }

/* ---- PORTFOLIO ------------------------------------------------------------- */
.wp-subtabs { flex: 0 0 auto; }
/* .sc-card is the app's box; the overview fills it edge to edge the way #dash-charts
   does on the dashboard, so the card gives up its padding to it. */
.wp-ov { flex: 0 0 540px; height: 540px; min-height: 0; padding: 0; background: var(--background); }
/* THE SWAP. On the dashboard the allocation rail is the narrow left column and the
   chart is the wide right one. Here the chart leads and the allocation answers it —
   the component is untouched, its two children trade sides and the divider moves
   with them. */
.wp-ov .bchart-ov {
  margin: 0; height: 100%;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  grid-auto-rows: minmax(0, 1fr);
}
.wp-ov .bchart-ov-pane { order: 1; }
.wp-ov .bchart-ov-rail { order: 2; border-right: 0; border-left: 1px solid var(--border); }
/* Top-aligned, slack at the foot. The dashboard's rail is exactly 360px and
   .bchart-alloc-head's `margin-bottom:auto` pushes the bar down to meet the table,
   which is right at that height. This rail is as tall as the viewport allows, and
   the same rule opens a 200px hole between the figure and the bar it belongs to. */
.wp-ov .bchart-alloc-top { flex: 0 0 auto; }
.wp-ov .bchart-alloc-top > .bchart-alloc-head { margin-bottom: 0; }

/* The stat band is the Activity card's stat band — .act-cards / .act-card, the same
   four tiles the dashboard's overview is built from. It needs one extra track for
   the add cell and its own frame, and nothing else. */
/* The band's own tokens, not new rules: .act-card reads its insets and its vertical
   padding from these three, so the tiles get taller and wider-inset without a single
   declaration reaching inside one. */
.wp-stats { flex: 0 0 auto; padding: 0; margin-top: 8px; }
.wp-stats .act-cards { --act-card-pad-y: 22px; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.wp-stats .act-card { --act-pad-l: 24px; --act-pad-r: 24px; }
/* Tight to the figure it qualifies — 2px, not 4 — and the arrow trails the number. */
.wp-stat-delta {
  display: inline-flex; align-items: center; gap: 4px; margin-top: 2px;
  font-size: var(--cap-size); color: var(--green);
}
.wp-stat-delta.down { color: var(--red); }
/* Reserved, not drawn: the line is there on every tile so the band is one height
   whatever is in scope, and empty on the three that have nothing to compare against. */
.wp-stat-delta.is-empty { visibility: hidden; }
.wp-stat-delta svg { width: 9px; height: 9px; fill: currentColor; stroke: none; }
/* ---- MANAGE ---------------------------------------------------------------- */
.wp-manage {
  flex: 1 1 auto; min-height: 0;
  display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 8px;
}
.wp-manage-right { min-width: 0; min-height: 0; display: flex; flex-direction: column; gap: 8px; }

/* .sc-card is a PADDED flex column with a --sp-3 gap between its children. Every
   panel here is bands stacked edge to edge — a search row on a toolbar on a list —
   so the padding and the gap both go, or each seam becomes a 12px trench and the
   first row of every table starts one gap down from the head naming it. */
.wp-coins, .wp-wallets, .wp-stats, .wp-ov { padding: 0; gap: 0; }

/* ---- the coin list --------------------------------------------------------- */
/* The app's rail, unpinned: same search row, same group bar, same chips, same rows,
   same transitions. Three tracks — name, chain, actions — because a coin is a name,
   the chain it is on, and one thing you can do to it. The plane is --rail, the page
   tone the real rail sits on: a list of rows on --surface reads as a card of them. */
.wp-coins {
  min-width: 0; min-height: 0; display: flex; flex-direction: column;
  background: var(--rail);
}
/* ON THE ELEMENTS, not on the panel. The app declares --rail-cols on
   `.rail-bal-head, .rail-wallet` themselves, and an element's own declaration beats
   anything it would otherwise inherit — so setting it on the container looked right
   and changed nothing. Same two selectors, one level more specific. */
.wp-coins .rail-wallet, .wp-coin-head {
  /* 72px stated, NOT var(--fig-col-act): that variable is declared on .wallet-rail,
     which this page does not have — so the var was invalid, which makes the whole
     --rail-cols value invalid at computed-value time, which drops
     grid-template-columns to `none` and collapses the head to one auto track. */
  --rail-cols: minmax(0, 1fr) 88px 28px;
  --rail-gap: 8px;
}
/* The field has the row to itself again, so the placeholder finishes its sentence. */
.wp-coins .rail-search-row { flex: 0 0 auto; gap: 12px; padding-inline: 16px; }
.wp-coins .rail-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.wp-coins .rail-wallet-actions { grid-column: 3; }
.wp-coins .rail-empty { padding: 24px 16px; color: var(--muted); font-size: var(--cap-size); }
/* Right-aligned, like every other non-identity column in the app's tables: the
   badges then share an edge instead of starting at eight different places. */
.wp-coin-chain {
  grid-column: 2; grid-row: 1 / span 2; align-self: center;
  min-width: 0; display: flex; justify-content: flex-end;
}
.wp-coin-chain .rail-wallet-group { max-width: 100%; }
/* The head reads the same three tracks, so a label can never sit over the wrong
   column. Sticky, because the list under it scrolls. */
/* .act-wt-head brings its own height, rule and type; all it needs here is the coin
   list's three tracks and the same inset the rows use. */
.wp-coin-head {
  grid-template-columns: var(--rail-cols); column-gap: var(--rail-gap);
  padding-inline: 16px;
}
.wp-coin-head > .act-wt-col:nth-child(2) { text-align: right; }
.wp-coin-head > .act-wt-col:nth-child(2) > .rail-sort-head { justify-content: flex-end; }
/* The rail dresses its bar and its field through #rail-groups / #rail-search — ids
   this list cannot borrow without colliding with the real rail. Same declarations,
   matched by position in the component instead. */
.wp-coins .rail-groups {
  display: flex; flex-direction: column; align-items: stretch;
  height: auto; gap: var(--sp-2);
  padding: var(--sp-3) 16px;
  border-bottom: 1px solid var(--border);
}
.wp-coins .rail-search-field input {
  width: 100%; height: 32px; box-sizing: border-box;
  padding: 0 0 0 24px; margin: 0;
  background: none; border: 0; border-radius: 0; color: var(--foreground);
  font-family: inherit; font-size: var(--body-size); line-height: 32px;
}
.wp-coins .rail-search-field input::placeholder { color: var(--muted-2); }
.wp-coins .rail-search-field input:focus,
.wp-coins .rail-search-field input:focus-visible {
  outline: none; box-shadow: none; border-color: transparent;
}
/* Selection is the rail's own: a low-alpha accent fill and a 2px accent bar, which is
   the app's "this one" mark everywhere a wallet is listed. Nothing overridden. */
/* --surface, NOT --surface-2. .rail-act's hover box is --surface-2, so a row that
   lit to the same tone swallowed it — the buttons had their boxes all along and
   nothing could show them. One step down and the box appears where it always was. */
.wp-coins .rail-wallet:hover { background: var(--surface); }

/* ---- the wallet table ------------------------------------------------------ */
/* .act-wt-head over .sc-wallet-card rows — the app's table, with three more figure
   columns. Everything here is the track list and where each of the card's children
   lands in it. */
.wp-wallets {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column;
  --act-wt-cols: minmax(0, 1.7fr) repeat(5, minmax(0, 1fr)) 56px;
  --act-inset: 20px;
}
/* The head: name, count, then the two controls pinned right. Show dust takes the
   slack — the same job .rail-bar-title's auto margin does on the rail's toolbar —
   and Recover keeps its own gap, because .sc-io-cap's --sp-2 is right between a title
   and its badge and too tight between two controls that do different things. */
.wp-wallets > .sc-io-cap { flex: 0 0 auto; }
.wp-wallets .wp-dust { margin-left: auto; flex: 0 0 auto; }
/* .sc-io-cap's own gap is 8px, which is the gap between two buttons everywhere in
   this app — so Create simply takes it. Recover keeps the extra 10 because the thing
   on ITS left is a toggle, not a button, and the two should not read as a pair. */
.wp-recover { flex: 0 0 auto; margin-left: 10px; }
.wp-create { flex: 0 0 auto; }
.wp-wallets > .act-wt-head { flex: 0 0 auto; padding-inline: var(--act-inset); }
.wp-wallet-rows { flex: 1 1 auto; min-height: 0; overflow-y: auto; background: var(--rail); }
/* 68px on a 20px inset — the height a wallet row is EVERYWHERE in this app. */
.wp-wallet-rows .sc-wallet-card {
  display: grid; grid-template-columns: var(--act-wt-cols);
  grid-template-rows: auto auto;
  grid-template-areas: "name f1 f2 f3 f4 f5 act" "addr f1 f2 f3 f4 f5 act";
  align-items: center; gap: 0 24px;
  min-height: 68px; padding: 12px var(--act-inset);
  border: 0; border-bottom: 1px solid var(--border); background: none;
  transition: background .12s;
}
.wp-wallet-rows .sc-wallet-card:last-child { border-bottom: 0; }
.wp-wallet-rows .sc-wallet-card:hover { background: var(--surface); }
/* The address is display:none on the base class and unhidden by a .sc-dropzone
   rule — this list is not a drop zone, so it says so itself. Its copy button is a
   BASELINE sibling of the address, not a block after it: .sc-wallet-addr is a grid
   item here, so the default alignment dropped the square half a line low. */
.wp-wallet-rows .sc-wallet-addr {
  display: flex; align-items: center; gap: 6px;
  text-align: left; grid-area: addr; min-width: 0;
}
.wp-wallet-rows .sc-wallet-addr > .wcopy { margin-left: 0; flex: 0 0 auto; }
.wp-wallet-rows .sc-wallet-name { grid-area: name; font-size: var(--body-size); color: var(--foreground); }
.wp-wallet-rows .wp-c1 { grid-area: f1; }
.wp-wallet-rows .wp-c2 { grid-area: f2; }
.wp-wallet-rows .wp-c3 { grid-area: f3; }
.wp-wallet-rows .wp-c4 { grid-area: f4; }
.wp-wallet-rows .wp-c5 { grid-area: f5; }
.wp-wallet-rows .sc-wallet-fig { text-align: right; align-self: center; }
.wp-wallet-rows .sc-wallet-act {
  grid-area: act; align-self: center; justify-self: end;
  display: flex; align-items: center; justify-content: flex-end; gap: 4px;
}
.wp-wt-pos { color: var(--green); }
.wp-wt-neg { color: var(--red); }
/* Every column right-aligned except the first, which the head shares with the name. */
.wp-wallets > .act-wt-head > .act-wt-col { text-align: right; }
.wp-wallets > .act-wt-head > .act-wt-col > .rail-sort-head { justify-content: flex-end; }
.wp-wallets > .act-wt-head > .act-wt-col:first-child { text-align: left; }
.wp-wallets > .act-wt-head > .act-wt-col:first-child > .rail-sort-head { justify-content: flex-start; }

/* ---- actions appear under the pointer -------------------------------------- */
/* A resting list stays quiet. Two glyphs on every one of twenty-two rows is a column
   of furniture; under the pointer they are the two things you can do to the row you
   are on. Focus counts as reaching for them, or they would be unreachable by
   keyboard. */
.wp-wt-acts, .wp-coins .rail-wallet-actions {
  opacity: 0; transition: opacity .12s;
}
.wp-wallet-rows .sc-wallet-card:hover .wp-wt-acts,
.wp-wallet-rows .sc-wallet-card:focus-within .wp-wt-acts,
.wp-coins .rail-wallet:hover .rail-wallet-actions,
.wp-coins .rail-wallet:focus-within .rail-wallet-actions,
.wp-coins .rail-wallet.selected .rail-wallet-actions { opacity: 1; }

/* NO GRIP. The six dots are the app's "this row can be picked up" mark, and neither
   of these lists is a drag source — there is nowhere on this page to drop a row. A
   handle that appears on hover and does nothing is worse than no handle at all. */
.wp-coins .rail-wallet::before,
.wp-wallet-rows .sc-wallet-card::before { content: none; }
.wp-wallet-rows .sc-wallet-card { cursor: default; }
/* Same inset both sides, and the same one the head above uses — .rail-wallet ships
   20px left / 16px right for a rail whose scrollbar eats the difference, and here
   that put every column 4px out of step with its heading. */
.wp-coins .rail-wallet { cursor: pointer; position: relative; padding: 12px 16px; }

.wp-empty { padding: 24px 16px; color: var(--muted); font-size: var(--cap-size); }


/* The address under a name reads at --muted-2 in the coin list (the rail's own final
   word on it) and at --muted in .sc-wallet-addr. Two tones for one kind of fact; the
   darker one is right — an address is what you check, not what you read. */
.wp-wallet-rows .sc-wallet-addr { color: var(--muted-2); }

/* ---- the wordmark is a control, and it says which origin you are on --------- */
/* A link, so it reads as one; the drag is off in the markup because a picture that
   follows the pointer is the browser answering a press this element wanted. */
.wp-brand-link { text-decoration: none; }
.wp-brand-link:focus-visible { outline: 2px solid var(--ring); outline-offset: 3px; }
/* .rail-wallet-group is the app's small tag — the one a wallet wears for its group.
   Same kind of fact: a short word about what this thing belongs to. */
.wp-vault-tag { flex: 0 0 auto; max-width: none; }

/* ---- the book, in the component's own classes ------------------------------ */
/* Three columns: what it is, what it is worth in ETH, how much of it there is. The
   unit is stated once in the heading and never again on a row — every figure in the
   Balance column is ETH, and repeating it eleven times is eleven words that say
   nothing the column has not said. */
.wp-ov .bchart-alloc-row {
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1fr);
}
.wp-ov .bchart-alloc-table { overflow-y: auto; min-height: 0; }
.wp-ov .bchart-alloc-thead { position: sticky; top: 0; z-index: 1; background: var(--surface); }
/* A key on EVERY row, native and the plotted coin included — they were the two the
   component coloured by class, so they were the two with no dot when the rest got one. */
.wp-ov .bchart-alloc-asset { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.wp-ov .bchart-alloc-dot { flex: 0 0 auto; }
/* An extra segment is a button like the component's two. */
.wp-ov .bchart-alloc-seg { display: block; height: 100%; border: 0; padding: 0; cursor: pointer; }
/* HOVER LINKS A ROW TO ITS SEGMENT. The component pairs its own two with :has(); with
   N assets the pair has to be named, so both carry the key and everything else dims. */
.wp-ov .bchart-alloc-seg, .wp-ov .bchart-alloc-key { transition: opacity .12s; }
.wp-ov .bchart-alloc-seg.is-dim, .wp-ov .bchart-alloc-key.is-dim { opacity: .35; }
/* FIVE KEYS AND A CONTROL DO NOT FIT ONE LINE at this width. The component's legend
   is a nowrap flex row with two keys in it; with five and a Show-more the keys were
   the only thing that could give, so they shrank to single letters. Wrapping, with
   each key holding its own width. */
.wp-ov .bchart-alloc-legend { flex-wrap: wrap; gap: 10px 16px; }
.wp-ov .bchart-alloc-key { flex: 0 0 auto; min-width: 0; }
.wp-ov .bchart-alloc-keyname { white-space: nowrap; }

/* THE SELECTED ROW, in the vocabulary style.css spells out at .rail-group-chip.active:
   "every other 'this one is selected' in here is a filled row with a 2px inset accent
   bar down its left edge" — .rail-wallet.selected, .loop-sub.selected and the coin
   list on Manage all say it that way, and a chosen coin here is the same fact. The
   fill lifts to --surface-2, the bar carries the state, and the row's two figures come
   up out of --muted the way an active chip's count does.
   The rows already carried `.active` (charts.js toggles it on its own two through
   chartSetSeries); nothing had ever drawn it. */
.wp-ov .bchart-alloc-item.active {
  background: var(--surface-2);
  box-shadow: inset 2px 0 0 var(--accent);
}
.wp-ov .bchart-alloc-item.active .bchart-alloc-total,
.wp-ov .bchart-alloc-item.active .bchart-alloc-share { color: var(--foreground); }

/* The line under the headline when a figure is INCOMPLETE: a coin whose token no
   quoter will price contributes its ETH and nothing else, and the total has to say so
   rather than quietly reading low. Same muted caption tier as the cap above it. */
.wp-alloc-note {
  margin-top: 4px;
  font-size: var(--cap-size); line-height: 16px; color: var(--muted-2);
  white-space: normal; text-align: left;
}

/* Show more is a control in the legend, not a row of the table below it. */
.wp-alloc-more {
  flex: 0 0 auto; padding: 0;
  border: 0; background: none;
  color: var(--muted-2); font-family: inherit; font-size: var(--cap-size);
  cursor: pointer; transition: color .12s;
}
.wp-alloc-more:hover { color: var(--foreground); }
.wp-alloc-more:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }

/* The quantity under the chart's own value, on its own line INSIDE the readout —
   flex-wrap plus a full-width basis, so it breaks under the figure rather than
   becoming a fourth grid row under the plot. */
.wp-ov .bchart-readout { flex-wrap: wrap; }
.wp-chart-amount {
  flex: 0 0 100%; margin-top: 2px;
  font-family: var(--num); font-variant-numeric: tabular-nums;
  font-size: var(--body-size); color: var(--muted); line-height: 20px;
}
.wp-chart-amount[hidden] { display: none; }

/* THE SPARK GETS A STATED HEIGHT AND THE BAND GROWS TO IT. It was taking whatever
   was left under the text in a tile sized by its padding, which is a trace squeezed
   into the gap rather than a chart given a box. 56px is the same lane the Sweep and
   Activity tiles give theirs. */
.wp-stats .act-card { display: flex; flex-direction: column; }
.wp-stats .act-card .act-spark { margin-top: auto; padding-top: 12px; height: 56px; flex: 0 0 56px; }
/* 4px under the figure, not the ~10 the line box was leaving. The percentage is a
   footnote on the number above it, and a footnote sits close. */
.wp-stats .act-fig-line { margin-top: 8px; min-height: 0; }
.wp-stat-delta { margin-top: 4px; }

/* ---- the app's overlay scrollbar, on this page's own scrollers -------------- */
/* .sc-oscroll hides the native bar and draws a thumb in the 8px lane the rows keep
   clear, so nothing overlaps a sticky heading and no column gives up width to it. The
   lists here reserve that lane the same way every list in the app does. */
.wp-ov .bchart-alloc-table.sc-oscroll,
.wp-coins .rail-body.sc-oscroll,
.wp-wallet-rows.sc-oscroll { padding-right: 0; }
/* The bar starts BELOW the sticky heading it would otherwise ride over. */
/* The scroll rail starts BELOW the sticky heading, so it must be told how tall that
   heading is — 40 now, in step with the rule above. */
.wp-ov .bchart-alloc-table { --sc-bar-top: 40px; }

/* ---- + Add: a glyph that turns into a chevron ------------------------------- */
.wp-add { gap: 6px; }
.wp-add-ico { width: 14px; height: 14px; display: block; overflow: visible; }
.wp-add-ico line {
  stroke: currentColor; stroke-width: 1.6; stroke-linecap: round;
  transform-origin: 8px 8px;
  transition: transform .24s cubic-bezier(.25, .46, .45, .94);
}
/* THE PLUS STAYS A PLUS. It used to fold into a chevron while the menu was open —
   a nice trick, and one more moving part on a button whose state the open menu right
   under it already states. The arms keep their transition property so nothing else
   in the icon has to change; they are simply never asked to move. */

/* A + on each row of the menu it opens. */
.qa-menu-ico {
  width: 14px; height: 14px; flex: 0 0 auto; align-self: center;
  fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round;
  color: var(--muted);
}
.qa-menu-item:hover .qa-menu-ico { color: var(--foreground); }
.qa-menu-item { gap: var(--sp-2); }

/* The eye rides inside the Reveal button, at the label's own weight. */
.wp-go-ico {
  width: 15px; height: 15px; margin-right: 6px; vertical-align: -2px;
  fill: none; stroke: currentColor; stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round;
}

/* ============================================================
   RESTORED. These rules were removed by a slice that deleted by ANCHOR — from
   one comment to another — rather than by rule, and took the dialog chrome, the
   chip inset, the selected-row hover and the sort arrow's side out with the block
   it was aiming at. Verbatim from 5ed3bd6.
   ============================================================ */
/* ---- dialogs --------------------------------------------------------------- */
/* .sc-modal is 380px, which is the right measure for a dialog that asks one thing
   ("name this group"). These ask for a form: two tracks with a figure each, or five
   fields in two columns. The class is the caller's, not the component's. */
.sc-modal:has(.wp-dlg-grid),
.sc-modal:has(.wp-wd-panel) { width: min(92vw, 560px); }
.sc-modal:has(.wp-secret) { width: min(92vw, 520px); }
/* scModalShell brings the box, the head, the ✕, the 70:30 footer and both
   animations. These are the field shapes that go inside one. */
.wp-field {
  width: 100%; box-sizing: border-box; height: var(--control-h);
  padding: 0 10px; background: var(--control-bg); color: var(--foreground);
  border: 1px solid var(--border); border-radius: var(--radius);
  font-family: inherit; font-size: var(--body-size);
}
.wp-field::placeholder { color: var(--muted-2); }
/* The seed box is the one field here that is a <textarea rows="2">, and .wp-field
   pins every field to one control height — so its second line was drawn OUTSIDE its
   own border, over whatever came next. Height follows the rows it was given. */
.wp-seed-field { height: auto; min-height: var(--control-h); padding: 7px 10px; line-height: 18px; resize: vertical; }
.wp-dlg-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 16px; }
/* csUpgrade replaces a <select> with .cs; it has to fill its field like an input. */
.wp-dlg-field .cs { width: 100%; }
.wp-dlg-field .cs-btn { width: 100%; height: var(--control-h); }
.wp-dlg-field { min-width: 0; display: flex; flex-direction: column; gap: 6px; color: var(--muted); }
.wp-dlg-field.is-wide { grid-column: 1 / -1; }
.wp-dlg-err { min-height: 1em; color: var(--red); font-size: var(--cap-size); }
.wp-dlg-err:empty { display: none; }
/* The footer's note takes the slack, which is what pins the buttons right — the same
   job .rail-bar-title's auto margin does on the toolbar. */
.wp-dlg-foot-note { margin-right: auto; color: var(--muted); font-size: var(--cap-size); }
.wp-dlg-warn { margin: 0; color: var(--muted); font-size: var(--body-size); line-height: 20px; }
.wp-dlg-warn strong { color: var(--foreground); font-weight: 400; }

/* ---- Add coin: what the chain says this token is --------------------------- */
/* The point of this block is that you can SEE the right coin was found before you
   commit an address to a vault. It is a report, not a decoration: name, symbol,
   decimals, the pool that was chosen, and its depth. Hidden entirely until there is
   something true to put in it, so an empty form is not decorated with an empty box.
   The dot carries the state — the same reading a lit .wp-chain-dot gives a row. */
.wp-detect { display: flex; align-items: flex-start; gap: 9px; }
.wp-detect[data-state="idle"] { display: none; }
.wp-detect-dot {
  flex: 0 0 auto; width: 6px; height: 6px; margin-top: 7px; border-radius: 50%;
  background: var(--muted-2);
}
.wp-detect[data-state="busy"] .wp-detect-dot {
  background: var(--muted); animation: actPulse 1.1s ease-in-out infinite;
}
.wp-detect[data-state="ok"] .wp-detect-dot {
  background: var(--green); box-shadow: 0 0 0 3px color-mix(in srgb, var(--green) 18%, transparent);
}
.wp-detect[data-state="warn"] .wp-detect-dot {
  background: var(--amber); box-shadow: 0 0 0 3px color-mix(in srgb, var(--amber) 18%, transparent);
}
.wp-detect[data-state="err"] .wp-detect-dot {
  background: var(--red); box-shadow: 0 0 0 3px color-mix(in srgb, var(--red) 18%, transparent);
}
.wp-detect-body { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.wp-detect-head { color: var(--foreground); font-size: var(--body-size); line-height: 20px; }
.wp-detect-line { color: var(--muted); font-size: var(--body-size); line-height: 20px; }
.wp-detect-note { color: var(--muted-2); font-size: var(--cap-size); line-height: 18px; }
/* The pool address is the one figure here worth checking against a block explorer,
   so it is set like every other address on this page and shown WHOLE — a truncated
   address is not something anyone can verify — and left selectable to be copied. */
.wp-detect-addr {
  font-family: var(--mono); font-size: var(--cap-size); line-height: 18px;
  color: var(--muted); word-break: break-all; user-select: text;
}

/* A revealed secret: monospace, wrapping, with the app's copy square beside it. */
.wp-secret { display: flex; flex-direction: column; gap: 6px; min-height: 24px; }
.wp-secret-cap { color: var(--muted); font-size: var(--cap-size); }
.wp-secret-row { display: flex; align-items: flex-start; gap: 8px; }
.wp-secret-value {
  flex: 1 1 auto; min-width: 0;
  font-family: var(--mono); font-size: var(--cap-size); line-height: 20px;
  color: var(--foreground); word-break: break-all;
}
.wp-secret-row > .wcopy { flex: 0 0 auto; margin-left: 0; }

/* Withdraw: the app's own .act-panel of .act-row sliders, then the destination. */
/* THE ROW IS A GRID HERE, not the panes' flex row. .act-row is
   `justify-content: space-between` with a fixed-width track, which is right in a pane
   where the sliders became typed boxes — in a dialog it leaves the track stranded at
   its natural width with the label and the figure pushed to the far edges. Three
   stated tracks: the label, the slider taking everything left, the figure on a fixed
   column so both rows end on one edge whatever they read. */
.wp-wd-panel { padding: 0; display: flex; flex-direction: column; gap: 12px; }
.wp-wd-panel .act-row {
  --act-read-w: 132px;
  display: grid; grid-template-columns: 56px minmax(0, 1fr) var(--act-read-w);
  gap: 16px; align-items: center; min-height: var(--control-h);
}
.wp-wd-panel .act-row > .act-label { flex: none; }
.wp-wd-panel .act-row > .act-track { flex: none; width: 100%; }
.wp-wd-panel .act-row > .act-read { flex: none; width: 100%; text-align: right; }
/* scReadEdit's editor is placed by a rule scoped to `.act-pane .act-row` and
   `.qa-params-fields .act-row` — neither of which is a dialog, so the field arrived
   at its browser default size and sat on top of the figure instead of over it. Same
   declarations, this scope. */
.wp-wd-panel .act-row > .act-read-input {
  position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  width: var(--act-read-w); min-width: 0; flex: none;
  box-sizing: border-box; height: 24px; padding: 0 6px;
  border: 0; border-radius: var(--radius);
  background-color: var(--control-bg-hover);
  box-shadow: 0 0 0 4px var(--control-bg-hover);
  color: var(--foreground);
  font-family: var(--num); font-variant-numeric: tabular-nums;
  font-size: var(--body-size); line-height: 24px; text-align: right;
  outline: none;
}
/* The destination row reads the same three tracks as the sliders above it, so "To"
   sits under "ETH" and the button ends where the figures do. */
/* NO LABEL COLUMN, and the same 8px every pair of buttons on this page sits on. The
   56px "To" pushed the field it named off the edge the sheet starts at, and 16px
   between the field and its picker was a different rhythm from the two buttons
   directly below them. */
.wp-field-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; align-items: center; }

/* The backup drop slot is the APP'S drop slot — .sc-dropzone, .sc-drop-empty, .sc-plus
   and .drop-hover are all style.css's, and a file lands in this one instead of a
   wallet. The only thing the component cannot know is that this box is also a button:
   clicking it opens the OS file picker, so it says so with the pointer. */
.wp-drop { cursor: pointer; }

/* The eye rides inside the Reveal button, at the label's own weight. */
.wp-go-ico {
  width: 15px; height: 15px; margin-right: 6px; vertical-align: -2px;
  fill: none; stroke: currentColor; stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round;
}

/* The address under a name reads at --muted-2 in the coin list (the rail's own final
   word on it) and at --muted in .sc-wallet-addr. Two tones for one kind of fact; the
   darker one is right — an address is what you check, not what you read. */
.wp-wallet-rows .sc-wallet-addr { color: var(--muted-2); }



/* The rail's chip reserves its right inset for a ✕ delete button (3px 5px 3px 9px).
   These chips have none, so that 5px read as a squeeze — worst beside the count,
   which then sat almost against the edge. Even inset, and the count keeps its gap. */
.wp-coins .rail-group-chip { padding: 3px 9px; }

/* ---- a selected row still lights under the pointer -------------------------- */
/* A tenth of the accent is the resting selection; a sixth is the same colour with
   the pointer on it. It used to fall through to the plain --surface hover, so the one
   row that was already marked went GREY when you touched it — the mark disappearing
   on hover is the opposite of what a hover is for. */
.wp-coins .rail-wallet.selected:hover {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
}

/* ---- the sort arrow hangs off the column's own edge ------------------------- */
/* .rail-sort-head is a flex row; a right-reading column puts the mark first, so the
   pair still ends flush with the figures under it. */
.rail-sort-head.is-right { justify-content: flex-end; }


/* ---- column heads --------------------------------------------------------- */
/* The SIZE is the component's own --cap-size, everywhere, same as the dashboard's.
   Only the BAND changes: 40px rather than 32, because the allocation table's heading
   was reading as a cramped strip against 68px rows. A heading is a caption over a
   column, not a row of it — the 12px was never the problem. */
.wp-page > .wp-sub-body .act-wt-head { height: 40px; }
/* flex: 0 0 auto with it. The table is a scrolling column flex container, so the
   heading is a flex ITEM — and a flex item shrinks past a stated height by default.
   It was being squeezed to its 22px of content while claiming to be 32. */
.wp-ov .bchart-alloc-thead { height: 40px; flex: 0 0 auto; }

/* ---- one body per sub-tab --------------------------------------------------- */
/* `display: contents` so the block DISSOLVES: the chart card is a fixed 540 and the
   band under it sizes to its content, and both of those are agreements with
   .wp-page's own column. A real box between them would take the agreement away from
   both and hand it to a wrapper that has no opinion about either. */
.wp-sub-body { display: contents; }

/* The pair a "not yet" panel says it with. The card that used to wrap them is gone —
   every tab is built now — but Sessions still speaks in this voice. */
.wp-soon-title { color: var(--foreground); font-size: var(--h3-size, 18px); }
.wp-soon-lead { max-width: 46ch; color: var(--muted); font-size: var(--body-size); line-height: 20px; }

/* ---- the chains table ------------------------------------------------------- */
/* The wallet table's parts, four tracks: chain · rpc · gas · actions. Same head,
   same rows, same fold — the only thing stated here is which track each fact sits
   in and how wide it gets. */
/* FLUSH UNDER THE TABS, the way the Overview's chart is. Every one of these panels
   carried a margin-top, so each tab but the first opened with its card floating a
   gap below the strip that selected it — and the strip stopped reading as the
   card's own head. The 8px rhythm belongs BETWEEN two cards (.wp-stats has it),
   not between a card and the tab that opened it. */
.wp-chains {
  flex: 1 1 auto; min-height: 0;
  padding: 0; gap: 0; display: flex; flex-direction: column;
  /* One inset for the cap, the column head and the rows — the same token every
     table in the app sizes itself from. */
  --act-inset: 20px;
}
/* .sc-io-cap is hard-coded to a 16px inset and every table under it to 20px, so a
   box head and its own column heads started at two different places. One token. */
.wp-chains > .sc-io-cap,
.wp-wallets > .sc-io-cap { padding-inline: var(--act-inset); }
.wp-chains > .sc-io-cap { flex: 0 0 auto; }
/* ADD sits at the far right of the head, away from the count it is not counting. */
.wp-chain-add { margin-left: auto; }
.wp-chains > .act-wt-head { flex: 0 0 auto; padding-inline: var(--act-inset); }
.wp-chain-rows {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; background: var(--rail);
}
/* ON THE ELEMENTS, not the panel: the app declares --rail-cols on .rail-wallet
   itself, and an element's own declaration beats anything it would inherit. Stated
   in full rather than through var(--fig-col-act), which is declared on .wallet-rail
   and would be invalid here — and one invalid var() drops the whole track list. */
.wp-chains .rail-wallet, .wp-chains > .act-wt-head {
  /* chain · coins · rpc · priority · max fee · limit × · gas cap · actions */
  /* ONE WIDE COLUMN, then six equal ones. Every column after the name holds a single
     short value, and sizing each to its own content left them clustered at the right
     of the table with a hole where the name ended. Equal tracks spread them across
     the width instead, which is the only arrangement in which a row can be read
     straight across. Actions is the exception: it holds one 26px button. */
  /* RPC carries a host and a status dot where the four beside it carry one short
     number each, so it takes half again as much of what is going. */
  --rail-cols: minmax(0, 2.4fr) minmax(0, 1fr) minmax(0, 1.9fr) repeat(4, minmax(0, 1fr)) 52px;
  --rail-gap: 12px;
}
.wp-chains > .act-wt-head {
  grid-template-columns: var(--rail-cols); column-gap: var(--rail-gap);
}
.wp-chains .rail-wallet { padding: 12px var(--act-inset); position: relative; }
.wp-chains .rail-wallet::before { content: none; }        /* nothing here is selectable */
.wp-chains .rail-wallet:hover { background: var(--surface); }
/* ON HOVER ONLY, the same as the coin and wallet rows. A control that is always
   visible on every row reads as part of the data; one that appears under the pointer
   reads as something you can do to the row you are pointing at. */
.wp-chains .rail-wallet-actions {
  grid-column: 8; opacity: 0; transition: opacity .12s;
}
.wp-chains .rail-wallet:hover .rail-wallet-actions,
.wp-chains .rail-wallet:focus-within .rail-wallet-actions { opacity: 1; }
/* Right-aligned like every other non-identity column, and the sort mark hangs off
   the edge the column is read from. */
.wp-chains > .act-wt-head > .act-wt-col { text-align: right; }
.wp-chains > .act-wt-head > .act-wt-col > .rail-sort-head { justify-content: flex-end; }
.wp-chains > .act-wt-head > .act-wt-col:first-child { text-align: left; }
.wp-chains > .act-wt-head > .act-wt-col:first-child > .rail-sort-head { justify-content: flex-start; }

/* Every cell but the identity block spans both rows and sits on the row's centre
   line — they are one fact each, not a title over a subtitle. */
.wp-chain-cell {
  grid-row: 1 / span 2; align-self: center; min-width: 0;
  color: var(--muted); font-size: var(--body-size);
  text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.wp-chain-coins {
  grid-column: 2; font-family: var(--num); font-variant-numeric: tabular-nums;
  color: var(--foreground);
}
.wp-chain-coins.is-dim { color: var(--muted-2); }
.wp-chain-rpc {
  grid-column: 3; display: flex; align-items: center; justify-content: flex-end; gap: 8px;
}
.wp-chain-num { font-family: var(--num); font-variant-numeric: tabular-nums; }
.wp-chain-g1 { grid-column: 4; }
.wp-chain-g2 { grid-column: 5; }
.wp-chain-g3 { grid-column: 6; }
.wp-chain-g4 { grid-column: 7; }
.wp-chain-rpc-host {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: var(--num); font-size: var(--body-size);
}
/* One dot lit: the RPC the coin in scope is actually talking to. */
.wp-chain-dot {
  flex: 0 0 auto; width: 6px; height: 6px; border-radius: 50%;
  background: var(--muted-2);
}
.wp-chain-dot.is-live { background: var(--green); box-shadow: 0 0 0 3px color-mix(in srgb, var(--green) 18%, transparent); }
/* The name reads at 14px like everything beside it; the chain id under it is the one
   thing that stays a caption, because it is a qualifier on the name and not a column
   of its own. */
.wp-chains .rail-wallet-name { font-size: var(--body-size); }
.wp-chains .rail-wallet-addr { font-size: var(--cap-size); }
/* The fold's rows are the panel's rows, so they read the same tracks. The section
   carries the rail's own top rule and nothing else. */
.wp-chain-rows > .rail-group { border-top: 1px solid var(--border); }
.wp-chain-rows > .rail-group > .rail-group-head { padding-inline: var(--act-inset); }
.wp-chains .rail-wallet-nameline > .rail-wallet-group { margin-left: 8px; }

/* ---- policy controls -------------------------------------------------------- */
/* A caption, the app's own slider and the app's own numeric box under it. Four to a
   row on a settings sheet, two on a narrow one — auto-fit rather than a fixed count,
   so the same control serves the chain sheet, the coin sheet and the Settings tab. */
/* Explicit counts, not auto-fit. On a 1248px settings card auto-fit puts FIVE of
   these in a row and orphans the sixth, and every caption is a phrase — "Transactions
   while unlocked · global only" — so the narrow track truncates the one thing that
   says what the slider does. Each sheet states how many it has room for. */
.wp-pol-grid { display: grid; gap: 18px 20px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.wp-settings .wp-pol-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.wp-chain-form .wp-pol-grid,
.wp-coin-form .wp-pol-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.wp-pol { min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.wp-pol-cap {
  color: var(--muted); font-size: var(--cap-size);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* The track takes the slack and the number keeps a fixed column, so a row of these
   line up down the sheet however wide their labels are. */
.wp-pol-row { display: flex; align-items: center; gap: 10px; }
.wp-pol-row > .act-track:not(.act-numbox) { flex: 1 1 auto; min-width: 0; }
.wp-pol-row > .act-numbox {
  flex: 0 0 78px; height: var(--control-h); box-sizing: border-box;
  border: 1px solid var(--border); background: var(--surface-2);
}
.wp-pol-row > .act-numbox > .act-num {
  width: 100%; height: 100%; box-sizing: border-box; padding: 0 8px;
  background: none; border: 0; color: var(--foreground);
  font-family: var(--num); font-size: var(--body-size); text-align: right;
  font-variant-numeric: tabular-nums;
}
.wp-pol-row > .act-numbox > .act-num:focus,
.wp-pol-row > .act-numbox > .act-num:focus-visible { outline: none; }
.wp-pol-row > .act-numbox:focus-within { border-color: var(--ring); }
/* An INHERITED field is legible but plainly not yours yet — dimmed, not hidden, so
   you can read the value you would be taking over. */
.wp-pol.is-off .wp-pol-row { opacity: .45; }
.wp-pol.is-off .act-num { cursor: default; }
.wp-pol-foot { display: flex; align-items: center; gap: 8px; min-width: 0; }
.wp-pol-note {
  min-width: 0; flex: 1 1 auto; color: var(--muted-2); font-size: var(--cap-size);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.wp-pol-note.is-on { color: var(--accent); }
.wp-pol-btn { flex: 0 0 auto; padding: 0 8px; height: 24px; font-size: var(--cap-size); }

/* ---- the two settings sheets ------------------------------------------------ */
/* Both are wider than a form dialog: a chain has five addresses to show and a coin
   has eight policy fields, and stacking either two-across turns a sheet you scan
   into a sheet you scroll. */
.sc-modal:has(.wp-chain-form) { width: min(94vw, 760px); }
.sc-modal:has(.wp-coin-form) { width: min(94vw, 860px); }
.wp-chain-form .wp-chain-addrs { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.wp-chain-form .wp-field[readonly] { color: var(--muted); cursor: default; }
.wp-chain-form .wp-field.num, .wp-coin-form .wp-field.num {
  font-family: var(--num); font-size: var(--cap-size);
}
.wp-coin-form .wp-coin-cfg { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.wp-coin-caps { margin-top: 4px; }
/* The two irreversible ones, below a rule and with the destructive one in red —
   the app's own way of saying "this is the end of the sheet, and of the coin". */
.wp-coin-danger { border-top: 1px solid var(--border); padding-top: 14px; }
.wp-coin-danger-row { display: flex; gap: 8px; margin-top: 10px; }
.wp-danger { color: var(--red); border-color: color-mix(in srgb, var(--red) 45%, var(--border)); }
.wp-danger:hover { border-color: var(--red); background: color-mix(in srgb, var(--red) 12%, transparent); }

/* ---- the Settings tab ------------------------------------------------------- */
.wp-settings {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  display: flex; flex-direction: column; gap: 8px;
}
.wp-set-card { padding: 0; gap: 0; flex: 0 0 auto; --act-inset: 20px; }
.wp-set-card > .sc-io-cap { padding-inline: var(--act-inset); }
.wp-set-body { padding: 18px var(--act-inset) 20px; display: flex; flex-direction: column; gap: 16px; }
.wp-set-lead { margin: 0; color: var(--muted); font-size: var(--body-size); line-height: 20px; }
.wp-set-identity { font-family: var(--num); font-size: var(--cap-size); line-height: 18px; }
.wp-set-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.wp-set-foot { display: flex; }
.wp-seed-list { display: flex; flex-direction: column; gap: 14px; max-height: 46vh; overflow-y: auto; }

/* ---- the Credits tab -------------------------------------------------------- */
/* The Overview's own split at the Overview's own height, so switching tabs moves the
   subject and not the furniture: one 540 card, four tiles under it. */
.wp-credits-wrap { display: contents; }
.wp-credits {
  flex: 0 0 540px; height: 540px; min-height: 0; padding: 0; gap: 0;
  display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  background: var(--background);
}
.wp-credits-main {
  min-width: 0; min-height: 0; display: flex; flex-direction: column;
  padding: 24px; gap: 0;
}
.wp-credits-rail {
  min-width: 0; min-height: 0; display: flex; flex-direction: column;
  border-left: 1px solid var(--border); background: var(--surface);
  --act-inset: 20px;
}
/* THE SWITCH IS OUT OF THE FLOW. It is 30px tall and the word beside it is 20, so a
   row holding both was 30 — and the ten pixels of nothing under "Credits" were part
   of the gap you could see but could not find in any margin. Pinned to the head's
   own top-right instead, and the caption row is exactly the caption again. */
.wp-cred-head { flex: 0 0 auto; position: relative; display: flex; flex-direction: column; gap: 0; }
.wp-cred-caprow { display: flex; align-items: flex-start; }
.wp-cred-tfbar { position: absolute; top: 0; right: 0; margin: 0; }
/* 30px. The Overview's headline is the portfolio and this one is a balance beside
   it — a notch down says which of the two the page is actually about. */
/* line-height 1, so the box IS the type. At 1.1 a 30px figure carries three pixels
   of leading above the digits that no margin can see and every eye can. */
.wp-cred-head > .act-fig-line { margin-top: 4px; align-items: baseline; }
.wp-cred-fig {
  font-family: var(--num); font-size: 30px; line-height: 1;
  color: var(--foreground); font-variant-numeric: tabular-nums;
}
/* The app's own address type — .rail-wallet-addr, middle-truncated by truncAddr, the
   way every address on this page is written. */
/* CLOSE. The address is what the number is paid into — one block, not two lines with
   a gap between them arguing about which the eye reads first. */
.wp-cred-addr { display: flex; align-items: center; gap: 6px; margin-top: 2px; min-width: 0; }
.wp-cred-addr > .rail-wallet-addr { font-size: var(--cap-size); }
.wp-cred-addr > .wcopy { flex: 0 0 auto; margin-left: 0; }
.wp-cred-acts { display: flex; gap: 8px; margin-top: 18px; }
.wp-cred-acts > .btn, .wp-cred-acts > .rail-btn {
  min-width: 118px; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
}
.wp-cred-acts svg {
  width: 14px; height: 14px; flex: 0 0 auto;
  fill: none; stroke: currentColor; stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round;
}
/* Deposit's arrow is Withdraw's, turned round — one glyph, two directions, which is
   the whole relationship between the two buttons. */
.wp-cred-dep svg { transform: rotate(180deg); }

/* The plot runs from the buttons to the floor of the card. The band that used to name
   it is gone: the switch beside the balance says which window, the axis says what the
   levels are, and the hover says what any one column holds. */
.wp-cred-chart-slot { flex: 1 1 auto; min-height: 0; display: flex; margin-top: 26px; }

/* The plot: a value gutter on the left, the columns on the right, the time axis
   under both. Levels and their labels are placed by PER CENT from the same number,
   so a line and the value naming it can never drift apart. */
.wp-cred-plot {
  flex: 1 1 auto; min-width: 0; min-height: 0;
  display: grid; grid-template-columns: 34px minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr) auto;
}
.wp-cred-yaxis { position: relative; }
.wp-cred-tick {
  position: absolute; right: 8px; transform: translateY(-50%);
  color: var(--muted-2); font-family: var(--num); font-size: 11px;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.wp-cred-plotarea { position: relative; min-width: 0; min-height: 0; }
/* BARELY VISIBLE. A gridline is there to be measured against, not looked at — at any
   more than this it competes with the columns for the same glance. */
.wp-cred-line {
  position: absolute; left: 0; right: 0; height: 1px;
  background: color-mix(in srgb, var(--border) 60%, transparent);
  pointer-events: none;
}
.wp-cred-line:last-of-type { background: var(--border); }   /* the floor is a real line */
.wp-cred-cols {
  position: absolute; inset: 0; display: flex; align-items: flex-end; gap: 0;
}
.wp-cred-col {
  flex: 1 1 0; min-width: 0; height: 100%;
  display: flex; align-items: flex-end; justify-content: center;
  cursor: default;
}
/* THE SELECTED ROW'S OWN MARK, stood up: an accent wash for the body and a 2px accent
   cap on the end you read the value off. Same relationship, same two colours — a
   column here and a chosen coin in the list say "this one" the same way.
   The wash is heavier than the row's 10%: a 12px column carries far less of it than a
   full-width row, and at 10% it disappeared. */
.wp-cred-bar {
  width: 78%; max-width: 28px; min-width: 4px;
  background: color-mix(in srgb, var(--accent) 24%, transparent);
  border-top: 2px solid var(--accent);
  box-sizing: border-box;
}
.wp-cred-bar.is-zero { background: none; border-top-color: var(--border-strong); }
/* Hovering one column dims the rest, so the tooltip's figures have an obvious owner. */
.wp-cred-cols.is-hover .wp-cred-col:not(.is-on) .wp-cred-bar { opacity: .35; }
.wp-cred-col .wp-cred-bar { transition: opacity .12s; }
.wp-cred-col.is-on .wp-cred-bar { background: color-mix(in srgb, var(--accent) 38%, transparent); }

/* WIDTH FROM THE CONTENT. A fixed 150 was narrower than "Received  0.0382 ETH", so
   the longest row — the one you most want to read — wrapped its unit onto a line of
   its own. max-content plus nowrap: the box fits the widest row it holds, whatever
   that turns out to be. */
.wp-cred-chip {
  position: absolute; top: 8px; z-index: 2; pointer-events: none;
  width: max-content; max-width: 60%; padding: 8px 10px;
  background: var(--float); border: 1px solid var(--border);
  opacity: 0; transform: translateX(10px); transition: opacity .1s;
}
.wp-cred-chip-row > span { white-space: nowrap; }
.wp-cred-chip.is-on { opacity: 1; }
.wp-cred-chip.is-right { transform: translateX(calc(-100% - 10px)); }
.wp-cred-chip-when { color: var(--foreground); font-size: var(--cap-size); margin-bottom: 6px; }
.wp-cred-chip-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  font-size: var(--cap-size); line-height: 17px;
}
.wp-cred-chip-key { color: var(--muted-2); }
.wp-cred-chip-val { font-family: var(--num); color: var(--muted); font-variant-numeric: tabular-nums; }
.wp-cred-chip-vol .wp-cred-chip-val { color: var(--foreground); }
.wp-cred-chip-buy .wp-cred-chip-key { color: var(--green); }
.wp-cred-chip-sell .wp-cred-chip-key { color: var(--red); }

.wp-cred-axis {
  display: flex; justify-content: space-between; padding-top: 10px;
  color: var(--muted-2); font-size: var(--cap-size);
}
.wp-credits-rail > .sc-io-cap { flex: 0 0 auto; padding-inline: var(--act-inset); }
.wp-cred-head-row, .wp-cred-row {
  display: grid; grid-template-columns: minmax(0, 1.05fr) 46px minmax(0, 1fr) minmax(0, 1fr);
  column-gap: 12px; align-items: center; padding-inline: var(--act-inset);
}
.wp-cred-head-row > .act-wt-col:nth-child(n + 3) { text-align: right; }
.wp-cred-rows { flex: 1 1 auto; min-height: 0; overflow-y: auto; background: var(--rail); }
/* 68px — the height a row is EVERYWHERE in this app, and the height of the wallet
   rows this list sits beside. */
.wp-cred-row {
  min-height: 68px; border-bottom: 1px solid var(--border);
  font-size: var(--body-size);
}
.wp-cred-row:hover { background: var(--surface); }
/* The stamp stays a caption: it is the one column that qualifies the row rather than
   stating a value in it. */
.wp-cred-time {
  color: var(--muted); font-size: var(--cap-size); font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.wp-cred-act { font-size: var(--body-size); }
.wp-cred-act.is-buy { color: var(--green); }
.wp-cred-act.is-sell { color: var(--red); }
.wp-cred-who {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  text-align: right; color: var(--foreground);
}
.wp-cred-amt { text-align: right; font-family: var(--num); color: var(--foreground); font-variant-numeric: tabular-nums; }

/* ---- the Referral tab ------------------------------------------------------- */
/* Stacked cards on the page's own 8px rhythm, scrolling as one column — this is the
   one tab with more in it than a screen. */
.wp-referral {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  display: flex; flex-direction: column; gap: 8px;
}
.wp-ref-stats { flex: 0 0 auto; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.wp-ref-stat {
  display: flex; flex-direction: column; gap: 0; padding: 20px;
  --act-inset: 20px;
}
.wp-ref-stat-top { display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 16px; }
/* THE ACCENT TILE. The reference puts each icon on a filled square; the app's accent
   is the colour it already uses to say "this one", so the square is that. */
.wp-ref-ico {
  display: grid; place-items: center; width: 34px; height: 34px; flex: 0 0 auto;
  background: var(--accent); color: #fff;
}
.wp-ref-ico svg {
  width: 17px; height: 17px; fill: none; stroke: currentColor;
  stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round;
}
/* Drawn at the same 1.5px weight as every other icon in the app, so the mark in the
   corner belongs to the same set as the one on the tile. */
.wp-ref-info {
  flex: 0 0 auto; display: grid; place-items: center; width: 16px; height: 16px;
  color: var(--muted-2); cursor: help;
}
.wp-ref-info svg {
  width: 16px; height: 16px; fill: none; stroke: currentColor;
  stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round;
}
.wp-ref-info:hover { color: var(--foreground); }
.wp-ref-fig {
  margin-top: 6px; font-family: var(--num); font-size: 26px; line-height: 1.15;
  color: var(--foreground); font-variant-numeric: tabular-nums;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.wp-ref-card { flex: 0 0 auto; padding: 0; gap: 0; --act-inset: 20px; }
.wp-ref-card > .sc-io-cap { padding-inline: var(--act-inset); }
.wp-ref-set { margin-left: auto; }
.wp-ref-body { padding: 18px var(--act-inset) 20px; display: flex; flex-direction: column; gap: 14px; }

/* The labelled box both fields sit in: a caption, the control, and one line saying
   what it costs you to get it wrong. */
.wp-ref-field {
  display: flex; flex-direction: column; gap: 8px;
  padding: 14px 16px; background: var(--surface-2); border: 1px solid var(--border);
}
.wp-ref-field-cap { color: var(--muted); font-size: var(--cap-size); }
.wp-ref-field-row { display: flex; align-items: stretch; gap: 8px; min-width: 0; }
.wp-ref-hint { margin: 0; color: var(--muted-2); font-size: var(--cap-size); line-height: 17px; }

/* The link reads as one string with the half that is yours picked out — an accent
   bar down the left edge, the way the app marks the row you have chosen. */
.wp-ref-link {
  flex: 1 1 auto; min-width: 0; display: flex; align-items: center;
  padding: 0 12px; height: var(--control-h);
  background: var(--surface); border: 1px solid var(--border);
  box-shadow: inset 2px 0 0 var(--accent);
  font-family: var(--num); font-size: var(--body-size);
  overflow: hidden; white-space: nowrap;
}
.wp-ref-link-base { color: var(--muted-2); }
.wp-ref-link-code { color: var(--accent); }
.wp-ref-copy {
  flex: 0 0 auto; height: var(--control-h);
  display: inline-flex; align-items: center; gap: 8px;
}
.wp-ref-copy svg {
  width: 14px; height: 14px; fill: none; stroke: currentColor;
  stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round;
}
.wp-ref-addr {
  flex: 1 1 auto; min-width: 0; display: flex; align-items: center;
  padding: 0 12px; height: var(--control-h);
  background: var(--surface); border: 1px solid var(--border);
  box-shadow: inset 2px 0 0 var(--accent);
  font-family: var(--num); font-size: var(--body-size); color: var(--foreground);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.wp-ref-field-row > .wcopy { flex: 0 0 auto; align-self: center; margin-left: 0; }

.wp-ref-steps, .wp-ref-tiers {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px;
}
.wp-ref-step { min-width: 0; }
/* A SQUARE, not a tag: three of these stand in a row across the card, and equal
   boxes read as a sequence where boxes sized to their own digit read as three
   unrelated labels. */
.wp-ref-step-n {
  display: grid; place-items: center; width: 26px; height: 26px; margin-bottom: 14px;
  background: var(--accent); color: #fff;
  font-family: var(--num); font-size: var(--cap-size); font-weight: 500; line-height: 1;
}
.wp-ref-step-title { color: var(--foreground); font-size: var(--body-size); margin-bottom: 6px; }
.wp-ref-step-lead { margin: 0; color: var(--muted); font-size: var(--body-size); line-height: 20px; }

/* Hairline-divided, so the three read as one table of terms rather than three cards
   that happen to be side by side. */
.wp-ref-tiers { gap: 0; }
.wp-ref-tier {
  min-width: 0; padding: 0 24px;
  display: flex; flex-direction: column;
  border-left: 1px solid var(--border);
}
.wp-ref-tier:first-child { padding-left: 0; border-left: 0; }
.wp-ref-tier-title { color: var(--foreground); font-size: var(--body-size); margin-bottom: 6px; }
.wp-ref-tier-lead { margin: 0; color: var(--muted); font-size: var(--body-size); line-height: 20px; }
/* ON THE FLOOR. One of the three carries an "Up to" above it, so figures aligned to
   the top of their own block sat at three different heights — the number is what you
   compare, so the numbers are what line up. */
.wp-ref-tiers { align-items: stretch; }
.wp-ref-tier-figwrap { margin-top: auto; padding-top: 22px; display: flex; flex-direction: column; }
.wp-ref-tier-lead-in { color: var(--muted-2); font-family: var(--num); font-size: var(--cap-size); }
.wp-ref-tier-fig {
  font-family: var(--num); font-size: 40px; line-height: 1.05; color: var(--foreground);
  font-variant-numeric: tabular-nums;
}

/* ---- sessions, behind glass ------------------------------------------------- */
/* The stage is what this tab will look like; the veil is what it says until then.
   Two layers, one box — the blur is on the stage so the message stays sharp. */
.wp-sessions {
  flex: 1 1 auto; min-height: 0;
  position: relative; overflow: hidden; padding: 0; gap: 0;
  --act-inset: 20px;
}
.wp-sessions-stage {
  position: absolute; inset: 0; padding: 32px var(--act-inset);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 28px;
  filter: blur(6px) saturate(.75); opacity: .62;
  pointer-events: none; user-select: none;
}
.wp-sessions-qr { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.wp-sessions-qr-note { color: var(--muted); font-size: var(--cap-size); }
.wp-qr { padding: 10px; background: var(--foreground); }
.wp-qr-grid { display: grid; width: 132px; aspect-ratio: 1; gap: 0; }
.wp-qr-cell { background: transparent; }
.wp-qr-cell.on { background: var(--background); }
.wp-sessions-stage .act-cards { width: min(100%, 720px); grid-template-columns: repeat(3, minmax(0, 1fr)); }
.wp-sessions-stage .act-card { --act-card-pad-y: 18px; }
.wp-sessions-stage .act-spark { height: 40px; margin-top: 10px; }

.wp-sessions-veil {
  position: relative; height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 24px; text-align: center;
  /* A SCRIM, not a flat wash: the message has to stay legible over the brightest
     thing behind it (the QR's white quiet zone) without hiding the shape that makes
     the panel worth looking through in the first place. */
  background: radial-gradient(ellipse 42% 30% at 50% 50%,
    color-mix(in srgb, var(--background) 90%, transparent) 0%,
    color-mix(in srgb, var(--background) 60%, transparent) 60%,
    transparent 100%);
}
.wp-sessions-veil .wp-soon-lead { max-width: 42ch; }
.wp-sessions-mark {
  display: grid; place-items: center; width: 40px; height: 40px; margin-bottom: 2px;
  border: 1px solid var(--border-strong); color: var(--muted);
}
.wp-sessions-mark svg {
  width: 18px; height: 18px; fill: none; stroke: currentColor;
  stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round;
}

/* ---- the pen ---------------------------------------------------------------- */
/* The dot that draws the sparkline. An HTML element, not a <circle>: the svg is
   `preserveAspectRatio: none`, so anything round drawn inside it comes out an
   ellipse — this sits in .act-spark's own positioned box and is placed in per-cent
   of it. It inherits the trace's colour from the tile, and it leaves when the trace
   reaches the current value, which is the only moment it has nothing left to say. */
.wp-spark-pen {
  position: absolute; width: 5px; height: 5px; margin: -2.5px 0 0 -2.5px;
  border-radius: 50%; background: currentColor; color: inherit;
  pointer-events: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 22%, transparent);
}
.wp-spark-pen.is-done { opacity: 0; transition: opacity .3s ease; }
/* Scripted motion answers to the same switch as every transition in the app: the
   two draw-ins check this in JS and hand back a finished chart instead. */
@media (prefers-reduced-motion: reduce) {
  .wp-spark-pen { display: none; }
}
