/* B20MINER design system, "sade" (design-system/b20.css). One file for every B20MINER site:
   tokens (light and dark), type, focus, the header, buttons, fields, tags, tiles, the side panel,
   toasts, loading skeletons, the skip link and the phone tab bar.
   Source of truth: design-system/b20.css. Sites get a copy from design-system/sync.mjs; never edit a copy.
   Each site links it first and keeps only its own styles after it (Launchpad: launchpad.css).
   Theme: <html data-theme="light|dark">, set before paint by theme.js (the device's theme, or the saved choice).
   Rules that come from the audits (contrast, 24 px touch areas, skip link) are explained in README.md. */
:root {
  /* Brand Kit 2.3 palette. Azure carries the primary action with #171717 ink
     (6.09:1); it is never small text on the light ground (2.79:1). */
  --azure: #149DF2;
  --azure-soft: #E1ECFE;
  /* Azure as small text (links, labels): dark enough on the light ground (5.8:1 on white). */
  --azure-text: #0A6AA8;
  --bg: #F6F9FD;
  --surface: #FFFFFF;
  --bg-2: #EDF2F9;
  --line: #DCE3EE;
  --text: #171717;
  /* Light secondary text is clearly darker than tertiary (audit F6, 7 Nov 2026): 8.5:1 vs 5.2:1 on the page,
     close to the dark theme's 9.4:1 vs 5.7:1. */
  --text-2: #434a55;
  --text-3: #626a76;
  --primary: #149DF2;
  --primary-text: #171717;
  --primary-hover: #3aaef5;
  --selected: #E1ECFE;
  --band: url("brand/ice-flow.svg");
  /* Accent colours come in two kinds (light theme audit, 7 Nov 2026, docs/LIGHT_THEME_AUDIT_V1.md):
     --warn / --trade / --up / --down are TEXT colours, darkened in light so small text reads (5.6:1+).
     --*-fill are for anything that is not text: bars, dots, glows, rings, filled buttons. In light they stay the
     brand's bright hue instead of turning brown or forest green. Ink on a fill is --fill-ink (#171717), as on
     the primary button: 7.5:1 on warn, 5.6:1 on trade, 4.9:1 on down. Never use a text colour as a fill.
     Brand colour rule (owner, 8 Nov 2026, as o1): azure carries the action and the brand accents, ink and white
     everything else. Amber is no brand colour: --warn is "needs your attention" and nothing more (same values as
     the old --mine, which is gone from every site and from here). */
  --warn: #955400;
  --warn-fill: #E8962A;
  --warn-soft: #fbf1e3;
  --trade: #157347;
  --trade-fill: #2FA36B;
  --trade-soft: #e8f4ed;
  --down-soft: #fbe9e7;
  --up: #157347;
  --down: #c0352b;
  --down-fill: #E5574B;
  --fill-ink: #171717;
  --focus: #0b7fc7;
  /* IBM Plex: the brand kit's own family. Sans for words and figures,
     Mono only for chain data (block heights, hashes, addresses). */
  --font: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --ease: cubic-bezier(.16, 1, .3, 1);
  --page: 1540px;
  /* The page edge clears an iPhone's notch and rounded corners when the phone is on its side (pages use
     viewport-fit=cover; mobile audit M7, 7 Nov 2026). */
  --gutter: max(32px, env(safe-area-inset-left), env(safe-area-inset-right));
  --r: 8px;
  /* Brand consistency V1 (owner, 8 Nov 2026, docs/BRAND_CONSISTENCY_RESEARCH_V1.md Ö6): one radius ladder for both
     apps. 6 info tag (New, Mined, 2×), 8 tool button and row, 12 inner box, 16 card and swap box, 20 large card,
     pill for every action button, filter chip, quick-amount chip and search field. Anything else snaps to the nearest step. */
  --r-xs: 6px;
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-xl: 20px;
  --r-pill: 999px;
  /* Ö3 + Ö9: green means money direction only (buy, up, money in). Open / live / active is azure; done is ink. */
  --live: var(--azure-text);
  --live-fill: var(--azure);
  --live-soft: var(--selected);
  --done: var(--text);
}
[data-theme="dark"] {
  --bg: #0A0D11;
  --surface: #171B21;
  --bg-2: #171B21;
  --line: #2A3038;
  --text: #FFFFFF;
  --text-2: #B0B4BC;
  --text-3: #868B94;
  --primary: #149DF2;
  --primary-text: #171717;
  --primary-hover: #3aaef5;
  --selected: rgba(20, 157, 242, 0.16);
  --band: url("night-halo-page.svg");
  --warn: #f0a945;
  --warn-fill: #f0a945;
  --warn-soft: rgba(240, 169, 69, 0.12);
  --trade: #4cc488;
  --trade-fill: #4cc488;
  --trade-soft: rgba(76, 196, 136, 0.12);
  --down-soft: rgba(240, 112, 95, 0.14);
  --up: #4cc488;
  --down: #f0705f;
  --down-fill: #f0705f;
  --fill-ink: #0B0B0C;
  --focus: #E1ECFE;
  --azure-text: #149DF2;
}
/* IBM Plex, self-hosted (the sites allow fonts only from themselves): Fontsource 5.3.0 WOFF2, OFL
   (fonts/LICENSE-*.txt). Latin always; Latin Extended (ğ, ş, ı, İ…) only when such a letter is on the page. */
@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: 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: 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: 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: 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 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: 700; font-display: swap; src: url(fonts/ibm-plex-sans-latin-700-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: 700; font-display: swap; src: url(fonts/ibm-plex-sans-latin-ext-700-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: 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: 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; }
@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; }
* { box-sizing: border-box; }
/* No grey flash on tap (mobile audit M9, 7 Nov 2026); focus rings stay. */
html { background: var(--bg); -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: transparent; }
body { margin: 0; background: var(--bg); color: var(--text); font-family: var(--font); font-size: 15px; line-height: 1.5; font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; -webkit-font-smoothing: antialiased; caret-color: var(--primary); }
/* No visible scrollbars anywhere (owner, 15 Oct 2026). */
* { scrollbar-width: none; }
*::-webkit-scrollbar { display: none; }
.mono { font-family: var(--mono); font-size: 0.92em; letter-spacing: -0.01em; }
[data-theme="light"] { color-scheme: light; }
[data-theme="dark"] { color-scheme: dark; }
/* While the theme switches, nothing fades: theme.js sets this class for two frames, so a button never shows
   one theme's fill under the other theme's text (light theme audit L3, 7 Nov 2026). */
.theme-switching, .theme-switching *, .theme-switching *::before, .theme-switching *::after { transition: none !important; }
::selection { background: var(--azure-soft); color: #171717; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 4px; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; cursor: pointer; }
.wrap { max-width: var(--page); margin: 0 auto; padding: 0 var(--gutter); }

/* Header */
header.top { position: sticky; top: 0; z-index: 10; background: var(--bg); border-bottom: 1px solid var(--line); }
.top .wrap { display: flex; align-items: center; gap: 32px; height: 60px; }
/* Brand Kit 2.3: the official horizontal logo at its 160px floor, the
   symbol alone where space is small; the product name in IBM Plex Sans Medium. */
.brand { display: flex; align-items: center; gap: 10px; flex-shrink: 0; color: var(--text); }
.brand i { display: block; background: currentColor; }
.brand .logo { width: 160px; height: 48px; -webkit-mask: url(brand/horizontal.svg) center / contain no-repeat; mask: url(brand/horizontal.svg) center / contain no-repeat; }
.brand .sym { display: none; width: 26px; height: 26px; -webkit-mask: url(brand/symbol.svg) center / contain no-repeat; mask: url(brand/symbol.svg) center / contain no-repeat; }
.brand span { padding-left: 10px; border-left: 1px solid var(--line); font: 500 15px/18px "IBM Plex Sans", var(--font); color: var(--text-2); }
nav.main { display: flex; gap: 4px; }
nav.main a { padding: 6px 10px; border-radius: 6px; font-size: 14.5px; font-weight: 500; color: var(--text-2); }
@media (hover: hover) and (pointer: fine) { nav.main a:hover { color: var(--text); background: var(--bg-2); } }
nav.main a[aria-current] { color: var(--text); background: var(--selected); }
.search { display: flex; align-items: center; gap: 8px; flex: 1; max-width: 320px; height: 36px; padding: 0 12px; border: 1px solid var(--line); border-radius: var(--r-pill); color: var(--text-3); font-size: 14px; white-space: nowrap; overflow: hidden; cursor: text; }
.search:focus-within { border-color: var(--azure); }
.search input { flex: 1; min-width: 0; height: 100%; border: 0; padding: 0; background: none; font: inherit; color: var(--text); outline: none; }
.search input::placeholder { color: var(--text-3); }
.search input::-webkit-search-cancel-button { cursor: pointer; }
/* Search matches inside names and tickers. */
mark { background: var(--selected); color: inherit; border-radius: 3px; box-shadow: 0 0 0 1px var(--selected); }
.right { margin-left: auto; display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.net { font-size: 13px; color: var(--text-2); display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.net i { width: 7px; height: 7px; border-radius: 50%; background: var(--live-fill); }
.net.late i { background: var(--warn-fill); }
.net.late { color: var(--warn); }
.btn { display: inline-flex; align-items: center; justify-content: center; height: 36px; padding: 0 16px; border-radius: var(--r-pill); border: 1px solid var(--line); background: var(--surface); font-size: 14px; font-weight: 600; white-space: nowrap; transition: background-color 120ms, border-color 120ms, transform 120ms var(--ease); }
@media (hover: hover) and (pointer: fine) { .btn:hover { background: var(--bg-2); } }
/* Every button answers a press (1 Nov 2026, docs/DESIGN_AI_PATTERNS_PLAN_V1.md §7 N1). */
.btn:active:not(:disabled) { transform: scale(.97); }
.btn.primary { background: var(--primary); border-color: var(--primary); color: var(--primary-text); }
@media (hover: hover) and (pointer: fine) { .btn.primary:hover { background: var(--primary-hover); border-color: var(--primary-hover); } }
.btn.lg { height: 48px; padding: 0 22px; font-size: 15px; }
/* The big action (swap, mine plan, claim): 56 px pill, the one shape the owner chose for the swap card (3.407). */
.btn.xl { height: 56px; padding: 0 24px; font-size: 16px; }
.short { display: none; }
.icon { display: inline-grid; place-items: center; width: 36px; height: 36px; border: 1px solid var(--line); border-radius: var(--r-pill); background: var(--bg); color: var(--text-2); }
@media (hover: hover) and (pointer: fine) { .icon:hover { color: var(--text); background: var(--bg-2); } }
.icon:active:not(:disabled) { color: var(--text); background: var(--bg-2); }
.icon .sun { display: none; }
[data-theme="dark"] .icon .sun { display: block; }
[data-theme="dark"] .icon .moon { display: none; }
.live { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--text-2); }
.live i { position: relative; width: 7px; height: 7px; border-radius: 50%; background: var(--live-fill); }
.live i::after { content: ""; position: absolute; inset: 0; border-radius: 50%; background: var(--live-fill); animation: pulse 2.4s var(--ease) infinite; }
@keyframes pulse { 0% { transform: scale(1); opacity: .45; } 70%, 100% { transform: scale(3); opacity: 0; } }
.tag { display: inline-flex; align-items: center; gap: 5px; height: 22px; padding: 0 8px; border-radius: var(--r-xs); font-size: 12px; font-weight: 500; } /* Ö8: info tags are 6px neutral-shaped chips; status pills set their own pill radius */
.sub { display: block; font-size: 12.5px; color: var(--text-3); }
.av { --h: 205; width: 40px; height: 40px; border-radius: 28%; flex-shrink: 0; display: grid; place-items: center; overflow: hidden; font-size: 16px; font-weight: 600; color: hsl(var(--h) 60% 24%); background: linear-gradient(145deg, hsl(var(--h) 90% 93%), hsl(calc(var(--h) + 28) 75% 82%)); box-shadow: inset 0 0 0 1px rgba(0,0,0,.06); }
.av { position: relative; }
.av img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
:root[data-theme="dark"] .av { color: hsl(var(--h) 70% 82%); background: linear-gradient(145deg, hsl(var(--h) 35% 24%), hsl(calc(var(--h) + 28) 40% 16%)); box-shadow: inset 0 0 0 1px rgba(255,255,255,.07); }
.sub b { font-weight: 600; color: var(--text-2); }
.sub .ok { color: var(--done); }
.up { color: var(--up); }
.down { color: var(--down); }

.tabbar { display: none; }
@media (max-width: 1240px) {
  .brand .logo { display: none; }
  .brand .sym { display: block; }
  .search { flex: none; width: 36px; padding: 0; justify-content: center; transition: width 160ms var(--ease); }
  .search input { flex: 0; width: 0; }
  .search:focus-within, .search.has-q { width: 220px; padding: 0 12px; justify-content: flex-start; }
  .search:focus-within input, .search.has-q input { flex: 1; }
}
@media (max-width: 1080px) {
  .net span { display: none; }
}
@media (max-width: 860px) {
  :root { --gutter: max(16px, env(safe-area-inset-left), env(safe-area-inset-right)); }
  nav.main, .search { display: none; }
  .right { gap: 8px; }
  .long { display: none; }
  .short { display: inline; }
  .top .wrap { height: 56px; }
  main { padding-bottom: calc(58px + env(safe-area-inset-bottom)); }
  .tabbar { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); position: fixed; left: 0; right: 0; bottom: 0; z-index: 20; height: calc(58px + env(safe-area-inset-bottom)); padding-bottom: env(safe-area-inset-bottom); background: var(--bg); border-top: 1px solid var(--line); }
  .tabbar a { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; font-size: 11.5px; font-weight: 500; color: var(--text-3); }
  .tabbar { padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); }
  /* iOS zooms the page into a field under 16px and does not zoom back (mobile audit M2). :where() keeps this at
     zero specificity: it only lifts fields no site has sized. */
  :where(input:not([type=checkbox], [type=radio], [type=range], [type=file]), select, textarea) { font-size: 16px; }
  .panel .inp input, .panel .fld textarea { font-size: 16px; }
  .tabbar a[aria-current] { color: var(--text); font-weight: 600; }
}
/* Phone held sideways (mobile audit M3): the screen is about 375 px tall, so the fixed bars took half of it.
   The header scrolls away with the page and the tab bar keeps its icons only at 44 px (the links keep their
   names for screen readers). Sites with a dock above the tab bar move it down to 44 px themselves. */
@media (max-width: 860px) and (max-height: 500px) and (orientation: landscape) {
  header.top { position: relative; }
  main { padding-bottom: calc(44px + env(safe-area-inset-bottom)); }
  .tabbar { height: calc(44px + env(safe-area-inset-bottom)); }
  .tabbar a { gap: 0; font-size: 0; }
}
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ---- Shell (shell.js) ---- */
.link { padding: 0; border: 0; background: none; font: inherit; font-size: 13.5px; font-weight: 600; color: var(--text-2); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--line); }
@media (hover: hover) and (pointer: fine) { .link:hover { color: var(--text); text-decoration-color: currentColor; } }
.btn.sm { height: 32px; padding: 0 14px; font-size: 13.5px; }
body.locked { overflow: hidden; }

/* The wallet button: Connect while not connected; the wallet's mark and short address once it is. */
#connect { position: relative; gap: 8px; }
#connect .wm { width: 18px; height: 18px; }
/* Alerts: a dot on the wallet button while something new waits in the wallet panel. */
.ndot { position: absolute; top: -4px; right: -4px; width: 11px; height: 11px; border-radius: 50%; background: var(--warn-fill); box-shadow: 0 0 0 2px var(--bg); }

/* A wallet's colour mark (or its picture), the same everywhere. */
.mark { --h: 205; display: inline-block; border-radius: 50%; flex-shrink: 0; overflow: hidden; background: conic-gradient(from 90deg, hsl(var(--h) 70% 60%), hsl(calc(var(--h) + 80) 70% 55%), hsl(calc(var(--h) + 160) 65% 58%), hsl(var(--h) 70% 60%)); box-shadow: inset 0 0 0 1px rgba(0,0,0,.08); }
.mark img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* Short messages at the bottom; they say what just happened and go. */
.toast { position: fixed; left: 50%; bottom: 64px; z-index: 70; transform: translate(-50%, 12px); opacity: 0; padding: 10px 16px; border-radius: 10px; background: var(--text); color: var(--bg); font-size: 13.5px; font-weight: 500; transition: opacity 200ms, transform 200ms var(--ease); pointer-events: none; max-width: calc(100vw - 32px); }
.toast.on { opacity: 1; transform: translate(-50%, 0); }

/* The side panel: the wallet, and a page's forms (edit the profile, withdraw). From the right on a wide
   screen, from the bottom on a phone; Esc, the backdrop or × closes it. */
.scrim { position: fixed; inset: 0; z-index: 50; background: rgba(10, 14, 20, .38); opacity: 0; transition: opacity 200ms var(--ease); }
.scrim.on { opacity: 1; }
.scrim[hidden] { display: none; }
.scrim.for-panel { z-index: 60; }
.panel { position: fixed; top: 0; right: 0; bottom: 0; z-index: 61; width: min(460px, 100vw); display: flex; flex-direction: column; background: var(--surface); border-left: 1px solid var(--line); box-shadow: -12px 0 40px rgba(0,0,0,.14); transform: translateX(100%); transition: transform 260ms var(--ease); }
.panel.on { transform: none; }
.panel[hidden] { display: none; }
.panel h2 { margin: 0; }
.panel .phead { display: flex; align-items: center; gap: 12px; padding: 16px 20px; border-bottom: 1px solid var(--line); }
.panel .phead .mark { width: 36px; height: 36px; }
.panel .phead h2 { font-size: 18px; font-weight: 600; }
.panel .phead p { margin: 2px 0 0; font-size: 13px; color: var(--text-2); }
.panel .x { margin-left: auto; flex-shrink: 0; }
.panel .pbody { flex: 1; overflow-y: auto; padding: 4px 20px 24px; }
.panel .pfoot { display: flex; gap: 8px; padding: 14px 20px calc(14px + env(safe-area-inset-bottom)); border-top: 1px solid var(--line); }
.panel .pfoot .btn { flex: 1; height: 42px; }
.panel .pfoot .btn[disabled] { opacity: .55; cursor: not-allowed; }
.panel .pfoot .btn.primary[disabled] { cursor: progress; }
.panel .big { padding: 20px 0 8px; }
.panel .big b { display: block; font-size: 30px; font-weight: 600; letter-spacing: -0.01em; }
.panel .big span { font-size: 13.5px; color: var(--text-2); }
.panel .pnote { margin: 20px 0 0; padding: 12px 14px; border-radius: 10px; background: var(--bg-2); font-size: 13px; line-height: 1.5; color: var(--text-2); }
.panel .warn { margin: 16px 0 0; padding: 12px 14px; border-radius: 10px; background: var(--warn-soft); font-size: 13.5px; line-height: 1.5; color: var(--text); }
.panel .warn b { color: var(--warn); }
/* Forms in the panel. */
.panel .fld { display: block; margin-top: 16px; }
.panel .fld > span { display: flex; justify-content: space-between; gap: 8px; margin-bottom: 6px; font-size: 13px; font-weight: 600; color: var(--text-2); }
.panel .fld > span em { font-style: normal; font-weight: 500; color: var(--text-3); font-variant-numeric: tabular-nums; }
.panel .fld > span em.over { color: var(--down); }
.panel .inp { display: flex; align-items: center; height: 40px; border: 1px solid var(--line); border-radius: var(--r); background: var(--bg); overflow: hidden; }
.panel .inp:focus-within { border-color: var(--azure); }
.panel .inp i { padding-left: 12px; font-style: normal; font-size: 14px; color: var(--text-3); white-space: nowrap; }
.panel .inp input { flex: 1; min-width: 0; height: 100%; padding: 0 12px 0 1px; border: 0; background: none; font: inherit; font-size: 14px; color: var(--text); outline: none; }
.panel .inp input:first-child { padding-left: 12px; }
.panel .fld textarea { display: block; width: 100%; min-height: 96px; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--r); background: var(--bg); font: inherit; font-size: 14px; line-height: 1.5; color: var(--text); resize: vertical; outline: none; }
.panel .fld textarea:focus { border-color: var(--azure); }
.panel .fld .err { display: block; margin-top: 6px; font-size: 12.5px; font-weight: 500; color: var(--down); }
.panel .fld .err:empty { display: none; }
.panel .fld.bad .inp, .panel .fld.bad textarea { border-color: var(--down-fill); }
.panel .pic { display: flex; align-items: center; gap: 14px; margin-top: 18px; }
.panel .pic .mark { width: 64px; height: 64px; }
.panel .pic .row { display: flex; gap: 6px; flex-wrap: wrap; }
.panel .pic .btn[hidden] { display: none; }
.panel .pic small { display: block; margin-top: 6px; font-size: 12.5px; color: var(--text-3); }
.panel .pic .err { display: block; margin-top: 6px; font-size: 12.5px; font-weight: 500; color: var(--down); }
.panel .pic .err:empty { display: none; }
/* The wallet: what it holds, what it did lately, and what is new. */
.panel .seg { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; margin: 14px 0 4px; padding: 4px; border-radius: 10px; background: var(--bg-2); }
.panel .seg button { height: 32px; border: 0; border-radius: 7px; background: none; font: inherit; font-size: 13.5px; font-weight: 600; color: var(--text-2); }
.panel .seg button[aria-selected="true"] { background: var(--surface); color: var(--text); box-shadow: 0 1px 2px rgba(0,0,0,.08), inset 0 0 0 1px var(--line); }
.panel .wrow { display: grid; grid-template-columns: 36px minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 11px 0; border-bottom: 1px solid var(--line); }
.panel .wrow .av { width: 36px; height: 36px; font-size: 14px; border-radius: 10px; }
.panel .wrow .av.eth { --h: 220; }
.panel .wrow .av.mwv { color: var(--azure-text); background: var(--selected); }
.panel .wrow .nm, .panel .wrow .val { min-width: 0; }
.panel .wrow .nm b, .panel .wrow .val b { display: block; font-size: 14px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.panel .wrow .nm span, .panel .wrow .val span { display: block; font-size: 12.5px; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.panel .wrow .val { text-align: right; }
.panel .wrow .link { font-size: 12.5px; }
.panel button.wrow, .panel a.wrow { width: 100%; border: 0; border-bottom: 1px solid var(--line); background: none; font: inherit; color: inherit; text-align: left; }
@media (hover: hover) and (pointer: fine) { .panel button.wrow:hover .nm b, .panel a.wrow:hover .nm b { text-decoration: underline; text-underline-offset: 3px; } }
.panel .wday { padding: 16px 0 2px; font-size: 12.5px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-3); }
.panel .wmore { display: flex; justify-content: center; padding: 16px 0 0; }
.panel .alerts a { display: grid; grid-template-columns: 8px minmax(0, 1fr) auto; gap: 12px; align-items: start; padding: 12px 0; border-bottom: 1px solid var(--line); }
.panel .alerts i { width: 8px; height: 8px; margin-top: 7px; border-radius: 50%; background: var(--line); }
.panel .alerts .fresh i { background: var(--k, var(--warn-fill)); }
.panel .alerts b { display: block; font-size: 14px; font-weight: 600; }
.panel .alerts a:not(.fresh) b { font-weight: 500; color: var(--text-2); }
.panel .alerts span { display: block; margin-top: 1px; font-size: 12.5px; line-height: 1.45; color: var(--text-3); }
.panel .alerts time { font-size: 12.5px; color: var(--text-3); white-space: nowrap; }
@media (hover: hover) and (pointer: fine) { .panel .alerts a:hover b { text-decoration: underline; text-underline-offset: 3px; } }


@media (max-width: 860px) {
  #connect .wm { display: none; }
  .toast { bottom: 132px; }
  .panel { top: auto; left: 0; width: 100%; max-height: 92vh; border-left: 0; border-top: 1px solid var(--line); border-radius: 16px 16px 0 0; box-shadow: 0 -12px 40px rgba(0,0,0,.14); transform: translateY(100%); }
  .panel { max-height: 92dvh; padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); } /* M10, M7 */
  .panel .phead, .panel .pbody, .panel .pfoot { padding-left: 16px; padding-right: 16px; }
}
@media (prefers-reduced-motion: reduce) { .toast, .panel, .scrim { transition: none !important; } }
/* Wallet names: the name first, the short address always beside it (a name can be copied, an address cannot). */
.wn { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 14ch; font-family: var(--font); font-weight: 600; color: var(--text); }
.wa { font-family: var(--mono); color: var(--text-3); font-weight: 400; }
.wn + .wa { font-size: .92em; }

/* Loading: grey bars the shape of what comes, one slow shimmer. Same on every page; still with reduced motion. */
.sk, .sk.av { display: inline-block; vertical-align: middle; max-width: 100%; border-radius: 4px; background: linear-gradient(90deg, var(--bg-2) 0 40%, color-mix(in srgb, var(--bg-2) 92%, var(--text)) 50%, var(--bg-2) 60% 100%) 0 0 / 300% 100%; animation: sk 1.6s linear infinite; }
.sk.av { width: 40px; height: 40px; border-radius: 28%; box-shadow: none; }
.sk.round { border-radius: 50%; }
.sk-lines { display: grid; gap: 6px; min-width: 0; }
@media (max-width: 860px) { .sk.wide { display: none; } }
@keyframes sk { from { background-position: 100% 0; } to { background-position: 0 0; } }
@media (prefers-reduced-motion: reduce) { .sk { animation: none; } }

/* ---- Design step 5: final audit ---- */
/* Phones: text links in crumbs, wallet names, block facts and card footers get a 24 px tall touch area
   (WCAG 2.5.8) without moving anything: the padding is taken back by a negative margin. */
@media (max-width: 860px) {
  :is(.crumbs a, a.who, a.back, a.hgt, dd a, td a, footer a, button.link):not(.btn, .go, .copy, .ext) { padding-block: 3px; margin-block: -3px; }
}
/* Skip link (theme.js): hidden until focused, then a small button at the top left. It sits far enough
   above the page that its shadow does not show either. */
.skip { position: fixed; left: 12px; top: 8px; z-index: 100; padding: 8px 14px; border-radius: 6px; background: var(--surface); color: var(--text); font-weight: 600; font-size: 14px; box-shadow: 0 0 0 1px var(--line), 0 6px 20px rgba(0, 0, 0, .25); transform: translateY(calc(-100% - 48px)); }
.skip:focus { transform: none; }
main:focus { outline: none; }
/* Very narrow phones (≤ 380 px): the header keeps only the symbol, so the unit switch, theme and wallet fit
   (the page's name is in the tab bar below; the link keeps its "B20MINER Launchpad" label). */
@media (max-width: 380px) { .brand span { display: none; } }
